You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by vl...@apache.org on 2018/08/28 09:33:55 UTC
calcite git commit: [CALCITE-2327] Avoid simplification of x AND
NOT(x) to false for nullable x
Repository: calcite
Updated Branches:
refs/heads/master af3e35d64 -> 141781bf4
[CALCITE-2327] Avoid simplification of x AND NOT(x) to false for nullable x
x AND NOT(x) ==> FALSE AND x IS NULL
closes #707
Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/141781bf
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/141781bf
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/141781bf
Branch: refs/heads/master
Commit: 141781bf4d591d973812c73ea9f03d715b5406cb
Parents: af3e35d
Author: Vladimir Sitnikov <si...@gmail.com>
Authored: Tue Aug 28 10:36:40 2018 +0300
Committer: Vladimir Sitnikov <si...@gmail.com>
Committed: Tue Aug 28 11:42:40 2018 +0300
----------------------------------------------------------------------
.../org/apache/calcite/rex/RexSimplify.java | 22 +++++++++++++++++++-
.../org/apache/calcite/test/RexProgramTest.java | 4 +---
2 files changed, 22 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/calcite/blob/141781bf/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
----------------------------------------------------------------------
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 7aaf141..1274391 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java
@@ -718,11 +718,31 @@ public class RexSimplify {
// Example #1. x AND y AND z AND NOT (x AND y) - not satisfiable
// Example #2. x AND y AND NOT (x AND y) - not satisfiable
// Example #3. x AND y AND NOT (x AND y AND z) - may be satisfiable
+ RexNode bestNotDisjunction = null;
for (RexNode notDisjunction : notTerms) {
final List<RexNode> terms2 = RelOptUtil.conjunctions(notDisjunction);
- if (terms.containsAll(terms2)) {
+ if (!terms.containsAll(terms2)) {
+ // may be satisfiable ==> check other terms
+ continue;
+ }
+ if (!notDisjunction.getType().isNullable()) {
+ // x is NOT nullable, then x AND NOT(x) ==> FALSE
return rexBuilder.makeLiteral(false);
}
+ // x AND NOT(x) is UNKNOWN for NULL input
+ // So we search for the shortest notDisjunction then convert
+ // original expression to NULL and x IS NULL
+ if (bestNotDisjunction == null
+ || bestNotDisjunction.toString().length() > notDisjunction.toString().length()) {
+ bestNotDisjunction = notDisjunction;
+ }
+ }
+ if (bestNotDisjunction != null) {
+ // NULL AND (x IS NULL)
+ return rexBuilder.makeCall(SqlStdOperatorTable.AND,
+ rexBuilder.makeNullLiteral(bestNotDisjunction.getType()),
+ simplifyIs(
+ (RexCall) rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, bestNotDisjunction)));
}
// Add the NOT disjunctions back in.
for (RexNode notDisjunction : notTerms) {
http://git-wip-us.apache.org/repos/asf/calcite/blob/141781bf/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
----------------------------------------------------------------------
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 9a8c27d..990afb6 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -56,7 +56,6 @@ import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Multimap;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import java.math.BigDecimal;
@@ -1543,7 +1542,6 @@ public class RexProgramTest extends RexProgramBuilderBase {
"false");
}
- @Ignore
@Test public void testSimplifyAnd3() {
final RelDataType boolType = typeFactory.createSqlType(SqlTypeName.BOOLEAN);
final RelDataType rowType = typeFactory.builder()
@@ -1557,7 +1555,7 @@ public class RexProgramTest extends RexProgramBuilderBase {
checkSimplify2(
and(aRef,
not(aRef)),
- "a is null and null",
+ "AND(null, IS NULL(?0.a))",
"false");
}