Skip to content

Commit

Permalink
fixed some edge-cases on casting with parameterization and potential …
Browse files Browse the repository at this point in the history
…concurrent modification exception with broadcast in frontend
  • Loading branch information
datomo committed Apr 7, 2024
1 parent 509ff33 commit 80648a3
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 13 deletions.
15 changes: 14 additions & 1 deletion core/src/main/java/org/polypheny/db/rex/RexLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,6 @@ public RexLiteral( PolyValue value, AlgDataType type, PolyType polyType ) {
System.err.println( polyType );
throw new IllegalArgumentException();
}
// Preconditions.checkArgument( valueMatchesType( value, typeName, true ) );
Preconditions.checkArgument( (value != null) || type.isNullable() );
Preconditions.checkArgument( polyType != PolyType.ANY );
this.digest = computeDigest( RexDigestIncludeType.OPTIONAL );
Expand Down Expand Up @@ -647,5 +646,19 @@ public int compareTo( RexLiteral o ) {
? 1 : -1;
}


/**
* Returns the value of this literal with the possibility to handle some edge cases. Like for parameterization.
*
* @param type the type to convert the value to
* @return the value of this literal
*/
public PolyValue getValue( AlgDataType type ) {
if ( PolyType.EXACT_TYPES.contains( type.getPolyType() ) && (PolyType.APPROX_TYPES.contains( value.type ) || PolyType.DECIMAL == value.type) ) {
return PolyValue.convert( value, type.getPolyType() );
}
return value;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@
import org.polypheny.db.type.entity.PolyBinary.ByteStringSerializer;
import org.polypheny.db.type.entity.PolyBoolean.PolyBooleanSerializerDef;
import org.polypheny.db.type.entity.PolyList.PolyListSerializerDef;
import org.polypheny.db.type.entity.numerical.PolyLong;
import org.polypheny.db.type.entity.numerical.PolyLong.PolyLongSerializerDef;
import org.polypheny.db.type.entity.PolyNull.PolyNullSerializerDef;
import org.polypheny.db.type.entity.PolyString.PolyStringSerializerDef;
import org.polypheny.db.type.entity.category.PolyBlob;
Expand All @@ -92,6 +90,8 @@
import org.polypheny.db.type.entity.numerical.PolyFloat.PolyFloatSerializerDef;
import org.polypheny.db.type.entity.numerical.PolyInteger;
import org.polypheny.db.type.entity.numerical.PolyInteger.PolyIntegerSerializerDef;
import org.polypheny.db.type.entity.numerical.PolyLong;
import org.polypheny.db.type.entity.numerical.PolyLong.PolyLongSerializerDef;
import org.polypheny.db.type.entity.relational.PolyMap;
import org.polypheny.db.type.entity.relational.PolyMap.PolyMapSerializerDef;
import org.polypheny.db.type.entity.temporal.PolyDate;
Expand Down Expand Up @@ -807,6 +807,8 @@ public static PolyValue convert( PolyValue value, PolyType type ) {
return value;
case BIGINT:
return PolyLong.convert( value );
case VARCHAR:
return PolyString.convert( value );
}
if ( type.getFamily() == value.getType().getFamily() ) {
return value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@

import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -451,7 +450,7 @@ public RexNode visitLiteral( RexLiteral literal ) {
return literal;
}
int i = index.getAndIncrement();
values.put( i, Collections.singletonList( new ParameterValue( i, literal.getType(), literal.getValue() ) ) );
values.put( i, List.of( new ParameterValue( i, literal.getType(), literal.getValue( literal.getType() ) ) ) );
types.add( literal.getType() );
return new RexDynamicParam( literal.getType(), i );
}
Expand All @@ -464,7 +463,7 @@ public RexNode visitCall( RexCall call ) {
} else if ( call.op.getKind() == Kind.ARRAY_VALUE_CONSTRUCTOR ) {
int i = index.getAndIncrement();
PolyList<PolyValue> list = createListForArrays( call.operands );
values.put( i, Collections.singletonList( new ParameterValue( i, call.type, list ) ) );
values.put( i, List.of( new ParameterValue( i, call.type, list ) ) );
types.add( call.type );
return new RexDynamicParam( call.type, i );
} else {
Expand Down
12 changes: 6 additions & 6 deletions dbms/src/test/java/org/polypheny/db/TestHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@
import org.polypheny.db.transaction.Transaction;
import org.polypheny.db.transaction.TransactionManager;
import org.polypheny.db.type.entity.PolyList;
import org.polypheny.db.type.entity.numerical.PolyLong;
import org.polypheny.db.type.entity.PolyString;
import org.polypheny.db.type.entity.PolyValue;
import org.polypheny.db.type.entity.numerical.PolyDouble;
import org.polypheny.db.type.entity.numerical.PolyFloat;
import org.polypheny.db.type.entity.numerical.PolyInteger;
import org.polypheny.db.type.entity.numerical.PolyLong;
import org.polypheny.db.util.Pair;
import org.polypheny.db.util.RunMode;
import org.polypheny.db.webui.HttpServer;
Expand Down Expand Up @@ -295,7 +295,7 @@ public static void checkResultSet( ResultSet resultSet, List<Object[]> expected,
int j = 0;
while ( j < expectedRow.length ) {
if ( expectedRow.length >= j + 1 ) {
int columnType = rsmd.getColumnType( j + 1 );
int columnType = rsmd.getColumnType( j + 1 ); // this leads to errors if expected is different aka expected is decimal and actual is integer
if ( columnType == Types.BINARY ) {
if ( expectedRow[j] == null ) {
assertNull( row[j], "Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "': " );
Expand All @@ -315,14 +315,15 @@ public static void checkResultSet( ResultSet resultSet, List<Object[]> expected,
double diff = Math.abs( (double) expectedRow[j] - (double) row[j] );
assertTrue( diff < EPSILON,
"Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "': The difference between the expected double and the received double exceeds the epsilon. Difference: " + (diff - EPSILON) );
} else if ( columnType == Types.DECIMAL ) { // Decimals are exact // but not for calculations?
} else if ( columnType == Types.DECIMAL || (expectedRow[j] instanceof Float || expectedRow[j] instanceof Double) ) { // Decimals are exact // but not for calculations?
BigDecimal expectedResult = new BigDecimal( expectedRow[j].toString() );
double diff = Math.abs( expectedResult.doubleValue() - ((BigDecimal) row[j]).doubleValue() );
BigDecimal actualResult = new BigDecimal( row[j].toString() );
double diff = Math.abs( expectedResult.doubleValue() - actualResult.doubleValue() );
if ( isConvertingDecimals ) {
assertTrue( diff < EPSILON,
"Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "': The difference between the expected decimal and the received decimal exceeds the epsilon. Difference: " + (diff - EPSILON) );
} else {
assertEquals( 0, expectedResult.doubleValue() - ((BigDecimal) row[j]).doubleValue(), 0.0, "Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "'" );
assertEquals( 0, expectedResult.doubleValue() - actualResult.doubleValue(), 0.0, "Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "'" );
}
} else if ( expectedRow[j] != null && row[j] != null && expectedRow[j] instanceof Number && row[j] instanceof Number ) {
assertEquals( ((Number) expectedRow[j]).longValue(), ((Number) row[j]).longValue(), "Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "'" );
Expand All @@ -335,7 +336,6 @@ public static void checkResultSet( ResultSet resultSet, List<Object[]> expected,
}
} else {
assertEquals(

expectedRow[j],
row[j],
"Unexpected data in column '" + rsmd.getColumnName( j + 1 ) + "'"
Expand Down
64 changes: 64 additions & 0 deletions dbms/src/test/java/org/polypheny/db/sql/clause/CastTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2019-2024 The Polypheny Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.polypheny.db.sql.clause;

import java.sql.SQLException;
import java.util.List;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.polypheny.db.TestHelper;

@SuppressWarnings({ "SqlDialectInspection", "SqlNoDataSourceInspection" })
public class CastTest {

@BeforeAll
public static void start() throws SQLException {
// Ensures that Polypheny-DB is running
//noinspection ResultOfMethodCallIgnored
TestHelper.getInstance();
}


@Test
public void floatToIntTest() {
List<Object[]> data = List.of(
new Object[][]{ new Object[]{ 1 } }
);

TestHelper.executeSql(
( c, s ) -> TestHelper.checkResultSet( s.executeQuery( "SELECT CAST(1.1 as INTEGER)" ), data, true, true ),
( c, s ) -> TestHelper.checkResultSet( s.executeQuery( "SELECT CAST('1.1' as INTEGER)" ), data, true, true ),
( c, s ) -> c.commit()
);
}


@Test
public void nullAsTest() {
List<Object[]> data = List.of(
new Object[][]{ new Object[]{ null } }
);

TestHelper.executeSql(
( c, s ) -> TestHelper.checkResultSet( s.executeQuery( "SELECT CAST(null as INTEGER)" ), data, true ),
( c, s ) -> TestHelper.checkResultSet( s.executeQuery( "SELECT CAST(null as VARCHAR)" ), data, true ),
( c, s ) -> c.commit()
);
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ public PartnerConnection( WsMessageContext... contexts ) {

public <E> void broadcast( E msg ) {
List<WsMessageContext> invalid = new ArrayList<>();
for ( WsMessageContext context : contexts ) {

for ( WsMessageContext context : List.copyOf( contexts ) ) { // Copy to avoid ConcurrentModificationException
if ( !context.session.isOpen() ) {
invalid.add( context );
continue;
Expand Down

0 comments on commit 80648a3

Please sign in to comment.