Skip to content

Commit

Permalink
[CALCITE-6718] Optimize SubstitutionVisitor's splitFilter with early …
Browse files Browse the repository at this point in the history
…return and uniform simplification for equivalence checking
  • Loading branch information
wangyanjing committed Dec 7, 2024
1 parent 0eb83b1 commit cf9b38d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -297,8 +297,11 @@ void register(MutableRel result, MutableRel query) {
RexNode condition, RexNode target) {
final RexBuilder rexBuilder = simplify.rexBuilder;
condition = simplify.simplify(condition);
target = simplify.simplify(target);
RexNode condition2 = canonizeNode(rexBuilder, condition);
if (target.isAlwaysTrue()) {
return condition2;
}
target = simplify.simplify(target);
RexNode target2 = canonizeNode(rexBuilder, target);

// First, try splitting into ORs.
Expand All @@ -321,7 +324,7 @@ void register(MutableRel result, MutableRel query) {
RexUtil.composeConjunction(rexBuilder,
ImmutableList.of(condition2, target2));
RexNode r =
canonizeNode(rexBuilder, simplify.simplifyUnknownAsFalse(x2));
canonizeNode(rexBuilder, simplify.simplify(x2));
if (!r.isAlwaysFalse() && isEquivalent(condition2, r)) {
List<RexNode> conjs = RelOptUtil.conjunctions(r);
for (RexNode e : RelOptUtil.conjunctions(target2)) {
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/apache/calcite/rex/RexSimplify.java
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ RexNode simplifyAnd(RexCall e, RexUnknownAs unknownAs) {
if (unknownAs == FALSE && predicateElimination) {
simplifyAndTerms(operands, FALSE);
} else {
simplifyList(operands, unknownAs);
simplifyAndTerms(operands, unknownAs);
}

final List<RexNode> terms = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import org.apache.calcite.rex.RexSimplify;
import org.apache.calcite.rex.RexUtil;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.util.Pair;

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

final RelDataType intType = f.typeFactory.createType(int.class);
final RelDataType booleanType = f.typeFactory.createSqlType(SqlTypeName.BOOLEAN);
final RexLiteral i1 = rexBuilder.makeExactLiteral(BigDecimal.ONE);
final RexLiteral i2 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(2));
final RexLiteral i3 = rexBuilder.makeExactLiteral(BigDecimal.valueOf(3));
final RexLiteral nullIntLiteral = rexBuilder.makeNullLiteral(intType);
final RexLiteral nullBooleanLiteral = rexBuilder.makeNullLiteral(booleanType);

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

// x in (null:int)
final RexNode x_in_null = rexBuilder.makeIn(x, ImmutableList.of(nullIntLiteral));
// x in (null:int) and x = 1
final RexNode x_in_null_and_x_eq_1 =
rexBuilder.makeCall(SqlStdOperatorTable.AND, x_in_null, x_eq_1);
// x = 1 and null:boolean
final RexNode x_eq_1_and_null =
rexBuilder.makeCall(SqlStdOperatorTable.AND, x_eq_1, nullBooleanLiteral);

RexNode newFilter;

// Example 1.
Expand Down Expand Up @@ -1853,6 +1866,28 @@ protected final MaterializedViewFixture sql(String materialize,
SubstitutionVisitor.splitFilter(simplify, x_times_y_gt, y_times_x_gt);
assertThat(newFilter, notNullValue());
assertThat(newFilter.isAlwaysTrue(), equalTo(true));

// Example 11.
// condition: x in (null:int) and x = 1
// target: true
// yields
// residue: x = 1 and null:boolean
newFilter =
SubstitutionVisitor.splitFilter(simplify, x_in_null_and_x_eq_1,
rexBuilder.makeLiteral(true));
assertThat(newFilter, notNullValue());
assertThat(newFilter, equalTo(x_eq_1_and_null));

// Example 12.
// condition: x in (null:int) and x = 1
// target: x = 1
// yields
// residue: null:boolean
newFilter =
SubstitutionVisitor.splitFilter(simplify, x_in_null_and_x_eq_1,
x_eq_1);
assertThat(newFilter, notNullValue());
assertThat(newFilter, equalTo(nullBooleanLiteral));
}

@Test void testSubQuery() {
Expand Down

0 comments on commit cf9b38d

Please sign in to comment.