Skip to content

Commit 9f87b8f

Browse files
author
wangyanjing
committed
[CALCITE-6718] Optimize SubstitutionVisitor's splitFilter with early return and uniform simplification for equivalence checking
1 parent 0eb83b1 commit 9f87b8f

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

core/src/main/java/org/apache/calcite/plan/SubstitutionVisitor.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,11 @@ void register(MutableRel result, MutableRel query) {
297297
RexNode condition, RexNode target) {
298298
final RexBuilder rexBuilder = simplify.rexBuilder;
299299
condition = simplify.simplify(condition);
300-
target = simplify.simplify(target);
301300
RexNode condition2 = canonizeNode(rexBuilder, condition);
301+
if (target.isAlwaysTrue()) {
302+
return condition2;
303+
}
304+
target = simplify.simplify(target);
302305
RexNode target2 = canonizeNode(rexBuilder, target);
303306

304307
// First, try splitting into ORs.
@@ -321,7 +324,7 @@ void register(MutableRel result, MutableRel query) {
321324
RexUtil.composeConjunction(rexBuilder,
322325
ImmutableList.of(condition2, target2));
323326
RexNode r =
324-
canonizeNode(rexBuilder, simplify.simplifyUnknownAsFalse(x2));
327+
canonizeNode(rexBuilder, simplify.simplify(x2));
325328
if (!r.isAlwaysFalse() && isEquivalent(condition2, r)) {
326329
List<RexNode> conjs = RelOptUtil.conjunctions(r);
327330
for (RexNode e : RelOptUtil.conjunctions(target2)) {

core/src/test/java/org/apache/calcite/test/MaterializedViewSubstitutionVisitorTest.java

+36-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.apache.calcite.rex.RexSimplify;
3535
import org.apache.calcite.rex.RexUtil;
3636
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
37+
import org.apache.calcite.sql.type.SqlTypeName;
3738
import org.apache.calcite.util.Pair;
3839

3940
import com.google.common.collect.ImmutableList;
@@ -1646,11 +1647,14 @@ protected final MaterializedViewFixture sql(String materialize,
16461647
final RexBuilder rexBuilder = f.rexBuilder;
16471648
final RexSimplify simplify = f.simplify;
16481649

1650+
final RelDataType intType = f.typeFactory.createType(int.class);
1651+
final RelDataType booleanType = f.typeFactory.createSqlType(SqlTypeName.BOOLEAN);
16491652
final RexLiteral i1 = rexBuilder.makeExactLiteral(BigDecimal.ONE);
16501653
final RexLiteral i2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(2));
16511654
final RexLiteral i3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(3));
1655+
final RexLiteral nullIntLiteral = rexBuilder.makeNullLiteral(intType);
1656+
final RexLiteral nullBooleanLiteral = rexBuilder.makeNullLiteral(booleanType);
16521657

1653-
final RelDataType intType = f.typeFactory.createType(int.class);
16541658
final RexInputRef x = rexBuilder.makeInputRef(intType, 0); // $0
16551659
final RexInputRef y = rexBuilder.makeInputRef(intType, 1); // $1
16561660
final RexInputRef z = rexBuilder.makeInputRef(intType, 2); // $2
@@ -1695,6 +1699,15 @@ protected final MaterializedViewFixture sql(String materialize,
16951699
rexBuilder.makeCall(SqlStdOperatorTable.PLUS, x, y),
16961700
i2);
16971701

1702+
// x in (null:int)
1703+
final RexNode x_in_null = rexBuilder.makeIn(x, ImmutableList.of(nullIntLiteral));
1704+
// x in (null:int) and x = 1
1705+
final RexNode x_in_null_and_x_eq_1 =
1706+
rexBuilder.makeCall(SqlStdOperatorTable.AND, x_in_null, x_eq_1);
1707+
// x = 1 and null:boolean
1708+
final RexNode x_eq_1_and_null =
1709+
rexBuilder.makeCall(SqlStdOperatorTable.AND, x_eq_1, nullBooleanLiteral);
1710+
16981711
RexNode newFilter;
16991712

17001713
// Example 1.
@@ -1853,6 +1866,28 @@ protected final MaterializedViewFixture sql(String materialize,
18531866
SubstitutionVisitor.splitFilter(simplify, x_times_y_gt, y_times_x_gt);
18541867
assertThat(newFilter, notNullValue());
18551868
assertThat(newFilter.isAlwaysTrue(), equalTo(true));
1869+
1870+
// Example 11.
1871+
// condition: x in (null:int) and x = 1
1872+
// target: true
1873+
// yields
1874+
// residue: x = 1 and null:boolean
1875+
newFilter =
1876+
SubstitutionVisitor.splitFilter(simplify, x_in_null_and_x_eq_1,
1877+
rexBuilder.makeLiteral(true));
1878+
assertThat(newFilter, notNullValue());
1879+
assertThat(newFilter, equalTo(x_eq_1_and_null));
1880+
1881+
// Example 12.
1882+
// condition: x in (null:int) and x = 1
1883+
// target: x = 1
1884+
// yields
1885+
// residue: null:boolean
1886+
newFilter =
1887+
SubstitutionVisitor.splitFilter(simplify, x_in_null_and_x_eq_1,
1888+
x_eq_1);
1889+
assertThat(newFilter, notNullValue());
1890+
assertThat(newFilter, equalTo(nullBooleanLiteral));
18561891
}
18571892

18581893
@Test void testSubQuery() {

0 commit comments

Comments
 (0)