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 = "";