You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by vo...@apache.org on 2019/12/24 11:11:35 UTC
[calcite] branch master updated: [CALCITE-3525] RexSimplify:
eliminate redundant rex calls in OR
This is an automated email from the ASF dual-hosted git repository.
volodymyr 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 1f3b710 [CALCITE-3525] RexSimplify: eliminate redundant rex calls in OR
1f3b710 is described below
commit 1f3b7105fcc5cca45e5cdbb73d59fb51c410d08f
Author: Igor Guzenko <ih...@gmail.com>
AuthorDate: Mon Nov 25 14:28:55 2019 +0200
[CALCITE-3525] RexSimplify: eliminate redundant rex calls in OR
close #1610
---
.../java/org/apache/calcite/plan/RelOptUtil.java | 6 ++--
.../rel/rules/FilterProjectTransposeRule.java | 30 ++--------------
.../java/org/apache/calcite/rex/RexBuilder.java | 10 +++---
.../java/org/apache/calcite/rex/RexSimplify.java | 7 ++--
.../org/apache/calcite/test/JdbcAdapterTest.java | 42 +++++++++++-----------
.../apache/calcite/test/RexProgramBuilderBase.java | 6 ++--
.../org/apache/calcite/test/RexProgramTest.java | 37 ++++++++++---------
.../apache/calcite/test/ScannableTableTest.java | 2 +-
.../test/enumerable/EnumerableCorrelateTest.java | 4 +--
core/src/test/resources/sql/misc.iq | 6 ++--
.../calcite/adapter/mongodb/MongoAdapterTest.java | 15 +++-----
.../org/apache/calcite/test/SparkAdapterTest.java | 6 ++--
12 files changed, 71 insertions(+), 100 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 7a2b76d..5709056 100644
--- a/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
+++ b/core/src/main/java/org/apache/calcite/plan/RelOptUtil.java
@@ -56,6 +56,7 @@ import org.apache.calcite.rel.metadata.RelMetadataQuery;
import org.apache.calcite.rel.rules.JoinAssociateRule;
import org.apache.calcite.rel.rules.MultiJoin;
import org.apache.calcite.rel.rules.ProjectTableScanRule;
+import org.apache.calcite.rel.rules.ReduceExpressionsRule;
import org.apache.calcite.rel.stream.StreamRules;
import org.apache.calcite.rel.type.RelDataType;
import org.apache.calcite.rel.type.RelDataTypeFactory;
@@ -2004,10 +2005,7 @@ public abstract class RelOptUtil {
}
}
- // Change the below to enable constant-reduction.
- if (false) {
- registerReductionRules(planner);
- }
+ planner.addRule(ReduceExpressionsRule.FILTER_INSTANCE);
}
diff --git a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
index 0e4efaa..dbe2bf5 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/FilterProjectTransposeRule.java
@@ -16,7 +16,6 @@
*/
package org.apache.calcite.rel.rules;
-import org.apache.calcite.plan.RelOptPredicateList;
import org.apache.calcite.plan.RelOptRule;
import org.apache.calcite.plan.RelOptRuleCall;
import org.apache.calcite.plan.RelOptRuleOperand;
@@ -28,15 +27,11 @@ import org.apache.calcite.rel.RelNode;
import org.apache.calcite.rel.core.Filter;
import org.apache.calcite.rel.core.Project;
import org.apache.calcite.rel.core.RelFactories;
-import org.apache.calcite.rex.RexBuilder;
-import org.apache.calcite.rex.RexExecutor;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexOver;
-import org.apache.calcite.rex.RexSimplify;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.tools.RelBuilder;
import org.apache.calcite.tools.RelBuilderFactory;
-import org.apache.calcite.util.Util;
import java.util.Collections;
import java.util.function.Predicate;
@@ -167,7 +162,8 @@ public class FilterProjectTransposeRule extends RelOptRule {
.replaceIfs(RelDistributionTraitDef.INSTANCE,
() -> Collections.singletonList(
input.getTraitSet().getTrait(RelDistributionTraitDef.INSTANCE)));
- newFilterRel = filter.copy(traitSet, input, simplifyFilterCondition(newCondition, call));
+ newCondition = RexUtil.removeNullabilityCast(relBuilder.getTypeFactory(), newCondition);
+ newFilterRel = filter.copy(traitSet, input, newCondition);
} else {
newFilterRel =
relBuilder.push(project.getInput()).filter(newCondition).build();
@@ -183,26 +179,4 @@ public class FilterProjectTransposeRule extends RelOptRule {
call.transformTo(newProjRel);
}
-
- /**
- * Simplifies the filter condition using a simplifier created by the
- * information in the current call.
- *
- * <p>This method is an attempt to replicate the simplification behavior of
- * {@link RelBuilder#filter(RexNode...)} which cannot be used in the case of
- * copying nodes. The main difference with the behavior of that method is that
- * it does not drop entirely the filter if the condition is always false.
- */
- private RexNode simplifyFilterCondition(RexNode condition, RelOptRuleCall call) {
- final RexBuilder xBuilder = call.builder().getRexBuilder();
- final RexExecutor executor =
- Util.first(call.getPlanner().getContext().unwrap(RexExecutor.class),
- Util.first(call.getPlanner().getExecutor(), RexUtil.EXECUTOR));
- // unknownAsFalse => true since in the WHERE clause:
- // 1>null evaluates to unknown and WHERE unknown behaves exactly like WHERE false
- RexSimplify simplifier =
- new RexSimplify(xBuilder, RelOptPredicateList.EMPTY, executor);
- return RexUtil.removeNullabilityCast(
- xBuilder.getTypeFactory(), simplifier.simplifyUnknownAsFalse(condition));
- }
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
index e3cb5c4..96efc53 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexBuilder.java
@@ -1374,7 +1374,8 @@ public class RexBuilder {
value = clean(value, type);
RexLiteral literal;
final List<RexNode> operands;
- switch (type.getSqlTypeName()) {
+ final SqlTypeName sqlTypeName = type.getSqlTypeName();
+ switch (sqlTypeName) {
case CHAR:
return makeCharLiteral(padRight((NlsString) value, type.getPrecision()));
case VARCHAR:
@@ -1468,7 +1469,7 @@ public class RexBuilder {
return makeCall(SqlStdOperatorTable.MULTISET_VALUE, operands);
} else {
return new RexLiteral((Comparable) FlatLists.of(operands), type,
- type.getSqlTypeName());
+ sqlTypeName);
}
case ROW:
operands = new ArrayList<>();
@@ -1481,11 +1482,12 @@ public class RexBuilder {
operands.add(e);
}
return new RexLiteral((Comparable) FlatLists.of(operands), type,
- type.getSqlTypeName());
+ sqlTypeName);
case ANY:
return makeLiteral(value, guessType(value), allowCast);
default:
- throw Util.unexpected(type.getSqlTypeName());
+ throw new IllegalArgumentException(
+ "Cannot create literal for type '" + sqlTypeName + "'");
}
}
diff --git a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
index a3b52f0..827c152 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -2210,10 +2210,11 @@ public class RexSimplify {
this.literal = Objects.requireNonNull(literal);
}
- /** Creates a comparison, between a {@link RexInputRef} or {@link RexFieldAccess}
- * and a literal. */
+ /** Creates a comparison, between a {@link RexInputRef} or {@link RexFieldAccess} or
+ * deterministic {@link RexCall} and a literal. */
static Comparison of(RexNode e) {
- return of(e, node -> RexUtil.isReferenceOrAccess(node, true));
+ return of(e, node -> RexUtil.isReferenceOrAccess(node, true)
+ || RexUtil.isDeterministic(node));
}
/** Creates a comparison, or returns null. */
diff --git a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
index 83e0e4a..ffa37b3 100644
--- a/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
+++ b/core/src/test/java/org/apache/calcite/test/JdbcAdapterTest.java
@@ -302,19 +302,19 @@ public class JdbcAdapterTest {
+ "from scott.emp e,scott.dept d \n"
+ "where e.deptno = d.deptno")
.explainContains("PLAN=JdbcToEnumerableConverter\n"
- + " JdbcProject(EMPNO=[$0], ENAME=[$1], DEPTNO=[$3], DNAME=[$4])\n"
- + " JdbcJoin(condition=[=($2, $3)], joinType=[inner])\n"
- + " JdbcProject(EMPNO=[$0], ENAME=[$1], DEPTNO=[$7])\n"
- + " JdbcTableScan(table=[[SCOTT, EMP]])\n"
+ + " JdbcProject(EMPNO=[$2], ENAME=[$3], DEPTNO=[$0], DNAME=[$1])\n"
+ + " JdbcJoin(condition=[=($4, $0)], joinType=[inner])\n"
+ " JdbcProject(DEPTNO=[$0], DNAME=[$1])\n"
- + " JdbcTableScan(table=[[SCOTT, DEPT]])")
+ + " JdbcTableScan(table=[[SCOTT, DEPT]])\n"
+ + " JdbcProject(EMPNO=[$0], ENAME=[$1], DEPTNO=[$7])\n"
+ + " JdbcTableScan(table=[[SCOTT, EMP]])")
.runs()
.enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
- .planHasSql("SELECT \"t\".\"EMPNO\", \"t\".\"ENAME\", "
- + "\"t0\".\"DEPTNO\", \"t0\".\"DNAME\"\n"
- + "FROM (SELECT \"EMPNO\", \"ENAME\", \"DEPTNO\"\nFROM \"SCOTT\".\"EMP\") AS \"t\"\n"
- + "INNER JOIN (SELECT \"DEPTNO\", \"DNAME\"\n"
- + "FROM \"SCOTT\".\"DEPT\") AS \"t0\" ON \"t\".\"DEPTNO\" = \"t0\".\"DEPTNO\"");
+ .planHasSql("SELECT \"t0\".\"EMPNO\", \"t0\".\"ENAME\", "
+ + "\"t\".\"DEPTNO\", \"t\".\"DNAME\"\n"
+ + "FROM (SELECT \"DEPTNO\", \"DNAME\"\nFROM \"SCOTT\".\"DEPT\") AS \"t\"\n"
+ + "INNER JOIN (SELECT \"EMPNO\", \"ENAME\", \"DEPTNO\"\n"
+ + "FROM \"SCOTT\".\"EMP\") AS \"t0\" ON \"t\".\"DEPTNO\" = \"t0\".\"DEPTNO\"");
}
// JdbcJoin not used for this
@@ -341,22 +341,20 @@ public class JdbcAdapterTest {
+ "where e.deptno = d.deptno \n"
+ "and e.deptno=20")
.explainContains("PLAN=JdbcToEnumerableConverter\n"
- + " JdbcProject(EMPNO=[$0], ENAME=[$1], DEPTNO=[$3], DNAME=[$4])\n"
- + " JdbcJoin(condition=[=($2, $3)], joinType=[inner])\n"
+ + " JdbcProject(EMPNO=[$2], ENAME=[$3], DEPTNO=[$0], DNAME=[$1])\n"
+ + " JdbcJoin(condition=[=($4, $0)], joinType=[inner])\n"
+ + " JdbcProject(DEPTNO=[$0], DNAME=[$1])\n"
+ + " JdbcTableScan(table=[[SCOTT, DEPT]])\n"
+ " JdbcProject(EMPNO=[$0], ENAME=[$1], DEPTNO=[$7])\n"
+ " JdbcFilter(condition=[=(CAST($7):INTEGER, 20)])\n"
- + " JdbcTableScan(table=[[SCOTT, EMP]])\n"
- + " JdbcProject(DEPTNO=[$0], DNAME=[$1])\n"
- + " JdbcTableScan(table=[[SCOTT, DEPT]])")
+ + " JdbcTableScan(table=[[SCOTT, EMP]])")
.runs()
.enable(CalciteAssert.DB == CalciteAssert.DatabaseInstance.HSQLDB)
- .planHasSql("SELECT \"t0\".\"EMPNO\", \"t0\".\"ENAME\", "
- + "\"t1\".\"DEPTNO\", \"t1\".\"DNAME\"\n"
- + "FROM (SELECT \"EMPNO\", \"ENAME\", \"DEPTNO\"\n"
- + "FROM \"SCOTT\".\"EMP\"\n"
- + "WHERE CAST(\"DEPTNO\" AS INTEGER) = 20) AS \"t0\"\n"
- + "INNER JOIN (SELECT \"DEPTNO\", \"DNAME\"\n"
- + "FROM \"SCOTT\".\"DEPT\") AS \"t1\" ON \"t0\".\"DEPTNO\" = \"t1\".\"DEPTNO\"");
+ .planHasSql("SELECT \"t1\".\"EMPNO\", \"t1\".\"ENAME\", \"t\".\"DEPTNO\", \"t\".\"DNAME\"\n"
+ + "FROM (SELECT \"DEPTNO\", \"DNAME\"\nFROM \"SCOTT\".\"DEPT\") AS \"t\"\n"
+ + "INNER JOIN (SELECT \"EMPNO\", \"ENAME\", \"DEPTNO\"\n"
+ + "FROM \"SCOTT\".\"EMP\"\nWHERE CAST(\"DEPTNO\" AS INTEGER) = 20) "
+ + "AS \"t1\" ON \"t\".\"DEPTNO\" = \"t1\".\"DEPTNO\"");
}
/** Test case for
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java b/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java
index 7e549fa..50d188c 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramBuilderBase.java
@@ -29,7 +29,6 @@ import org.apache.calcite.rex.RexCall;
import org.apache.calcite.rex.RexDynamicParam;
import org.apache.calcite.rex.RexExecutor;
import org.apache.calcite.rex.RexExecutorImpl;
-import org.apache.calcite.rex.RexInputRef;
import org.apache.calcite.rex.RexLiteral;
import org.apache.calcite.rex.RexNode;
import org.apache.calcite.rex.RexSimplify;
@@ -317,7 +316,7 @@ public abstract class RexProgramBuilderBase {
return rexBuilder.makeCall(SqlStdOperatorTable.PLUS, n1, n2);
}
- protected RexNode item(RexInputRef inputRef, RexNode literal) {
+ protected RexNode item(RexNode inputRef, RexNode literal) {
RexNode rexNode = rexBuilder.makeCall(
SqlStdOperatorTable.ITEM,
inputRef,
@@ -368,6 +367,9 @@ public abstract class RexProgramBuilderBase {
return nullable ? nullableInt : nonNullableInt;
}
+ protected RelDataType tArray(RelDataType elemType) {
+ return typeFactory.createArrayType(elemType, -1);
+ }
// Literals
/**
diff --git a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
index cd10236..403067d 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -620,26 +620,17 @@ public class RexProgramTest extends RexProgramBuilderBase {
}
@Test public void testItemStrong() {
- final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
-
final ImmutableBitSet c0 = ImmutableBitSet.of(0);
- final RelDataType intArray = typeFactory.createArrayType(intType, -1);
- RexInputRef inputRef = rexBuilder.makeInputRef(intArray, 0);
-
- RexNode rexNode = item(inputRef, literal(0));
-
- assertThat(Strong.isStrong(rexNode), is(true));
-
- assertThat(Strong.isNull(rexNode, c0), is(true));
+ RexNode item = item(input(tArray(tInt()), 0), literal(0));
- final RelDataType varcharType = typeFactory.createSqlType(SqlTypeName.VARCHAR);
- final RelDataType mapType = typeFactory.createMapType(varcharType, varcharType);
+ assertThat(Strong.isStrong(item), is(true));
+ assertThat(Strong.isNull(item, c0), is(true));
- inputRef = rexBuilder.makeInputRef(mapType, 0);
- rexNode = item(inputRef, literal("abc"));
- assertThat(Strong.isStrong(rexNode), is(true));
+ RelDataType mapType = typeFactory.createMapType(tVarchar(), tVarchar());
+ item = item(input(mapType, 0), literal("abc"));
- assertThat(Strong.isNull(rexNode, c0), is(true));
+ assertThat(Strong.isStrong(item), is(true));
+ assertThat(Strong.isNull(item, c0), is(true));
}
@Test public void xAndNotX() {
@@ -1733,6 +1724,20 @@ public class RexProgramTest extends RexProgramBuilderBase {
"true");
}
+ @Test public void testSimplifyItemRangeTerms() {
+ RexNode item = item(input(tArray(tInt()), 3), literal(1));
+ // paranoid validation doesn't support array types, disable it for a moment
+ simplify = this.simplify.withParanoid(false);
+ // (a=1 or a=2 or (arr[1]>4 and arr[1]<3 and a=3)) => a=1 or a=2
+ checkSimplifyFilter(
+ or(
+ eq(vInt(), literal(1)),
+ eq(vInt(), literal(2)),
+ and(gt(item, literal(4)), lt(item, literal(3)), eq(vInt(), literal(3)))),
+ "OR(=(?0.int0, 1), =(?0.int0, 2))");
+ simplify = simplify.withParanoid(true);
+ }
+
@Test public void testSimplifyNotAnd() {
final RexNode e = or(
le(
diff --git a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
index ed8997a..04b4775 100644
--- a/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
+++ b/core/src/test/java/org/apache/calcite/test/ScannableTableTest.java
@@ -371,7 +371,7 @@ public class ScannableTableTest {
@Test public void testProjectableFilterableTableJoin() throws Exception {
final StringBuilder buf = new StringBuilder();
final String explain = "PLAN="
- + "EnumerableHashJoin(condition=[=($0, $3)], joinType=[inner])\n"
+ + "EnumerableNestedLoopJoin(condition=[true], joinType=[inner])\n"
+ " EnumerableInterpreter\n"
+ " BindableTableScan(table=[[s, b1]], filters=[[=($0, 10)]])\n"
+ " EnumerableInterpreter\n"
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 711ca25..baff85e 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
@@ -125,10 +125,10 @@ public class EnumerableCorrelateTest {
})
.explainContains(""
+ "EnumerableCalc(expr#0..3=[{inputs}], empid=[$t1], name=[$t3])\n"
- + " EnumerableCorrelate(correlation=[$cor5], joinType=[inner], requiredColumns=[{0}])\n"
+ + " EnumerableCorrelate(correlation=[$cor4], joinType=[inner], requiredColumns=[{0}])\n"
+ " EnumerableAggregate(group=[{0}])\n"
+ " EnumerableTableScan(table=[[s, depts]])\n"
- + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[100], expr#6=[>($t0, $t5)], expr#7=[$cor5], expr#8=[$t7.deptno], expr#9=[=($t1, $t8)], expr#10=[AND($t6, $t9)], proj#0..2=[{exprs}], $condition=[$t10])\n"
+ + " EnumerableCalc(expr#0..4=[{inputs}], expr#5=[$cor4], expr#6=[$t5.deptno], expr#7=[=($t1, $t6)], expr#8=[100], expr#9=[>($t0, $t8)], expr#10=[AND($t7, $t9)], proj#0..2=[{exprs}], $condition=[$t10])\n"
+ " EnumerableTableScan(table=[[s, emps]])")
.returnsUnordered(
"empid=110; name=Theodore",
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index 43989bb..4e63283 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -639,7 +639,7 @@ select count(*) as c
from "customer"
where period ("birthdate", DATE '1970-02-05') contains DATE '1964-01-01';
EnumerableAggregate(group=[{}], C=[COUNT()])
- EnumerableCalc(expr#0..28=[{inputs}], expr#29=[1970-02-05], expr#30=[<=($t16, $t29)], expr#31=[CASE($t30, $t16, $t29)], expr#32=[1964-01-01], expr#33=[<=($t31, $t32)], expr#34=[CASE($t30, $t29, $t16)], expr#35=[>=($t34, $t32)], expr#36=[AND($t33, $t35)], proj#0..28=[{exprs}], $condition=[$t36])
+ EnumerableCalc(expr#0..28=[{inputs}], expr#29=[1964-01-01], expr#30=[<=($t16, $t29)], proj#0..28=[{exprs}], $condition=[$t30])
EnumerableTableScan(table=[[foodmart2, customer]])
!plan
+------+
@@ -683,7 +683,7 @@ from "sales_fact_1997" as s
join "product_class" as pc on p."product_class_id" = pc."product_class_id"
where c."city" = 'San Francisco'
and pc."product_department" = 'Snacks';
-EnumerableCalc(expr#0..56=[{inputs}], product_id=[$t20], time_id=[$t21], customer_id=[$t22], promotion_id=[$t23], store_id=[$t24], store_sales=[$t25], store_cost=[$t26], unit_sales=[$t27], customer_id0=[$t28], account_num=[$t29], lname=[$t30], fname=[$t31], mi=[$t32], address1=[$t33], address2=[$t34], address3=[$t35], address4=[$t36], city=[$t37], state_province=[$t38], postal_code=[$t39], country=[$t40], customer_region_id=[$t41], phone1=[$t42], phone2=[$t43], birthdate=[$t44], marital_ [...]
+EnumerableCalc(expr#0..56=[{inputs}], product_id0=[$t20], time_id=[$t21], customer_id=[$t22], promotion_id=[$t23], store_id=[$t24], store_sales=[$t25], store_cost=[$t26], unit_sales=[$t27], customer_id0=[$t28], account_num=[$t29], lname=[$t30], fname=[$t31], mi=[$t32], address1=[$t33], address2=[$t34], address3=[$t35], address4=[$t36], city=[$t37], state_province=[$t38], postal_code=[$t39], country=[$t40], customer_region_id=[$t41], phone1=[$t42], phone2=[$t43], birthdate=[$t44], marital [...]
EnumerableHashJoin(condition=[=($6, $20)], joinType=[inner])
EnumerableHashJoin(condition=[=($0, $5)], joinType=[inner])
EnumerableCalc(expr#0..4=[{inputs}], expr#5=['Snacks':VARCHAR(30)], expr#6=[=($t3, $t5)], proj#0..4=[{exprs}], $condition=[$t6])
@@ -1123,7 +1123,7 @@ select * from "scott".emp where hiredate < '1981-01-02';
(1 row)
!ok
-EnumerableCalc(expr#0..7=[{inputs}], expr#8=['1981-01-02'], expr#9=[CAST($t8):DATE NOT NULL], expr#10=[<($t4, $t9)], proj#0..7=[{exprs}], $condition=[$t10])
+EnumerableCalc(expr#0..7=[{inputs}], expr#8=[1981-01-02], expr#9=[<($t4, $t8)], proj#0..7=[{exprs}], $condition=[$t9])
EnumerableTableScan(table=[[scott, EMP]])
!plan
select * from "scott".emp where '1981-01-02' > hiredate;
diff --git a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
index 35567be..701aaca 100644
--- a/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
+++ b/mongodb/src/test/java/org/apache/calcite/adapter/mongodb/MongoAdapterTest.java
@@ -284,22 +284,15 @@ public class MongoAdapterTest implements SchemaFactory {
.runs();
}
- /** Tests that we don't generate multiple constraints on the same column.
- * MongoDB doesn't like it. If there is an '=', it supersedes all other
- * operators. */
+ /**
+ * Tests that mongo query is empty when filter simplified to false.
+ */
@Test public void testFilterRedundant() {
assertModel(MODEL)
.query(
"select * from zips where state > 'CA' and state < 'AZ' and state = 'OK'")
.runs()
- .queryContains(
- mongoChecker(
- "{\n"
- + " \"$match\": {\n"
- + " \"state\": \"OK\"\n"
- + " }\n"
- + "}",
- "{$project: {CITY: '$city', LONGITUDE: '$loc[0]', LATITUDE: '$loc[1]', POP: '$pop', STATE: '$state', ID: '$_id'}}"));
+ .queryContains(mongoChecker());
}
@Test public void testSelectWhere() {
diff --git a/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java b/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
index 2ca751d..89a0eb6 100644
--- a/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
+++ b/spark/src/test/java/org/apache/calcite/test/SparkAdapterTest.java
@@ -524,8 +524,7 @@ public class SparkAdapterTest {
+ "where false";
final String plan = "PLAN="
- + "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[false], proj#0..1=[{exprs}], $condition=[$t2])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, { 2, 'c' }, { 2, 'c' }]])\n\n";
+ + "EnumerableValues(tuples=[[]])\n\n";
final String expectedResult = "";
@@ -576,8 +575,7 @@ public class SparkAdapterTest {
+ "where x is null";
final String plan = "PLAN="
- + "EnumerableCalc(expr#0..1=[{inputs}], expr#2=[IS NULL($t0)], proj#0..1=[{exprs}], $condition=[$t2])\n"
- + " EnumerableValues(tuples=[[{ 1, 'a' }, { 2, 'b' }, { 1, 'b' }, { 2, 'c' }, { 2, 'c' }]])\n\n";
+ + "EnumerableValues(tuples=[[]])\n\n";
final String expectedResult = "";