This is an automated email from the ASF dual-hosted git repository.
kgyrtkirk 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 f7762b6 [CALCITE-3192] Simplification may weaken OR conditions
containing inequalities
f7762b6 is described below
commit f7762b6a7cd85711a8cc6d7c7174dedca22bdcd2
Author: Zoltan Haindrich <[email protected]>
AuthorDate: Mon Jul 29 17:51:53 2019 +0200
[CALCITE-3192] Simplification may weaken OR conditions containing
inequalities
For expressions like: (1 < x or ( x < 3 and c ))
simplification was made to ( 1 < x or c )
---
.../java/org/apache/calcite/rex/RexSimplify.java | 29 ++++++++++++++++++++--
.../org/apache/calcite/test/RexProgramTest.java | 12 +++++++++
.../org/apache/calcite/test/RelOptRulesTest.xml | 4 +--
3 files changed, 41 insertions(+), 4 deletions(-)
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 187b926..bbf6b28 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -502,7 +502,7 @@ public class RexSimplify {
RexSimplify simplify = this;
for (int i = 0; i < terms.size(); i++) {
final RexNode t = terms.get(i);
- if (Predicate.of(t) == null) {
+ if (!allowedAsPredicateDuringOrSimplification(t)) {
continue;
}
final RexNode t2 = simplify.simplify(t, unknownAs);
@@ -516,13 +516,38 @@ public class RexSimplify {
}
for (int i = 0; i < terms.size(); i++) {
final RexNode t = terms.get(i);
- if (Predicate.of(t) != null) {
+ if (allowedAsPredicateDuringOrSimplification(t)) {
continue;
}
terms.set(i, simplify.simplify(t, unknownAs));
}
}
+ /**
+ * Decides whether the given node could be used as a predicate during the
simplification
+ * of other OR operands.
+ */
+ private boolean allowedAsPredicateDuringOrSimplification(final RexNode t) {
+ Predicate predicate = Predicate.of(t);
+ if (predicate == null) {
+ return false;
+ }
+ /** Inequalities are not supported. */
+ SqlKind kind = t.getKind();
+ if (!SqlKind.COMPARISON.contains(kind)) {
+ return true;
+ }
+ switch (kind) {
+ case LESS_THAN:
+ case GREATER_THAN:
+ case GREATER_THAN_OR_EQUAL:
+ case LESS_THAN_OR_EQUAL:
+ return false;
+ default:
+ return true;
+ }
+ }
+
private RexNode simplifyNot(RexCall call, RexUnknownAs unknownAs) {
final RexNode a = call.getOperands().get(0);
switch (a.getKind()) {
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 d79c133..e75c5e1 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -2704,6 +2704,18 @@ public class RexProgramTest extends
RexProgramBuilderBase {
assertThat(e.toString(), is("IN(?0.int0, 1, 2)"));
}
+ /** Unit test for
+ * <a
href="https://issues.apache.org/jira/browse/CALCITE-3192">[CALCITE-3192]
+ * Simplify OR incorrectly weaks condition</a>. */
+ @Test public void testOrSimplificationNotWeakensCondition() {
+ // "1 < a or (a < 3 and b = 2)" can't be simplified
+ checkSimplifyUnchanged(
+ or(
+ lt(literal(1), vIntNotNull()),
+ and(
+ lt(vIntNotNull(), literal(3)),
+ vBoolNotNull(2))));
+ }
}
// End RexProgramTest.java
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 79aa0ea..73e0ea6 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -4955,7 +4955,7 @@ LogicalProject(EXPR$0=[1])
LogicalProject(DEPTNO=[$7])
LogicalFilter(condition=[>($7, 10)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalFilter(condition=[>($7, 7)])
+ LogicalFilter(condition=[OR(>($7, 7), >($7, 10))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>
@@ -5275,7 +5275,7 @@ LogicalProject(EXPR$0=[1])
LogicalProject(DEPTNO=[$7])
LogicalFilter(condition=[>($7, 1)])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
- LogicalFilter(condition=[OR(>($7, 7), >($7, 1))])
+ LogicalFilter(condition=[OR(>($7, 7), >($7, 10), >($7, 1))])
LogicalTableScan(table=[[CATALOG, SALES, EMP]])
]]>
</Resource>