This is an automated email from the ASF dual-hosted git repository. danny0405 pushed a commit to branch branch-1.22 in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 926478ee7d997a06a63fd6e9926436aafa42ac9f Author: yuzhao.cyz <[email protected]> AuthorDate: Fri Feb 28 13:43:04 2020 +0800 [CALCITE-3826] UPDATE assigns wrong type to bind variables (cherry picked from commit eab156a88baf992644fc7b185dc7c730a49154f7) --- .../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)
