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 a3f81bb  [CALCITE-2998] RexCopier should support all rex types 
(Chunwei Lei, Alexander Shilov)
a3f81bb is described below

commit a3f81bb7b088fd8c1d0c1df3b0f2b0cf122633de
Author: Chunwei Lei <chunwei....@alibaba-inc.com>
AuthorDate: Sun Apr 14 18:40:21 2019 +0800

    [CALCITE-2998] RexCopier should support all rex types (Chunwei Lei, 
Alexander Shilov)
    
    Close apache/calcite#1164
    Close apache/calcite#969
---
 .../java/org/apache/calcite/rex/RexCopier.java     |  22 ++-
 .../org/apache/calcite/rex/RexBuilderTest.java     | 155 +++++++++++++++++++++
 2 files changed, 165 insertions(+), 12 deletions(-)

diff --git a/core/src/main/java/org/apache/calcite/rex/RexCopier.java 
b/core/src/main/java/org/apache/calcite/rex/RexCopier.java
index 7b66086..f207750 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCopier.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCopier.java
@@ -24,9 +24,6 @@ import org.apache.calcite.rel.type.RelDataType;
  * <p>This is useful when copying objects from one type factory or builder to
  * another.
  *
- * <p>Due to the laziness of the author, not all Rex types are supported at
- * present.
- *
  * @see RexBuilder#copy(RexNode)
  */
 class RexCopier extends RexShuttle {
@@ -52,11 +49,10 @@ class RexCopier extends RexShuttle {
   }
 
   public RexNode visitOver(RexOver over) {
-    throw new UnsupportedOperationException();
-  }
-
-  public RexWindow visitWindow(RexWindow window) {
-    throw new UnsupportedOperationException();
+    final boolean[] update = null;
+    return new RexOver(copy(over.getType()), over.getAggOperator(),
+        visitList(over.getOperands(), update), visitWindow(over.getWindow()),
+        over.isDistinct(), over.ignoreNulls());
   }
 
   public RexNode visitCall(final RexCall call) {
@@ -67,7 +63,7 @@ class RexCopier extends RexShuttle {
   }
 
   public RexNode visitCorrelVariable(RexCorrelVariable variable) {
-    throw new UnsupportedOperationException();
+    return builder.makeCorrel(copy(variable.getType()), variable.id);
   }
 
   public RexNode visitFieldAccess(RexFieldAccess fieldAccess) {
@@ -80,7 +76,7 @@ class RexCopier extends RexShuttle {
   }
 
   public RexNode visitLocalRef(RexLocalRef localRef) {
-    throw new UnsupportedOperationException();
+    return new RexLocalRef(localRef.getIndex(), copy(localRef.getType()));
   }
 
   public RexNode visitLiteral(RexLiteral literal) {
@@ -90,11 +86,13 @@ class RexCopier extends RexShuttle {
   }
 
   public RexNode visitDynamicParam(RexDynamicParam dynamicParam) {
-    throw new UnsupportedOperationException();
+    return builder.makeDynamicParam(copy(dynamicParam.getType()),
+        dynamicParam.getIndex());
   }
 
   public RexNode visitRangeRef(RexRangeRef rangeRef) {
-    throw new UnsupportedOperationException();
+    return builder.makeRangeReference(copy(rangeRef.getType()),
+        rangeRef.getOffset(), false);
   }
 }
 
diff --git a/core/src/test/java/org/apache/calcite/rex/RexBuilderTest.java 
b/core/src/test/java/org/apache/calcite/rex/RexBuilderTest.java
index b8b30f0..780469a 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexBuilderTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexBuilderTest.java
@@ -17,10 +17,15 @@
 package org.apache.calcite.rex;
 
 import org.apache.calcite.avatica.util.ByteString;
+import org.apache.calcite.rel.core.CorrelationId;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rel.type.RelDataTypeFactory;
 import org.apache.calcite.rel.type.RelDataTypeSystem;
 import org.apache.calcite.sql.SqlCollation;
+import org.apache.calcite.sql.SqlWindow;
+import org.apache.calcite.sql.fun.SqlStdOperatorTable;
+import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.BasicSqlType;
 import org.apache.calcite.sql.type.SqlTypeFactoryImpl;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.DateString;
@@ -30,6 +35,9 @@ import org.apache.calcite.util.TimestampString;
 import org.apache.calcite.util.TimestampWithTimeZoneString;
 import org.apache.calcite.util.Util;
 
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
 import org.junit.Test;
 
 import java.math.BigDecimal;
@@ -44,6 +52,7 @@ import static org.hamcrest.core.Is.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 /**
@@ -51,6 +60,30 @@ import static org.junit.Assert.fail;
  */
 public class RexBuilderTest {
 
+  private static final int PRECISION = 256;
+
+  /**
+   * MySqlTypeFactoryImpl provides a specific implementation of
+   * {@link SqlTypeFactoryImpl} which sets precision to 256 for VARCHAR.
+   */
+  private static class MySqlTypeFactoryImpl extends SqlTypeFactoryImpl {
+
+    MySqlTypeFactoryImpl(RelDataTypeSystem typeSystem) {
+      super(typeSystem);
+    }
+
+    @Override public RelDataType createTypeWithNullability(
+        final RelDataType type,
+        final boolean nullable) {
+      if (type.getSqlTypeName() == SqlTypeName.VARCHAR) {
+        return new BasicSqlType(this.typeSystem, type.getSqlTypeName(),
+            PRECISION);
+      }
+      return super.createTypeWithNullability(type, nullable);
+    }
+  }
+
+
   /**
    * Test RexBuilder.ensureType()
    */
@@ -558,6 +591,128 @@ public class RexBuilderTest {
     checkBigDecimalLiteral(builder, "-73786976294838206464");
   }
 
+  /** Tests {@link RexCopier#visitOver(RexOver)} */
+  @Test public void testCopyOver() {
+    final RelDataTypeFactory sourceTypeFactory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 
65536);
+
+    final RelDataTypeFactory targetTypeFactory =
+        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final RexBuilder builder = new RexBuilder(targetTypeFactory);
+
+    final RexOver node = (RexOver) builder.makeOver(type,
+        SqlStdOperatorTable.COUNT,
+        ImmutableList.of(builder.makeInputRef(type, 0)),
+        ImmutableList.of(builder.makeInputRef(type, 1)),
+        ImmutableList.of(
+            new RexFieldCollation(
+                builder.makeInputRef(type, 2), ImmutableSet.of())),
+        RexWindowBound.create(
+            SqlWindow.createUnboundedPreceding(SqlParserPos.ZERO), null),
+        RexWindowBound.create(
+            SqlWindow.createCurrentRow(SqlParserPos.ZERO), null),
+        true, true, false, false, false);
+    final RexNode copy = builder.copy(node);
+    assertTrue(copy instanceof RexOver);
+
+    RexOver result = (RexOver) copy;
+    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+    assertThat(result.getType().getPrecision(), is(PRECISION));
+    assertThat(result.getWindow(), is(node.getWindow()));
+    assertThat(result.getAggOperator(), is(node.getAggOperator()));
+    assertThat(result.getAggOperator(), is(node.getAggOperator()));
+    assertEquals(node.isDistinct(), result.isDistinct());
+    assertEquals(node.ignoreNulls(), result.ignoreNulls());
+    for (int i = 0; i < node.getOperands().size(); i++) {
+      assertThat(result.getOperands().get(i).getType().getSqlTypeName(),
+          is(node.getOperands().get(i).getType().getSqlTypeName()));
+      assertThat(result.getOperands().get(i).getType().getPrecision(),
+          is(PRECISION));
+    }
+  }
+
+  /** Tests {@link RexCopier#visitCorrelVariable(RexCorrelVariable)} */
+  @Test public void testCopyCorrelVariable() {
+    final RelDataTypeFactory sourceTypeFactory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 
65536);
+
+    final RelDataTypeFactory targetTypeFactory =
+        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final RexBuilder builder = new RexBuilder(targetTypeFactory);
+
+    final RexCorrelVariable node =
+        (RexCorrelVariable) builder.makeCorrel(type, new CorrelationId(0));
+    final RexNode copy = builder.copy(node);
+    assertTrue(copy instanceof RexCorrelVariable);
+
+    final RexCorrelVariable result = (RexCorrelVariable) copy;
+    assertThat(result.id, is(node.id));
+    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+    assertThat(result.getType().getPrecision(), is(PRECISION));
+  }
+
+  /** Tests {@link RexCopier#visitLocalRef(RexLocalRef)} */
+  @Test public void testCopyLocalRef() {
+    final RelDataTypeFactory sourceTypeFactory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 
65536);
+
+    final RelDataTypeFactory targetTypeFactory =
+        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final RexBuilder builder = new RexBuilder(targetTypeFactory);
+
+    final RexLocalRef node = new RexLocalRef(0, type);
+    final RexNode copy = builder.copy(node);
+    assertTrue(copy instanceof RexLocalRef);
+
+    final RexLocalRef result = (RexLocalRef) copy;
+    assertThat(result.getIndex(), is(node.getIndex()));
+    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+    assertThat(result.getType().getPrecision(), is(PRECISION));
+  }
+
+  /** Tests {@link RexCopier#visitDynamicParam(RexDynamicParam)} */
+  @Test public void testCopyDynamicParam() {
+    final RelDataTypeFactory sourceTypeFactory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 
65536);
+
+    final RelDataTypeFactory targetTypeFactory =
+        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final RexBuilder builder = new RexBuilder(targetTypeFactory);
+
+    final RexDynamicParam node = builder.makeDynamicParam(type, 0);
+    final RexNode copy = builder.copy(node);
+    assertTrue(copy instanceof RexDynamicParam);
+
+    final RexDynamicParam result = (RexDynamicParam) copy;
+    assertThat(result.getIndex(), is(node.getIndex()));
+    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+    assertThat(result.getType().getPrecision(), is(PRECISION));
+  }
+
+  /** Tests {@link RexCopier#visitRangeRef(RexRangeRef)} */
+  @Test public void testCopyRangeRef() {
+    final RelDataTypeFactory sourceTypeFactory =
+        new SqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    RelDataType type = sourceTypeFactory.createSqlType(SqlTypeName.VARCHAR, 
65536);
+
+    final RelDataTypeFactory targetTypeFactory =
+        new MySqlTypeFactoryImpl(RelDataTypeSystem.DEFAULT);
+    final RexBuilder builder = new RexBuilder(targetTypeFactory);
+
+    final RexRangeRef node = builder.makeRangeReference(type, 1, true);
+    final RexNode copy = builder.copy(node);
+    assertTrue(copy instanceof RexRangeRef);
+
+    final RexRangeRef result = (RexRangeRef) copy;
+    assertThat(result.getOffset(), is(node.getOffset()));
+    assertThat(result.getType().getSqlTypeName(), is(SqlTypeName.VARCHAR));
+    assertThat(result.getType().getPrecision(), is(PRECISION));
+  }
+
   private void checkBigDecimalLiteral(RexBuilder builder, String val) {
     final RexLiteral literal = builder.makeExactLiteral(new BigDecimal(val));
     assertThat("builder.makeExactLiteral(new BigDecimal(" + val

Reply via email to