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