Repository: calcite Updated Branches: refs/heads/master a5d520df7 -> cd493efd3
[CALCITE-2054] Error while validating UPDATE with dynamic parameter in SET clause (Enrico Olivelli) Close apache/calcite#568 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/cd493efd Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/cd493efd Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/cd493efd Branch: refs/heads/master Commit: cd493efd3e892d8279582cd9252204d90caa2589 Parents: a5d520d Author: Enrico Olivelli <[email protected]> Authored: Fri Nov 17 12:40:49 2017 +0100 Committer: Julian Hyde <[email protected]> Committed: Mon Nov 27 15:46:12 2017 -0800 ---------------------------------------------------------------------- .../calcite/sql/validate/SqlValidatorImpl.java | 3 +- .../java/org/apache/calcite/test/JdbcTest.java | 70 ++++++++++++++++++++ .../calcite/test/SqlToRelConverterTest.java | 6 ++ .../calcite/test/SqlToRelConverterTest.xml | 13 ++++ 4 files changed, 91 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/cd493efd/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java ---------------------------------------------------------------------- diff --git a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java index 2e66e54..7c7c065 100644 --- a/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java +++ b/core/src/main/java/org/apache/calcite/sql/validate/SqlValidatorImpl.java @@ -345,10 +345,11 @@ public class SqlValidatorImpl implements SqlValidatorWithHints { final List<Map.Entry<String, RelDataType>> types = new ArrayList<>(); for (int i = 0; i < selectList.size(); i++) { final SqlNode selectItem = selectList.get(i); + final RelDataType originalType = getValidatedNodeTypeIfKnown(selectItem); expandSelectItem( selectItem, select, - unknownType, + Util.first(originalType, unknownType), list, catalogReader.nameMatcher().isCaseSensitive() ? new LinkedHashSet<String>() http://git-wip-us.apache.org/repos/asf/calcite/blob/cd493efd/core/src/test/java/org/apache/calcite/test/JdbcTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/JdbcTest.java b/core/src/test/java/org/apache/calcite/test/JdbcTest.java index f269ba6..cdebd47 100644 --- a/core/src/test/java/org/apache/calcite/test/JdbcTest.java +++ b/core/src/test/java/org/apache/calcite/test/JdbcTest.java @@ -6528,6 +6528,76 @@ public class JdbcTest { } + /** + * Test case for + * <a href="https://issues.apache.org/jira/browse/CALCITE-2054">[CALCITE-2054] + * Error while validating UPDATE with dynamic parameter in SET clause</a>. + */ + @Test public void testUpdateBind() throws Exception { + String hsqldbMemUrl = "jdbc:hsqldb:mem:."; + try (Connection baseConnection = DriverManager.getConnection(hsqldbMemUrl); + Statement baseStmt = baseConnection.createStatement()) { + baseStmt.execute("CREATE TABLE T2 (\n" + + "ID INTEGER,\n" + + "VALS DOUBLE)"); + baseStmt.execute("INSERT INTO T2 VALUES (1, 1.0)"); + baseStmt.execute("INSERT INTO T2 VALUES (2, null)"); + baseStmt.execute("INSERT INTO T2 VALUES (null, 2.0)"); + + baseStmt.close(); + baseConnection.commit(); + + Properties info = new Properties(); + final String model = "inline:" + + "{\n" + + " version: '1.0',\n" + + " defaultSchema: 'BASEJDBC',\n" + + " schemas: [\n" + + " {\n" + + " type: 'jdbc',\n" + + " name: 'BASEJDBC',\n" + + " jdbcDriver: '" + jdbcDriver.class.getName() + "',\n" + + " jdbcUrl: '" + hsqldbMemUrl + "',\n" + + " jdbcCatalog: null,\n" + + " jdbcSchema: null\n" + + " }\n" + + " ]\n" + + "}"; + info.put("model", model); + + Connection calciteConnection = + DriverManager.getConnection("jdbc:calcite:", info); + + ResultSet rs = calciteConnection.prepareStatement("select * from t2") + .executeQuery(); + + assertThat(rs.next(), is(true)); + assertThat((Integer) rs.getObject("ID"), is(1)); + assertThat((Double) rs.getObject("VALS"), is(1.0)); + + assertThat(rs.next(), is(true)); + assertThat((Integer) rs.getObject("ID"), is(2)); + assertThat(rs.getObject("VALS"), nullValue()); + + assertThat(rs.next(), is(true)); + assertThat(rs.getObject("ID"), nullValue()); + assertThat((Double) rs.getObject("VALS"), equalTo(2.0)); + + rs.close(); + + final String sql = "update t2 set vals=? where id=?"; + try (PreparedStatement ps = + calciteConnection.prepareStatement(sql)) { + ParameterMetaData pmd = ps.getParameterMetaData(); + assertThat(pmd.getParameterCount(), is(2)); + assertThat(pmd.getParameterType(1), is(Types.DOUBLE)); + assertThat(pmd.getParameterType(2), is(Types.INTEGER)); + ps.close(); + } + calciteConnection.close(); + } + } + /** Test case for * <a href="https://issues.apache.org/jira/browse/CALCITE-730">[CALCITE-730] * ClassCastException in table from CloneSchema</a>. */ http://git-wip-us.apache.org/repos/asf/calcite/blob/cd493efd/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java index 5424041..de0b268 100644 --- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java +++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java @@ -1941,6 +1941,12 @@ public class SqlToRelConverterTest extends SqlToRelTestBase { sql(sql).ok(); } + @Test public void testUpdateBind2() { + final String sql = "update emp" + + " set sal = ? where slacker = false"; + sql(sql).ok(); + } + @Ignore("CALCITE-1708") @Test public void testUpdateBindExtendedColumn() { final String sql = "update emp(test INT)" http://git-wip-us.apache.org/repos/asf/calcite/blob/cd493efd/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml ---------------------------------------------------------------------- diff --git a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml index 18f4494..c7d2b24 100644 --- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml +++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml @@ -3989,6 +3989,19 @@ LogicalTableModify(table=[[CATALOG, SALES, EMP]], operation=[UPDATE], updateColu ]]> </Resource> </TestCase> + <TestCase name="testUpdateBind2"> + <Resource name="sql"> + <![CDATA[update emp set sal = ? where slacker = false]]> + </Resource> + <Resource name="plan"> + <![CDATA[ +LogicalTableModify(table=[[CATALOG, SALES, EMP]], operation=[UPDATE], updateColumnList=[[SAL]], sourceExpressionList=[[?0]], flattened=[true]) + LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$5], COMM=[$6], DEPTNO=[$7], SLACKER=[$8], EXPR$0=[?0]) + LogicalFilter(condition=[=($8, false)]) + LogicalTableScan(table=[[CATALOG, SALES, EMP]]) +]]> + </Resource> + </TestCase> <TestCase name="testUpdateExtendedColumnCollision"> <Resource name="sql"> <![CDATA[update empdefaults(empno INTEGER NOT NULL, deptno INTEGER) set deptno = 1, empno = 20, ename = 'Bob' where deptno = 10]]>
