diff --git a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
index 4e2d890..07718a3 100644
--- a/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
+++ b/core/src/main/java/org/apache/calcite/rel/rules/ReduceExpressionsRule.java
@@ -510,16 +510,61 @@ protected static void findReducibleExps(RelDataTypeFactory typeFactory,
// We cannot use an ImmutableMap.Builder here. If there are multiple entries
// with the same key (e.g. "WHERE deptno = 1 AND deptno = 2"), it doesn't
// matter which we take, so the latter will replace the former.
- final Map builder = Maps.newHashMap();
+ // The basic idea is to find all the pairs of RexNode = RexLiteral
+ // (1) If 'predicates' contain a non-EQUALS, we bail out.
+ // (2) It is OK if a RexNode is equal to the same RexLiteral several times,
+ // (e.g. "WHERE deptno = 1 AND deptno = 1")
+ // (3) It will return false if there are inconsistent constraints (e.g.
+ // "WHERE deptno = 1 AND deptno = 2")
+ Map builder = Maps.newHashMap();
+ boolean findUsefulConstants = true;
for (RexNode predicate : predicates.pulledUpPredicates) {
- switch (predicate.getKind()) {
- case EQUALS:
+ if (predicate.getKind().equals(SqlKind.EQUALS)) {
final List operands = ((RexCall) predicate).getOperands();
- if (operands.get(1) instanceof RexLiteral) {
- builder.put(operands.get(0), (RexLiteral) operands.get(1));
+ if (operands.size() != 2) {
+ findUsefulConstants = false;
+ break;
+ } else {
+ if (operands.get(1) instanceof RexLiteral) {
+ RexLiteral literal = builder.get(operands.get(0));
+ if (literal == null) {
+ builder.put(operands.get(0), (RexLiteral) operands.get(1));
+ } else {
+ RexLiteral newLiteral = (RexLiteral) operands.get(1);
+ if (!literal.getValue().equals(newLiteral)) {
+ // should return false
+ // we bail out, the reduce filter expression rule should be able
+ // to deal with this.
+ findUsefulConstants = false;
+ break;
+ }
+ }
+ } else if (operands.get(0) instanceof RexLiteral) {
+ RexLiteral literal = builder.get(operands.get(1));
+ if (literal == null) {
+ builder.put(operands.get(1), (RexLiteral) operands.get(0));
+ } else {
+ RexLiteral newLiteral = (RexLiteral) operands.get(0);
+ if (!literal.getValue().equals(newLiteral)) {
+ // should return false
+ // we bail out, the reduce filter expression rule should be able
+ // to deal with this.
+ findUsefulConstants = false;
+ break;
+ }
+ }
+ } else {
+ findUsefulConstants = false;
+ break;
+ }
}
+ } else {
+ findUsefulConstants = false;
}
}
+ if (!findUsefulConstants) {
+ builder = Maps.newHashMap();
+ }
return ImmutableMap.copyOf(builder);
}
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 ddfefbb..818451c 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -646,7 +646,7 @@ LogicalProject(DEPTNO=[$0])
@@ -2908,8 +2908,8 @@ LogicalProject(EMPNO=[$0], ENAME=[$1], JOB=[$2], MGR=[$3], HIREDATE=[$4], SAL=[$