Skip to content

Commit

Permalink
[CALCITE-2582] FilterProjectTransposeRule does not always simplify th…
Browse files Browse the repository at this point in the history
…e new filter condition

1. Simplify newCondition in a similar manner to RelBuilder#filter method.

2. Update tests in misc.iq, sub-query.iq, GeodeZipsTest, GeodeAllDataTypesTest to reflect the applied simplifications.
  • Loading branch information
zabetak committed Feb 21, 2019
1 parent e448920 commit 233d9dd
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
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;
Expand All @@ -24,11 +25,15 @@
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.function.Predicate;

Expand Down Expand Up @@ -151,8 +156,7 @@ public void onMatch(RelOptRuleCall call) {
RelNode newFilterRel;
if (copyFilter) {
newFilterRel = filter.copy(filter.getTraitSet(), project.getInput(),
RexUtil.removeNullabilityCast(relBuilder.getTypeFactory(),
newCondition));
simplifyFilterCondition(newCondition, call));
} else {
newFilterRel =
relBuilder.push(project.getInput()).filter(newCondition).build();
Expand All @@ -168,6 +172,28 @@ public void onMatch(RelOptRuleCall call) {

call.transformTo(newProjRel);
}

/**
* Simplifies the filter condition using a simplifier created by the information in the
* current call.
*
* The 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));
}
}

// End FilterProjectTransposeRule.java
2 changes: 1 addition & 1 deletion core/src/test/resources/sql/misc.iq
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ EnumerableCalc(expr#0..7=[{inputs}], expr#8=[IS NULL($t5)], expr#9=[IS NULL($t7)
EnumerableCalc(expr#0..3=[{inputs}], expr#4=[true], deptno=[$t0], $f0=[$t4])
EnumerableTableScan(table=[[hr, depts]])
EnumerableAggregate(group=[{0}], agg#0=[MIN($1)])
EnumerableCalc(expr#0..3=[{inputs}], expr#4=[90], expr#5=[+($t0, $t4)], expr#6=[true], $f4=[$t5], $f0=[$t6], $condition=[$t6])
EnumerableCalc(expr#0..3=[{inputs}], expr#4=[90], expr#5=[+($t0, $t4)], expr#6=[true], $f4=[$t5], $f0=[$t6])
EnumerableTableScan(table=[[hr, depts]])
!plan

Expand Down
16 changes: 8 additions & 8 deletions core/src/test/resources/sql/sub-query.iq
Original file line number Diff line number Diff line change
Expand Up @@ -624,7 +624,7 @@ where exists (
!ok
EnumerableSemiJoin(condition=[=($0, $10)], joinType=[inner])
EnumerableTableScan(table=[[scott, DEPT]])
EnumerableCalc(expr#0..7=[{inputs}], expr#8=[=($t7, $t7)], expr#9=['SMITH':VARCHAR(10)], expr#10=[=($t1, $t9)], expr#11=[AND($t8, $t10)], proj#0..7=[{exprs}], $condition=[$t11])
EnumerableCalc(expr#0..7=[{inputs}], expr#8=['SMITH':VARCHAR(10)], expr#9=[=($t1, $t8)], expr#10=[IS NOT NULL($t7)], expr#11=[AND($t9, $t10)], proj#0..7=[{exprs}], $condition=[$t11])
EnumerableTableScan(table=[[scott, EMP]])
!plan

Expand Down Expand Up @@ -831,7 +831,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], expr#
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], expr#4=[123], expr#5=[null:INTEGER], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], cs=[$t3])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down Expand Up @@ -1009,7 +1009,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], expr#
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down Expand Up @@ -1081,7 +1081,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], expr#4=[123], expr#5=[null:INTEGER], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], cs=[$t3])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down Expand Up @@ -1259,7 +1259,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t3)], expr#5=[false], expr
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down Expand Up @@ -1424,7 +1424,7 @@ select sal from "scott".emp
EnumerableCalc(expr#0..2=[{inputs}], SAL=[$t2])
EnumerableJoin(condition=[true], joinType=[inner])
EnumerableAggregate(group=[{0}])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], cs=[$t3], $condition=[$t6])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
EnumerableCalc(expr#0..7=[{inputs}], EMPNO=[$t0], SAL=[$t5])
EnumerableTableScan(table=[[scott, EMP]])
Expand Down Expand Up @@ -1468,7 +1468,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], expr#
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], expr#4=[123], expr#5=[null:INTEGER], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[false], cs=[$t3])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down Expand Up @@ -1573,7 +1573,7 @@ EnumerableCalc(expr#0..3=[{inputs}], expr#4=[false], expr#5=[=($t2, $t4)], expr#
EnumerableLimit(fetch=[1])
EnumerableSort(sort0=[$0], dir0=[DESC])
EnumerableAggregate(group=[{0}], c=[COUNT()])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[CAST($t0):TINYINT], expr#6=[=($t4, $t5)], expr#7=[IS NULL($t5)], expr#8=[OR($t6, $t7)], cs=[$t3], $condition=[$t8])
EnumerableCalc(expr#0..2=[{inputs}], expr#3=[true], expr#4=[10], expr#5=[=($t4, $t0)], cs=[$t3], $condition=[$t5])
EnumerableTableScan(table=[[scott, DEPT]])
!plan

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ public void testSqlWhereWithMultipleOrForLiteralFields() {
.queryContains(
GeodeAssertions.query("SELECT stringValue AS stringValue "
+ "FROM /allDataTypesRegion WHERE "
+ "stringValue IN SET('abc', 'def') OR floatValue IN SET(1.5678, null) "
+ "OR booleanValue IN SET(true, false, null)"));
+ "stringValue IN SET('abc', 'def') OR floatValue = 1.5678 "
+ "OR booleanValue IN SET(true, false)"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ public void testSqlSingleStringWhereFilter() {
@Test
public void testWhereWithOrWithEmptyResult() {
String expectedQuery = "SELECT state AS state FROM /zips "
+ "WHERE state IN SET('', null, true, false, 123, 13.892)";
+ "WHERE state IN SET('', true, false, 123, 13.892)";
calciteAssert()
.query("SELECT state as state "
+ "FROM view WHERE state = '' OR state = null OR "
Expand Down

0 comments on commit 233d9dd

Please sign in to comment.