You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by za...@apache.org on 2019/04/02 17:06:34 UTC
[calcite] branch master updated: [CALCITE-2930]
IllegalStateException when FilterCorrelateRule matches a SEMI or ANTI
Correlate (Ruben Quesada Lopez)
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 43ba147 [CALCITE-2930] IllegalStateException when FilterCorrelateRule matches a SEMI or ANTI Correlate (Ruben Quesada Lopez)
43ba147 is described below
commit 43ba147937dc53dfb86ee8723d45562e48b14d20
Author: rubenada <ru...@gmail.com>
AuthorDate: Mon Mar 18 12:21:34 2019 +0100
[CALCITE-2930] IllegalStateException when FilterCorrelateRule matches a SEMI or ANTI Correlate (Ruben Quesada Lopez)
Close #1112
---
.../java/org/apache/calcite/plan/RelOptUtil.java | 15 ++++++++---
.../calcite/rel/rules/FilterCorrelateRule.java | 5 ++--
.../test/enumerable/EnumerableCorrelateTest.java | 29 ++++++++++++++++++++++
3 files changed, 44 insertions(+), 5 deletions(-)
diff --git a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
index 9160b04..809dd27 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -26,6 +26,7 @@ import org.apache.calcite.rel.RelVisitor;
import org.apache.calcite.rel.RelWriter;
import org.apache.calcite.rel.core.AggregateCall;
import org.apache.calcite.rel.core.Calc;
+import org.apache.calcite.rel.core.Correlate;
import org.apache.calcite.rel.core.CorrelationId;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Join;
@@ -2355,9 +2356,10 @@ public abstract class RelOptUtil {
final List<RelDataTypeField> rightFields =
joinRel.getInputs().get(1).getRowType().getFieldList();
final int nFieldsRight = rightFields.size();
- assert nTotalFields == (joinRel instanceof SemiJoin
- ? nSysFields + nFieldsLeft
- : nSysFields + nFieldsLeft + nFieldsRight);
+
+ assert nTotalFields == (returnsJustFirstInput(joinRel)
+ ? nSysFields + nFieldsLeft
+ : nSysFields + nFieldsLeft + nFieldsRight);
// set the reference bitmaps for the left and right children
ImmutableBitSet leftBitmap =
@@ -2444,6 +2446,13 @@ public abstract class RelOptUtil {
return !filtersToRemove.isEmpty();
}
+ private static boolean returnsJustFirstInput(RelNode joinRel) {
+ // SemiJoin, CorrelateSemiJoin, CorrelateAntiJoin: right fields are not returned
+ return joinRel instanceof SemiJoin
+ || (joinRel instanceof Correlate
+ && ((Correlate) joinRel).getJoinType().returnsJustFirstInput());
+ }
+
private static RexNode shiftFilter(
int start,
int end,
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterCorrelateRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterCorrelateRule.java
index 7bd9c5f..7fd4732 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterCorrelateRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterCorrelateRule.java
@@ -27,6 +27,7 @@ import org.apache.calcite.rel.core.RelFactories;
import org.apache.calcite.rex.RexBuilder;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexUtil;
+import org.apache.calcite.sql.SemiJoinType;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
@@ -86,8 +87,8 @@ public class FilterCorrelateRule extends RelOptRule {
aboveFilters,
JoinRelType.INNER,
false,
- !corr.getJoinType().toJoinType().generatesNullsOnLeft(),
- !corr.getJoinType().toJoinType().generatesNullsOnRight(),
+ true,
+ corr.getJoinType() == SemiJoinType.INNER,
aboveFilters,
leftFilters,
rightFilters);
diff --git a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
index 451d95d..d5f05a0 100644
--- a/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
+++ b/core/src/test/java/org/apache/calcite/test/enumerable/EnumerableCorrelateTest.java
@@ -21,6 +21,7 @@ import org.apache.calcite.adapter.java.ReflectiveSchema;
import org.apache.calcite.config.CalciteConnectionProperty;
import org.apache.calcite.config.Lex;
import org.apache.calcite.plan.RelOptPlanner;
+import org.apache.calcite.rel.rules.FilterCorrelateRule;
import org.apache.calcite.rel.rules.JoinToCorrelateRule;
import org.apache.calcite.runtime.Hook;
import org.apache.calcite.test.CalciteAssert;
@@ -103,6 +104,34 @@ public class EnumerableCorrelateTest {
"empid=150; name=Sebastian");
}
+ /** Test case for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-2930">[CALCITE-2930]
+ * FilterCorrelateRule on a Correlate with SemiJoinType SEMI (or ANTI)
+ * throws IllegalStateException</a> */
+ @Test public void semiJoinCorrelateWithFilterCorrelateRule() {
+ tester(false, new JdbcTest.HrSchema())
+ .query(
+ "select empid, name from emps e where e.deptno in (select d.deptno from depts d) and e.empid > 100")
+ .withHook(Hook.PLANNER, (Consumer<RelOptPlanner>) planner -> {
+ // force the semi-join to run via EnumerableCorrelate instead of EnumerableJoin/SemiJoin,
+ // and push the 'empid > 100' filter into the Correlate
+ planner.addRule(JoinToCorrelateRule.SEMI);
+ planner.addRule(FilterCorrelateRule.INSTANCE);
+ planner.removeRule(EnumerableRules.ENUMERABLE_JOIN_RULE);
+ planner.removeRule(EnumerableRules.ENUMERABLE_SEMI_JOIN_RULE);
+ })
+ .explainContains(""
+ + "EnumerableCalc(expr#0..2=[{inputs}], empid=[$t0], name=[$t2])\n"
+ + " EnumerableCorrelate(correlation=[$cor3], joinType=[semi], requiredColumns=[{1}])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[100], expr#6=[>($t0, $t5)], proj#0..2=[{exprs}], $condition=[$t6])\n"
+ + " EnumerableTableScan(table=[[s, emps]])\n"
+ + " EnumerableCalc(expr#0..3=[{inputs}], expr#4=[$cor3], expr#5=[$t4.deptno], expr#6=[=($t5, $t0)], proj#0..3=[{exprs}], $condition=[$t6])\n"
+ + " EnumerableTableScan(table=[[s, depts]])")
+ .returnsUnordered(
+ "empid=110; name=Theodore",
+ "empid=150; name=Sebastian");
+ }
+
@Test public void simpleCorrelate() {
tester(false, new JdbcTest.HrSchema())
.query(