You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by da...@apache.org on 2020/02/29 02:44:21 UTC

[calcite] branch master updated: [CALCITE-3826] UPDATE assigns wrong type to bind variables

This is an automated email from the ASF dual-hosted git repository.

danny0405 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git


The following commit(s) were added to refs/heads/master by this push:
     new eab156a  [CALCITE-3826] UPDATE assigns wrong type to bind variables
eab156a is described below

commit eab156a88baf992644fc7b185dc7c730a49154f7
Author: yuzhao.cyz <yu...@gmail.com>
AuthorDate: Fri Feb 28 13:43:04 2020 +0800

    [CALCITE-3826] UPDATE assigns wrong type to bind variables
---
 .../apache/calcite/sql/validate/SqlValidatorImpl.java    | 16 ++++++++++------
 .../org/apache/calcite/test/SqlToRelConverterTest.java   | 16 ++++++++++++++++
 2 files changed, 26 insertions(+), 6 deletions(-)

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 7bcb6e6..d80e16d 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
@@ -4235,8 +4235,7 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
     final Set<String> aliases = new HashSet<>();
     final List<Map.Entry<String, RelDataType>> fieldList = new ArrayList<>();
 
-    for (int i = 0; i < selectItems.size(); i++) {
-      SqlNode selectItem = selectItems.get(i);
+    for (SqlNode selectItem : selectItems) {
       if (selectItem instanceof SqlSelect) {
         handleScalarSubQuery(
             select,
@@ -4245,13 +4244,18 @@ public class SqlValidatorImpl implements SqlValidatorWithHints {
             aliases,
             fieldList);
       } else {
+        // Use the field list size to record the field index
+        // because the select item may be a STAR(*), which could have been expanded.
+        final int fieldIdx = fieldList.size();
+        final RelDataType fieldType =
+                targetRowType.isStruct()
+                        && targetRowType.getFieldCount() > fieldIdx
+                ? targetRowType.getFieldList().get(fieldIdx).getType()
+                : unknownType;
         expandSelectItem(
             selectItem,
             select,
-            targetRowType.isStruct()
-                && targetRowType.getFieldCount() > i
-                ? targetRowType.getFieldList().get(i).getType()
-                : unknownType,
+            fieldType,
             expandedSelectItems,
             aliases,
             fieldList,
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 9eb3ce6..b24e2f3 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -35,7 +35,9 @@ import org.apache.calcite.rel.externalize.RelXmlWriter;
 import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rel.logical.LogicalSort;
 import org.apache.calcite.rel.logical.LogicalTableModify;
+import org.apache.calcite.rex.RexNode;
 import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.sql.validate.SqlConformance;
 import org.apache.calcite.sql.validate.SqlConformanceEnum;
 import org.apache.calcite.sql.validate.SqlDelegatingConformance;
@@ -3679,6 +3681,20 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
   }
 
   /**
+   * Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-3826">[CALCITE-3826]
+   * UPDATE assigns wrong type to bind variables</a>.
+   */
+  @Test public void testDynamicParamTypesInUpdate() {
+    RelNode rel = tester.convertSqlToRel("update emp set sal = ?, ename = ? where empno = ?").rel;
+    LogicalTableModify modify = (LogicalTableModify) rel;
+    List<RexNode> parameters = modify.getSourceExpressionList();
+    assertThat(parameters.size(), is(2));
+    assertThat(parameters.get(0).getType().getSqlTypeName(), is(SqlTypeName.INTEGER));
+    assertThat(parameters.get(1).getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+  }
+
+  /**
    * Visitor that checks that every {@link RelNode} in a tree is valid.
    *
    * @see RelNode#isValid(Litmus, RelNode.Context)