You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by za...@apache.org on 2019/03/29 22:57:47 UTC
[calcite] branch master updated: [CALCITE-2900]
RelStructuredTypeFlattener generates wrong types on nested columns (Will
Yu)
This is an automated email from the ASF dual-hosted git repository.
zabetak 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 1018d25 [CALCITE-2900] RelStructuredTypeFlattener generates wrong types on nested columns (Will Yu)
1018d25 is described below
commit 1018d25af62da638f8125e24214d3b97a76f71c2
Author: Will Yu <wm...@gmail.com>
AuthorDate: Fri Mar 22 21:36:16 2019 -0700
[CALCITE-2900] RelStructuredTypeFlattener generates wrong types on nested columns (Will Yu)
Close #1104
---
.../sql2rel/RelStructuredTypeFlattener.java | 22 +++++++++++++++++-----
.../apache/calcite/test/SqlToRelConverterTest.java | 11 +++++++++++
.../apache/calcite/test/SqlToRelConverterTest.xml | 10 ++++++++++
3 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
index 3a28d84..6b26808 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/RelStructuredTypeFlattener.java
@@ -303,9 +303,11 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
* corresponding field post-flattening, and also returns its type.
*
* @param oldOrdinal Pre-flattening ordinal
+ * @param existingOffset offset already calculated the target column inside the oldOrdinal column.
+ * For unnested column, it should be 0.
* @return Post-flattening ordinal and type
*/
- protected Ord<RelDataType> getNewFieldForOldInput(int oldOrdinal) {
+ private Ord<RelDataType> getNewFieldForOldInput(int oldOrdinal, int existingOffset) {
assert currentRel != null;
int newOrdinal = 0;
@@ -328,7 +330,7 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
assert newInput != null;
RelDataType oldInputType = oldInput.getRowType();
- final int newOffset = calculateFlattenedOffset(oldInputType, oldOrdinal);
+ final int newOffset = calculateFlattenedOffset(oldInputType, oldOrdinal) + existingOffset;
newOrdinal += newOffset;
final RelDataTypeField field =
newInput.getRowType().getFieldList().get(newOffset);
@@ -336,6 +338,17 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
}
/**
+ * Maps the ordinal of a field pre-flattening to the ordinal of the
+ * corresponding field post-flattening, and also returns its type.
+ *
+ * @param oldOrdinal Pre-flattening ordinal
+ * @return Post-flattening ordinal and type
+ */
+ protected Ord<RelDataType> getNewFieldForOldInput(int oldOrdinal) {
+ return getNewFieldForOldInput(oldOrdinal, 0);
+ }
+
+ /**
* Returns a mapping between old and new fields.
*
* @param oldRel Old relational expression
@@ -822,9 +835,8 @@ public class RelStructuredTypeFlattener implements ReflectiveVisitor {
// correct ordinal and type.
RexInputRef inputRef = (RexInputRef) refExp;
final Ord<RelDataType> newField =
- getNewFieldForOldInput(inputRef.getIndex());
- iInput += newField.i;
- return new RexInputRef(iInput, removeDistinct(newField.e));
+ getNewFieldForOldInput(inputRef.getIndex(), iInput);
+ return new RexInputRef(newField.getKey(), removeDistinct(newField.getValue()));
} else if (refExp instanceof RexCorrelVariable) {
RelDataType refType =
SqlTypeUtil.flattenRecordType(
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 b5749b1..7d13416 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -2616,6 +2616,17 @@ public class SqlToRelConverterTest extends SqlToRelTestBase {
sql(sql).with(getTesterWithDynamicTable()).ok();
}
+ /**
+ * Test case for <a href="https://issues.apache.org/jira/browse/CALCITE-2900">[CALCITE-2900]
+ * RelStructuredTypeFlattener generates wrong types on nested columns</a>.
+ */
+ @Test
+ public void testNestedColumnType() {
+ final String sql =
+ "select empa.home_address.zip from sales.emp_address empa where empa.home_address.city = 'abc'";
+ sql(sql).ok();
+ }
+
@Test public void testDynamicSchemaUnnest() {
final String sql3 = "select t1.c_nationkey, t3.fake_col3\n"
+ "from SALES.CUSTOMER as t1,\n"
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 dc4219c..25589d2 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -860,6 +860,16 @@ LogicalProject(FAKE2=[ITEM($0, 'fake_col2')])
]]>
</Resource>
</TestCase>
+ <TestCase name="testNestedColumnType">
+ <Resource name="plan">
+ <![CDATA[
+LogicalProject(ZIP=[$4])
+ LogicalFilter(condition=[=($3, 'abc':VARCHAR(20))])
+ LogicalProject(EMPNO=[$0], STREET=[$1.STREET], CITY=[$1.CITY], ZIP=[$1.ZIP], STATE=[$1.STATE], STREET5=[$2.STREET], CITY6=[$2.CITY], ZIP7=[$2.ZIP], STATE8=[$2.STATE])
+ LogicalTableScan(table=[[CATALOG, SALES, EMP_ADDRESS]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testDynamicSchemaUnnest">
<Resource name="sql">
<![CDATA[select t1.c_nationkey, t3.fake_col3