Repository: calcite Updated Branches: refs/heads/master d12549530 -> 86993bded
Following [CALCITE-2469] simplify "f(x, y) IS NULL" to "x IS NULL OR y IS NULL" if "f" is strong Previously we did not use OR, which was wrong. Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/86993bde Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/86993bde Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/86993bde Branch: refs/heads/master Commit: 86993bdedea758916deefcabbfd38eaa1c14eca7 Parents: d125495 Author: Julian Hyde <jh...@apache.org> Authored: Fri Aug 31 11:33:07 2018 -0700 Committer: Julian Hyde <jh...@apache.org> Committed: Mon Sep 3 19:22:17 2018 -0700 ---------------------------------------------------------------------- .../java/org/apache/calcite/rex/RexSimplify.java | 12 +++++------- .../org/apache/calcite/test/RexProgramTest.java | 16 ++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/86993bde/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 f69ca9a..892b7ab 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -501,8 +501,8 @@ public class RexSimplify { case NOT_NULL: return rexBuilder.makeLiteral(true); case ANY: - // "f" is a strong operator, so "f(operand) IS NOT NULL" simplifies to - // "operand IS NOT NULL" + // "f" is a strong operator, so "f(operand0, operand1) IS NOT NULL" + // simplifies to "operand0 IS NOT NULL AND operand1 IS NOT NULL" final List<RexNode> operands = new ArrayList<>(); for (RexNode operand : ((RexCall) a).getOperands()) { final RexNode simplified = simplifyIsNotNull(operand); @@ -538,21 +538,19 @@ public class RexSimplify { case NOT_NULL: return rexBuilder.makeLiteral(false); case ANY: - // "f" is a strong operator, so "f(operand) IS NULL" simplifies to - // "operand IS NULL" + // "f" is a strong operator, so "f(operand0, operand1) IS NULL" simplifies + // to "operand0 IS NULL OR operand1 IS NULL" final List<RexNode> operands = new ArrayList<>(); for (RexNode operand : ((RexCall) a).getOperands()) { final RexNode simplified = simplifyIsNull(operand); if (simplified == null) { operands.add( rexBuilder.makeCall(SqlStdOperatorTable.IS_NULL, operand)); - } else if (simplified.isAlwaysFalse()) { - return rexBuilder.makeLiteral(false); } else { operands.add(simplified); } } - return RexUtil.composeConjunction(rexBuilder, operands, false); + return RexUtil.composeDisjunction(rexBuilder, operands, false); case AS_IS: default: return null; http://git-wip-us.apache.org/repos/asf/calcite/blob/86993bde/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 92ad323..aa6c808 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java @@ -1199,6 +1199,22 @@ public class RexProgramTest extends RexProgramBuilderBase { // "(not x) is not null" to "x is not null" checkSimplify(isNotNull(not(vBool())), "IS NOT NULL(?0.bool0)"); checkSimplify(isNotNull(not(vBoolNotNull())), "true"); + + // "(x + y) is null" simplifies to "x is null or y is null" + checkSimplify(isNull(plus(vInt(0), vInt(1))), + "OR(IS NULL(?0.int0), IS NULL(?0.int1))"); + checkSimplify(isNull(plus(vInt(0), vIntNotNull(1))), "IS NULL(?0.int0)"); + checkSimplify(isNull(plus(vIntNotNull(0), vIntNotNull(1))), "false"); + checkSimplify(isNull(plus(vIntNotNull(0), vInt(1))), "IS NULL(?0.int1)"); + + // "(x + y) is not null" simplifies to "x is not null and y is not null" + checkSimplify(isNotNull(plus(vInt(0), vInt(1))), + "AND(IS NOT NULL(?0.int0), IS NOT NULL(?0.int1))"); + checkSimplify(isNotNull(plus(vInt(0), vIntNotNull(1))), + "IS NOT NULL(?0.int0)"); + checkSimplify(isNotNull(plus(vIntNotNull(0), vIntNotNull(1))), "true"); + checkSimplify(isNotNull(plus(vIntNotNull(0), vInt(1))), + "IS NOT NULL(?0.int1)"); } @Test public void testSimplifyFilter() {