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 <[email protected]>
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