You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by li...@apache.org on 2022/03/04 13:24:31 UTC
[calcite] 27/41: [CALCITE-4988] ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL) When A is deterministic
This is an automated email from the ASF dual-hosted git repository.
liyafan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/calcite.git
commit 4c73e859c352fa02c59eb810a2073420ab47d144
Author: NobiGo <no...@gmail.com>
AuthorDate: Fri Jan 21 19:05:22 2022 +0800
[CALCITE-4988] ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL) When A is deterministic
---
.../java/org/apache/calcite/rex/RexSimplify.java | 4 +-
.../org/apache/calcite/rex/RexProgramTest.java | 76 ++++++++++++++++++++++
2 files changed, 78 insertions(+), 2 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 96338ab..7c0aa6b 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -865,7 +865,7 @@ public class RexSimplify {
}
private @Nullable RexNode simplifyIsPredicate(SqlKind kind, RexNode a) {
- if (!RexUtil.isReferenceOrAccess(a, true)) {
+ if (!(RexUtil.isReferenceOrAccess(a, true) || RexUtil.isDeterministic(a))) {
return null;
}
@@ -2664,7 +2664,7 @@ public class RexSimplify {
case IS_NULL:
case IS_NOT_NULL:
RexNode pA = ((RexCall) e).getOperands().get(0);
- if (!RexUtil.isReferenceOrAccess(pA, true)) {
+ if (!(RexUtil.isReferenceOrAccess(pA, true) || RexUtil.isDeterministic(pA))) {
return null;
}
return new IsPredicate(pA, e.getKind());
diff --git a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
index 9edb64a..691c954 100644
--- a/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/rex/RexProgramTest.java
@@ -2157,6 +2157,82 @@ class RexProgramTest extends RexProgramTestBase {
checkSimplify(isNotNull(cast(i2, intType)), "true");
}
+ /**
+ * Unit test for
+ * <a href="https://issues.apache.org/jira/browse/CALCITE-4988">[CALCITE-4988]
+ * ((A IS NOT NULL OR B) AND A IS NOT NULL) can't be simplify to (A IS NOT NULL)
+ * When A is deterministic</a>. */
+ @Test void testSimplifyIsNotNullWithDeterministic() {
+ // "(A IS NOT NULL OR B) AND A IS NOT NULL" when A is deterministic
+ // ==>
+ // "A IS NOT NULL"
+ SqlOperator dc = getDeterministicOperator();
+ checkSimplify2(
+ and(or(isNotNull(rexBuilder.makeCall(dc)), gt(vInt(2), literal(2))),
+ isNotNull(rexBuilder.makeCall(dc))),
+ "AND(OR(IS NOT NULL(DC()), >(?0.int2, 2)), IS NOT NULL(DC()))",
+ "IS NOT NULL(DC())");
+ }
+
+ @Test void testSimplifyIsNotNullWithDeterministic2() {
+ // "(A IS NOT NULL AND B) OR A IS NULL" when A is deterministic
+ // ==>
+ // "A IS NULL OR B"
+ SqlOperator dc = getDeterministicOperator();
+ checkSimplify(
+ or(and(isNotNull(rexBuilder.makeCall(dc)), gt(vInt(2), literal(2))),
+ isNull(rexBuilder.makeCall(dc))),
+ "OR(IS NULL(DC()), >(?0.int2, 2))");
+ }
+
+ @Test void testSimplifyIsNotNullWithNoDeterministic() {
+ // "(A IS NOT NULL OR B) AND A IS NOT NULL" when A is not deterministic
+ // ==>
+ // "(A IS NOT NULL OR B) AND A IS NOT NULL"
+ SqlOperator ndc = getNoDeterministicOperator();
+ checkSimplifyUnchanged(
+ and(or(isNotNull(rexBuilder.makeCall(ndc)), gt(vInt(2), literal(2))),
+ isNotNull(rexBuilder.makeCall(ndc))));
+ }
+
+ @Test void testSimplifyIsNotNullWithNoDeterministic2() {
+ // "(A IS NOT NULL AND B) OR A IS NOT NULL" when A is not deterministic
+ // ==>
+ // "(A IS NOT NULL AND B) OR A IS NOT NULL"
+ SqlOperator ndc = getNoDeterministicOperator();
+ checkSimplifyUnchanged(
+ and(or(isNotNull(rexBuilder.makeCall(ndc)), gt(vInt(2), literal(2))),
+ isNotNull(rexBuilder.makeCall(ndc))));
+ }
+
+ private SqlOperator getDeterministicOperator() {
+ return new SqlSpecialOperator(
+ "DC",
+ SqlKind.OTHER_FUNCTION,
+ 0,
+ false,
+ ReturnTypes.BOOLEAN_FORCE_NULLABLE,
+ null, null) {
+ @Override public boolean isDeterministic() {
+ return true;
+ }
+ };
+ }
+
+ private SqlOperator getNoDeterministicOperator() {
+ return new SqlSpecialOperator(
+ "NDC",
+ SqlKind.OTHER_FUNCTION,
+ 0,
+ false,
+ ReturnTypes.BOOLEAN_FORCE_NULLABLE,
+ null, null) {
+ @Override public boolean isDeterministic() {
+ return false;
+ }
+ };
+ }
+
/** Unit test for
* <a href="https://issues.apache.org/jira/browse/CALCITE-2929">[CALCITE-2929]
* Simplification of IS NULL checks are incorrectly assuming that CAST-s are possible</a>. */