You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by da...@apache.org on 2019/07/04 01:43:06 UTC
[calcite] branch master updated: [CALCITE-3121] VolcanoPlanner
hangs due to subquery with dynamic star
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 0ed54bd [CALCITE-3121] VolcanoPlanner hangs due to subquery with dynamic star
0ed54bd is described below
commit 0ed54bd64d0beb0849a499e65e872c43f00efce9
Author: yuzhao.cyz <yu...@alibaba-inc.com>
AuthorDate: Tue Jul 2 14:06:48 2019 +0800
[CALCITE-3121] VolcanoPlanner hangs due to subquery with dynamic star
---
.../rel/rules/ProjectFilterTransposeRule.java | 21 +++++++++
.../org/apache/calcite/test/RelOptRulesTest.java | 55 +++++++++++++++++++++-
.../org/apache/calcite/test/RelOptRulesTest.xml | 21 +++++++++
3 files changed, 95 insertions(+), 2 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTransposeRule.java
index dd1c0c9..7106560 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ProjectFilterTransposeRule.java
@@ -98,6 +98,27 @@ public class ProjectFilterTransposeRule extends RelOptRule {
return;
}
+ if ((origProj != null)
+ && origProj.getRowType().getFieldList().get(0).isDynamicStar()) {
+ // The PushProjector would change the plan:
+ //
+ // prj(**=[$0])
+ // : - filter
+ // : - scan
+ //
+ // to form like:
+ //
+ // prj(**=[$0]) (1)
+ // : - filter (2)
+ // : - prj(**=[$0], ITEM= ...) (3)
+ // : - scan
+ // This new plan has more cost that the old one, because of the new
+ // redundant project (3), if we also have FilterProjectTransposeRule in
+ // the rule set, it will also trigger infinite match of the ProjectMergeRule
+ // for project (1) and (3).
+ return;
+ }
+
PushProjector pushProjector =
new PushProjector(
origProj, origFilter, rel, preserveExprCondition, call.builder());
diff --git a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
index 337ce66..244ff05 100644
--- a/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RelOptRulesTest.java
@@ -165,6 +165,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
+import java.util.Locale;
import java.util.Properties;
import java.util.function.Predicate;
@@ -4994,8 +4995,7 @@ public class RelOptRulesTest extends RelOptTestBase {
/** Test case for testing type created by SubQueryRemoveRule: an
* ANY sub-query is non-nullable therefore plan should have cast. */
- @Test public void
- testAnyInProjectNonNullable() {
+ @Test public void testAnyInProjectNonNullable() {
final String sql = "select name, deptno > ANY (\n"
+ " select deptno from emp)\n"
+ "from dept";
@@ -5148,6 +5148,57 @@ public class RelOptRulesTest extends RelOptTestBase {
checkSubQuery(sql).check();
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-3121">[CALCITE-3121]
+ * VolcanoPlanner hangs due to subquery with dynamic star</a>. */
+ @Test public void testSubQueryWithDynamicStarHang() {
+ String sql = "select n.n_regionkey from (select * from "
+ + "(select * from sales.customer) t) n where n.n_nationkey >1";
+
+ VolcanoPlanner planner = new VolcanoPlanner(null, null);
+ planner.addRelTraitDef(ConventionTraitDef.INSTANCE);
+
+ Tester dynamicTester = createDynamicTester().withDecorrelation(true)
+ .withClusterFactory(
+ relOptCluster -> RelOptCluster.create(planner, relOptCluster.getRexBuilder()));
+
+ RelRoot root = dynamicTester.convertSqlToRel(sql);
+
+ String planBefore = NL + RelOptUtil.toString(root.rel);
+ getDiffRepos().assertEquals("planBefore", "${planBefore}", planBefore);
+
+ PushProjector.ExprCondition exprCondition = expr -> {
+ if (expr instanceof RexCall) {
+ RexCall call = (RexCall) expr;
+ return "item".equals(call.getOperator().getName().toLowerCase(Locale.ROOT));
+ }
+ return false;
+ };
+ RuleSet ruleSet =
+ RuleSets.ofList(
+ FilterProjectTransposeRule.INSTANCE,
+ FilterMergeRule.INSTANCE,
+ ProjectMergeRule.INSTANCE,
+ new ProjectFilterTransposeRule(Project.class, Filter .class,
+ RelFactories.LOGICAL_BUILDER, exprCondition),
+ EnumerableRules.ENUMERABLE_PROJECT_RULE,
+ EnumerableRules.ENUMERABLE_FILTER_RULE,
+ EnumerableRules.ENUMERABLE_SORT_RULE,
+ EnumerableRules.ENUMERABLE_LIMIT_RULE,
+ EnumerableRules.ENUMERABLE_TABLE_SCAN_RULE);
+ Program program = Programs.of(ruleSet);
+
+ RelTraitSet toTraits =
+ root.rel.getCluster().traitSet()
+ .replace(0, EnumerableConvention.INSTANCE);
+
+ RelNode relAfter = program.run(planner, root.rel, toTraits,
+ Collections.emptyList(), Collections.emptyList());
+
+ String planAfter = NL + RelOptUtil.toString(relAfter);
+ getDiffRepos().assertEquals("planAfter", "${planAfter}", planAfter);
+ }
+
@Ignore("[CALCITE-1045]")
@Test public void testExpandJoinIn() throws Exception {
final String sql = "select empno\n"
diff --git a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
index 0453f4a..1e1bc06 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -9522,6 +9522,27 @@ LogicalProject(EMPNO=[$0])
]]>
</Resource>
</TestCase>
+ <TestCase name="testSubQueryWithDynamicStarHang">
+ <Resource name="sql">
+ <![CDATA[select n.n_regionkey from (select * from
+(select * from sales.customer) t) n where n.n_nationkey >1]]>
+ </Resource>
+ <Resource name="planBefore">
+ <![CDATA[
+LogicalProject(N_REGIONKEY=[ITEM($0, 'N_REGIONKEY')])
+ LogicalFilter(condition=[>(ITEM($0, 'N_NATIONKEY'), 1)])
+ LogicalProject(**=[$0])
+ LogicalTableScan(table=[[CATALOG, SALES, CUSTOMER]])
+]]>
+ </Resource>
+ <Resource name="planAfter">
+ <![CDATA[
+EnumerableProject(N_REGIONKEY=[ITEM($0, 'N_REGIONKEY')])
+ EnumerableFilter(condition=[>(ITEM($0, 'N_NATIONKEY'), 1)])
+ EnumerableTableScan(table=[[CATALOG, SALES, CUSTOMER]])
+]]>
+ </Resource>
+ </TestCase>
<TestCase name="testExpandFilterExists">
<Resource name="sql">
<![CDATA[select empno