This is an automated email from the ASF dual-hosted git repository.
danny0405 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 796675c [CALCITE-4548] Support convert subQuery for
SqlToRelConverter#convertExpression (jibiyr)
796675c is described below
commit 796675c9b33e0461bc45a72780162d474a4b098b
Author: laughing.sheng <[email protected]>
AuthorDate: Fri Mar 26 17:58:56 2021 +0800
[CALCITE-4548] Support convert subQuery for
SqlToRelConverter#convertExpression (jibiyr)
close apache/calcite#2382
---
.../apache/calcite/sql2rel/SqlToRelConverter.java | 2 +
.../apache/calcite/test/SqlToRelConverterTest.java | 30 +++--
.../org/apache/calcite/test/SqlToRelTestBase.java | 144 ++++++++++++++++-----
.../apache/calcite/test/SqlToRelConverterTest.xml | 11 ++
4 files changed, 145 insertions(+), 42 deletions(-)
diff --git
a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
index d0beac9..a1d14de 100644
--- a/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
+++ b/core/src/main/java/org/apache/calcite/sql2rel/SqlToRelConverter.java
@@ -1940,6 +1940,7 @@ public class SqlToRelConverter {
final ParameterScope scope =
new ParameterScope((SqlValidatorImpl) validator(), nameToTypeMap);
final Blackboard bb = createBlackboard(scope, null, false);
+ replaceSubQueries(bb, node, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
return bb.convertExpression(node);
}
@@ -1964,6 +1965,7 @@ public class SqlToRelConverter {
final ParameterScope scope =
new ParameterScope((SqlValidatorImpl) validator(), nameToTypeMap);
final Blackboard bb = createBlackboard(scope, nameToNodeMap, false);
+ replaceSubQueries(bb, node, RelOptUtil.Logic.TRUE_FALSE_UNKNOWN);
return bb.convertExpression(node);
}
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 b28ef48..e81bb01 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelConverterTest.java
@@ -88,7 +88,12 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
/** Sets the SQL statement for a test. */
public final Sql sql(String sql) {
return new Sql(sql, true, tester, false, UnaryOperator.identity(),
- tester.getConformance());
+ tester.getConformance(), true);
+ }
+
+ public final Sql expr(String expr) {
+ return new Sql(expr, true, tester, false, UnaryOperator.identity(),
+ tester.getConformance(), false);
}
@Test void testDotLiteralAfterNestedRow() {
@@ -4192,6 +4197,12 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
sql(sql).trim(true).ok();
}
+
+ @Test public void testInWithConstantList() {
+ String expr = "1 in (1,2,3)";
+ expr(expr).ok();
+ }
+
/**
* Visitor that checks that every {@link RelNode} in a tree is valid.
*
@@ -4232,10 +4243,12 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
private final boolean trim;
private final UnaryOperator<SqlToRelConverter.Config> config;
private final SqlConformance conformance;
+ private final boolean query;
+
Sql(String sql, boolean decorrelate, Tester tester, boolean trim,
UnaryOperator<SqlToRelConverter.Config> config,
- SqlConformance conformance) {
+ SqlConformance conformance, boolean query) {
this.sql = Objects.requireNonNull(sql, "sql");
if (sql.contains(" \n")) {
throw new AssertionError("trailing whitespace");
@@ -4245,6 +4258,7 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
this.trim = trim;
this.config = Objects.requireNonNull(config, "config");
this.conformance = Objects.requireNonNull(conformance, "conformance");
+ this.query = query;
}
public void ok() {
@@ -4256,13 +4270,13 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
.withConformance(conformance)
.withConfig(config)
.withConfig(c -> c.withTrimUnusedFields(true))
- .assertConvertsTo(sql, plan, trim);
+ .assertConvertsTo(sql, plan, trim, query);
}
public Sql withConfig(UnaryOperator<SqlToRelConverter.Config> config) {
final UnaryOperator<SqlToRelConverter.Config> config2 =
this.config.andThen(Objects.requireNonNull(config, "config"))::apply;
- return new Sql(sql, decorrelate, tester, trim, config2, conformance);
+ return new Sql(sql, decorrelate, tester, trim, config2, conformance,
query);
}
public Sql expand(boolean expand) {
@@ -4270,19 +4284,19 @@ class SqlToRelConverterTest extends SqlToRelTestBase {
}
public Sql decorrelate(boolean decorrelate) {
- return new Sql(sql, decorrelate, tester, trim, config, conformance);
+ return new Sql(sql, decorrelate, tester, trim, config, conformance,
query);
}
public Sql with(Tester tester) {
- return new Sql(sql, decorrelate, tester, trim, config, conformance);
+ return new Sql(sql, decorrelate, tester, trim, config, conformance,
query);
}
public Sql trim(boolean trim) {
- return new Sql(sql, decorrelate, tester, trim, config, conformance);
+ return new Sql(sql, decorrelate, tester, trim, config, conformance,
query);
}
public Sql conformance(SqlConformance conformance) {
- return new Sql(sql, decorrelate, tester, trim, config, conformance);
+ return new Sql(sql, decorrelate, tester, trim, config, conformance,
query);
}
}
}
diff --git a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
index 5cc65da..93921f1 100644
--- a/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
+++ b/core/src/test/java/org/apache/calcite/test/SqlToRelTestBase.java
@@ -47,6 +47,7 @@ import org.apache.calcite.rel.type.RelDataTypeFactory;
import org.apache.calcite.rel.type.RelDataTypeField;
import org.apache.calcite.rel.type.RelDataTypeSystem;
import org.apache.calcite.rex.RexBuilder;
+import org.apache.calcite.rex.RexNode;
import org.apache.calcite.schema.ColumnStrategy;
import org.apache.calcite.sql.SqlNode;
import org.apache.calcite.sql.SqlOperatorTable;
@@ -169,6 +170,13 @@ public abstract class SqlToRelTestBase {
*/
RelRoot convertSqlToRel(String sql);
+ /**
+ * Converts an expression string to {@link RexNode}.
+ *
+ * @param expr The expression
+ */
+ RexNode convertExprToRex(String expr);
+
SqlNode parseQuery(String sql) throws Exception;
/**
@@ -221,6 +229,21 @@ public abstract class SqlToRelTestBase {
boolean trim);
/**
+ * Checks that a SQL statement converts to a given plan, optionally
+ * trimming columns that are not needed.
+ *
+ * @param sql SQL query or expression
+ * @param plan Expected plan
+ * @param trim Whether to trim columns that are not needed
+ * @param query True if {@code sql} is a query, false if it is an
expression
+ */
+ void assertConvertsTo(
+ String sql,
+ String plan,
+ boolean trim,
+ boolean query);
+
+ /**
* Returns the diff repository.
*
* @return Diff repository
@@ -266,6 +289,8 @@ public abstract class SqlToRelTestBase {
/** Trims a RelNode. */
RelNode trimRelNode(RelNode relNode);
+
+ SqlNode parseExpression(String expr) throws Exception;
}
//~ Inner Classes ----------------------------------------------------------
@@ -594,24 +619,9 @@ public abstract class SqlToRelTestBase {
final Prepare.CatalogReader catalogReader =
createCatalogReader(typeFactory);
final SqlValidator validator =
- createValidator(
- catalogReader, typeFactory);
- final Context context = getContext();
- context.maybeUnwrap(CalciteConnectionConfig.class)
- .ifPresent(calciteConfig -> {
- validator.transform(config ->
- config.withDefaultNullCollation(
- calciteConfig.defaultNullCollation()));
- });
- final SqlToRelConverter.Config config =
- configTransform.apply(SqlToRelConverter.config());
-
- final SqlToRelConverter converter =
- createSqlToRelConverter(
- validator,
- catalogReader,
- typeFactory,
- config);
+ createValidator(catalogReader, typeFactory);
+ SqlToRelConverter converter =
+ createSqlToRelConverter(validator, catalogReader);
final SqlNode validatedQuery = validator.validate(sqlQuery);
RelRoot root =
@@ -634,29 +644,33 @@ public abstract class SqlToRelTestBase {
final Prepare.CatalogReader catalogReader =
createCatalogReader(typeFactory);
final SqlValidator validator =
- createValidator(
- catalogReader, typeFactory);
- final Context context = getContext();
- final CalciteConnectionConfig calciteConfig =
- context.unwrap(CalciteConnectionConfig.class);
- if (calciteConfig != null) {
- validator.transform(config ->
-
config.withDefaultNullCollation(calciteConfig.defaultNullCollation()));
- }
- final SqlToRelConverter.Config config =
- configTransform.apply(SqlToRelConverter.config());
+ createValidator(catalogReader, typeFactory);
final SqlToRelConverter converter =
- createSqlToRelConverter(
- validator,
- catalogReader,
- typeFactory,
- config);
+ createSqlToRelConverter(validator, catalogReader);
relNode = converter.flattenTypes(relNode, true);
relNode = converter.trimUnusedFields(true, relNode);
return relNode;
}
+ private SqlToRelConverter createSqlToRelConverter(SqlValidator validator,
+ Prepare.CatalogReader
catalogReader) {
+ final Context context = getContext();
+ context.maybeUnwrap(CalciteConnectionConfig.class)
+ .ifPresent(calciteConfig -> {
+ validator.transform(config ->
+
config.withDefaultNullCollation(calciteConfig.defaultNullCollation()));
+ });
+ final SqlToRelConverter.Config config =
+ configTransform.apply(SqlToRelConverter.config());
+
+ return createSqlToRelConverter(
+ validator,
+ catalogReader,
+ typeFactory,
+ config);
+ }
+
protected SqlToRelConverter createSqlToRelConverter(
final SqlValidator validator,
final Prepare.CatalogReader catalogReader,
@@ -699,6 +713,13 @@ public abstract class SqlToRelTestBase {
return parser.parseQuery();
}
+ @Override public SqlNode parseExpression(String expr) throws Exception {
+ final SqlParser.Config config =
+ SqlParser.config().withConformance(getConformance());
+ SqlParser parser = SqlParser.create(expr, config);
+ return parser.parseExpression();
+ }
+
public SqlConformance getConformance() {
return conformance;
}
@@ -774,6 +795,38 @@ public abstract class SqlToRelTestBase {
String sql,
String plan,
boolean trim) {
+ assertConvertsTo(sql, plan, false, true);
+ }
+
+ public void assertConvertsTo(
+ String sql,
+ String plan,
+ boolean trim,
+ boolean query) {
+ if (query) {
+ assertSqlConvertsTo(sql, plan, trim);
+ } else {
+ assertExprConvertsTo(sql, plan);
+ }
+ }
+
+ private void assertExprConvertsTo(
+ String expr,
+ String plan) {
+ String expr2 = getDiffRepos().expand("sql", expr);
+ RexNode rex = convertExprToRex(expr2);
+ assertNotNull(rex);
+ // NOTE jvs 28-Mar-2006: insert leading newline so
+ // that plans come out nicely stacked instead of first
+ // line immediately after CDATA start
+ String actual = NL + rex.toString() + NL;
+ diffRepos.assertEquals("plan", plan, actual);
+ }
+
+ private void assertSqlConvertsTo(
+ String sql,
+ String plan,
+ boolean trim) {
String sql2 = getDiffRepos().expand("sql", sql);
RelNode rel = convertSqlToRel(sql2).project();
@@ -796,6 +849,29 @@ public abstract class SqlToRelTestBase {
diffRepos.assertEquals("plan", plan, actual);
}
+ public RexNode convertExprToRex(String expr) {
+ Objects.requireNonNull(expr, "expr");
+ final SqlNode sqlQuery;
+ try {
+ sqlQuery = parseExpression(expr);
+ } catch (RuntimeException | Error e) {
+ throw e;
+ } catch (Exception e) {
+ throw TestUtil.rethrow(e);
+ }
+
+ final RelDataTypeFactory typeFactory = getTypeFactory();
+ final Prepare.CatalogReader catalogReader =
+ createCatalogReader(typeFactory);
+ final SqlValidator validator =
+ createValidator(
+ catalogReader, typeFactory);
+ SqlToRelConverter converter = createSqlToRelConverter(validator,
catalogReader);
+
+ final SqlNode validatedQuery = validator.validate(sqlQuery);
+ return converter.convertExpression(validatedQuery);
+ }
+
/**
* Creates a RelFieldTrimmer.
*
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 fa6780f..64b9104 100644
--- a/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/SqlToRelConverterTest.xml
@@ -2303,6 +2303,17 @@ LogicalProject(EMPNO=[$0])
]]>
</Resource>
</TestCase>
+ <TestCase name="testInWithConstantList">
+ <Resource name="sql">
+ <![CDATA[1 in (1,2,3)
+]]>
+ </Resource>
+ <Resource name="plan">
+ <![CDATA[
+OR(=(1, 1), =(1, 2), =(1, 3))
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testInsert">
<Resource name="sql">
<![CDATA[insert into empnullables (deptno, empno, ename)