-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[CALCITE-1703] Functions on TIME or TIMESTAMP column can throw ClassC…
…astException
- Loading branch information
1 parent
f3655e1
commit c2056f6
Showing
4 changed files
with
108 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
core/src/test/java/org/apache/calcite/test/ObjectArrayTableTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
package org.apache.calcite.test; | ||
|
||
import org.apache.calcite.adapter.java.AbstractQueryableTable; | ||
import org.apache.calcite.jdbc.CalciteConnection; | ||
import org.apache.calcite.jdbc.JavaTypeFactoryImpl; | ||
import org.apache.calcite.linq4j.Enumerable; | ||
import org.apache.calcite.linq4j.EnumerableDefaults; | ||
import org.apache.calcite.linq4j.Linq4j; | ||
import org.apache.calcite.linq4j.QueryProvider; | ||
import org.apache.calcite.linq4j.Queryable; | ||
import org.apache.calcite.rel.type.RelDataType; | ||
import org.apache.calcite.rel.type.RelDataTypeFactory; | ||
import org.apache.calcite.rel.type.RelDataTypeSystem; | ||
import org.apache.calcite.schema.SchemaPlus; | ||
import org.apache.calcite.schema.Table; | ||
import org.junit.Test; | ||
|
||
import java.sql.Connection; | ||
import java.sql.DriverManager; | ||
import java.sql.ResultSet; | ||
import java.sql.SQLException; | ||
import java.sql.Statement; | ||
import java.util.Arrays; | ||
import java.util.Collections; | ||
|
||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertTrue; | ||
|
||
public class ObjectArrayTableTest { | ||
|
||
/** Test case for | ||
* <a href="https://issues.apache.org/jira/browse/CALCITE-1703">[CALCITE-1703] | ||
* Functions on TIME and TIMESTAMP column can throw ClassCastException</a>. */ | ||
@Test public void testJavaSqlDateColumnReference() throws SQLException { | ||
|
||
try ( | ||
Connection connection = DriverManager.getConnection("jdbc:calcite:"); | ||
final CalciteConnection calciteConnection = connection.unwrap(CalciteConnection.class) | ||
) { | ||
final SchemaPlus rootSchema = calciteConnection.getRootSchema(); | ||
|
||
final JavaTypeFactoryImpl typeFactory = | ||
new JavaTypeFactoryImpl(RelDataTypeSystem.DEFAULT); | ||
|
||
final RelDataType rowType =typeFactory.createStructType( | ||
Arrays.asList( | ||
typeFactory.createJavaType(java.sql.Date.class), | ||
typeFactory.createJavaType(java.sql.Time.class), | ||
typeFactory.createJavaType(java.sql.Timestamp.class) | ||
), | ||
Arrays.asList("dt", "tm", "ts") | ||
); | ||
|
||
final Enumerable<Object[]> enumerable = | ||
Linq4j.asEnumerable( | ||
Collections.singletonList(new Object[]{ | ||
java.sql.Date.valueOf("2018-12-14"), | ||
java.sql.Time.valueOf("18:29:34"), | ||
java.sql.Timestamp.valueOf("2018-12-14 18:29:34.123")})); | ||
|
||
final Table table = new AbstractQueryableTable(Object[].class) { | ||
@Override | ||
@SuppressWarnings({"unchecked", "rawtypes"}) | ||
public Queryable<Object[]> asQueryable(QueryProvider queryProvider, SchemaPlus schema, String tableName) { | ||
return EnumerableDefaults.asOrderedQueryable(enumerable); | ||
} | ||
|
||
@Override | ||
public RelDataType getRowType(RelDataTypeFactory typeFactory) { | ||
return rowType; | ||
} | ||
}; | ||
|
||
rootSchema.add("java_sql_date_types", table); | ||
|
||
// 'extract' function expects numeric date representation. | ||
// RexToLixTranslator.convert() handles Java type to numeric conversion. | ||
final Statement statement = connection.createStatement(); | ||
String sql = "select extract(year from \"dt\")," + | ||
" extract(hour from \"tm\")," + | ||
" extract(day from \"ts\") from \"java_sql_date_types\""; | ||
|
||
ResultSet resultSet = statement.executeQuery(sql); | ||
assertTrue(resultSet.next()); | ||
assertEquals(2018, resultSet.getInt(1)); | ||
// Although using 'extract' function against time value doesn't make sense, this confirms time column can be converted to int. | ||
assertEquals(0, resultSet.getInt(2)); | ||
assertEquals(14, resultSet.getInt(3)); | ||
|
||
} | ||
} | ||
|
||
} |