You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by ru...@apache.org on 2019/07/12 07:00:48 UTC

[calcite] branch master updated: [CALCITE-3165] Project#accept(RexShuttle shuttle) does not update rowType

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

rubenql 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 e5e5809  [CALCITE-3165] Project#accept(RexShuttle shuttle) does not update rowType
e5e5809 is described below

commit e5e5809d28f422896147bd9f069f4930f22629ad
Author: rubenada <ru...@gmail.com>
AuthorDate: Tue Jul 2 11:14:31 2019 +0200

    [CALCITE-3165] Project#accept(RexShuttle shuttle) does not update rowType
---
 .../main/java/org/apache/calcite/rel/RelNode.java  |  3 +-
 .../java/org/apache/calcite/rel/core/Project.java  |  6 ++
 .../java/org/apache/calcite/test/CalciteSuite.java |  1 +
 .../org/apache/calcite/test/RexShuttleTest.java    | 76 ++++++++++++++++++++++
 4 files changed, 85 insertions(+), 1 deletion(-)

diff --git a/core/src/main/java/org/apache/calcite/rel/RelNode.java b/core/src/main/java/org/apache/calcite/rel/RelNode.java
index 95b15b1..02622e9 100644
--- a/core/src/main/java/org/apache/calcite/rel/RelNode.java
+++ b/core/src/main/java/org/apache/calcite/rel/RelNode.java
@@ -434,7 +434,8 @@ public interface RelNode extends RelOptNode, Cloneable {
 
   /**
    * Accepts a visit from a shuttle. If the shuttle updates expression, then
-   * a copy of the relation should be created.
+   * a copy of the relation should be created. This new relation might have
+   * a different row-type.
    *
    * @param shuttle Shuttle
    * @return A copy of this node incorporating changes made by the shuttle to
diff --git a/core/src/main/java/org/apache/calcite/rel/core/Project.java b/core/src/main/java/org/apache/calcite/rel/core/Project.java
index b484bf3..3492586 100644
--- a/core/src/main/java/org/apache/calcite/rel/core/Project.java
+++ b/core/src/main/java/org/apache/calcite/rel/core/Project.java
@@ -145,6 +145,12 @@ public abstract class Project extends SingleRel {
     if (this.exps == exps) {
       return this;
     }
+    final RelDataType rowType =
+        RexUtil.createStructType(
+            getInput().getCluster().getTypeFactory(),
+            exps,
+            this.rowType.getFieldNames(),
+            null);
     return copy(traitSet, getInput(), exps, rowType);
   }
 
diff --git a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
index 54bd512..1d1cd3b 100644
--- a/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
+++ b/core/src/test/java/org/apache/calcite/test/CalciteSuite.java
@@ -135,6 +135,7 @@ import org.junit.runners.Suite;
     SqlTypeUtilTest.class,
     SqlValidatorUtilTest.class,
     TypeFinderTest.class,
+    RexShuttleTest.class,
 
     // medium tests (above 0.1s)
     SqlParserTest.class,
diff --git a/core/src/test/java/org/apache/calcite/test/RexShuttleTest.java b/core/src/test/java/org/apache/calcite/test/RexShuttleTest.java
new file mode 100644
index 0000000..da90d60
--- /dev/null
+++ b/core/src/test/java/org/apache/calcite/test/RexShuttleTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.calcite.test;
+
+import org.apache.calcite.rel.RelNode;
+import org.apache.calcite.rel.type.RelDataType;
+import org.apache.calcite.rex.RexInputRef;
+import org.apache.calcite.rex.RexNode;
+import org.apache.calcite.rex.RexShuttle;
+import org.apache.calcite.sql.type.SqlTypeName;
+import org.apache.calcite.tools.RelBuilder;
+
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Unit tests for {@link RexShuttle}
+ */
+public class RexShuttleTest {
+
+  /** Test case for
+   * <a href="https://issues.apache.org/jira/browse/CALCITE-3165">[CALCITE-3165]
+   * Project#accept(RexShuttle shuttle) does not update rowType</a>. */
+  @Test
+  public void testProjectUpdatesRowType() {
+    final RelBuilder builder = RelBuilder.create(RelBuilderTest.config().build());
+
+    // Equivalent SQL: SELECT deptno, sal FROM emp
+    final RelNode root =
+        builder
+            .scan("EMP")
+            .project(
+                builder.field("DEPTNO"),
+                builder.field("SAL"))
+            .build();
+
+    // Equivalent SQL: SELECT CAST(deptno AS VARCHAR), CAST(sal AS VARCHAR) FROM emp
+    final RelNode rootWithCast =
+        builder
+            .scan("EMP")
+            .project(
+                builder.cast(builder.field("DEPTNO"), SqlTypeName.VARCHAR),
+                builder.cast(builder.field("SAL"), SqlTypeName.VARCHAR))
+            .build();
+    final RelDataType type = rootWithCast.getRowType();
+
+    // Transform the first expression into the second one, by using a RexShuttle
+    // that converts every RexInputRef into a 'CAST(RexInputRef AS VARCHAR)'
+    final RelNode rootWithCastViaRexShuttle = root.accept(new RexShuttle() {
+      @Override public RexNode visitInputRef(RexInputRef inputRef) {
+        return  builder.cast(inputRef, SqlTypeName.VARCHAR);
+      }
+    });
+    final RelDataType type2 = rootWithCastViaRexShuttle.getRowType();
+
+    assertThat(type, is(type2));
+  }
+}
+
+// End RexShuttleTest.java