Repository: calcite Updated Branches: refs/heads/master 2ab83e468 -> b40562bf6
[CALCITE-2556] Simplify not(true/false) to false/true (pengzhiwei) closes #853 Project: http://git-wip-us.apache.org/repos/asf/calcite/repo Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/b40562bf Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/b40562bf Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/b40562bf Branch: refs/heads/master Commit: b40562bf6ae9fc36606907d4f4c9e7217bacc9b6 Parents: 2ab83e4 Author: pengzhiwei <[email protected]> Authored: Sat Sep 22 12:07:03 2018 +0800 Committer: Vladimir Sitnikov <[email protected]> Committed: Sat Sep 22 16:54:06 2018 +0300 ---------------------------------------------------------------------- .../org/apache/calcite/rex/RexSimplify.java | 5 +++ .../org/apache/calcite/test/RexProgramTest.java | 35 ++++++++++++++++---- 2 files changed, 34 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/calcite/blob/b40562bf/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 33bdbeb..1e70a53 100644 --- a/core/src/main/java/org/apache/calcite/rex/RexSimplify.java +++ b/core/src/main/java/org/apache/calcite/rex/RexSimplify.java @@ -377,6 +377,11 @@ public class RexSimplify { case NOT: // NOT NOT x ==> x return simplify_(((RexCall) a).getOperands().get(0)); + case LITERAL: + if (a.getType().getSqlTypeName() == SqlTypeName.BOOLEAN + && !RexLiteral.isNullLiteral(a)) { + return rexBuilder.makeLiteral(!RexLiteral.booleanValue(a)); + } } final SqlKind negateKind = a.getKind().negate(); if (a.getKind() != negateKind) { http://git-wip-us.apache.org/repos/asf/calcite/blob/b40562bf/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 d7ca9dc..268b479 100644 --- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java +++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java @@ -2162,29 +2162,52 @@ public class RexProgramTest extends RexProgramBuilderBase { return map2.toString(); } - @Test public void testSimplifyNot() { + @Test public void testSimplifyFalse() { final RelDataType booleanNullableType = typeFactory.createTypeWithNullability( typeFactory.createSqlType(SqlTypeName.BOOLEAN), true); - final RexNode booleanInput = rexBuilder.makeInputRef(booleanNullableType, 0); - final RexNode isFalse = rexBuilder.makeCall(SqlStdOperatorTable.IS_FALSE, booleanInput); + final RexNode booleanInput = input(booleanNullableType, 0); + final RexNode isFalse = isFalse(booleanInput); final RexCall result = (RexCall) simplify(isFalse); assertThat(result.getType().isNullable(), is(false)); - assertThat(result.getOperator(), is((SqlOperator) SqlStdOperatorTable.IS_FALSE)); + assertThat(result.getOperator(), is(SqlStdOperatorTable.IS_FALSE)); assertThat(result.getOperands().size(), is(1)); assertThat(result.getOperands().get(0), is(booleanInput)); // Make sure that IS_FALSE(IS_FALSE(nullable boolean)) != IS_TRUE(nullable boolean) // IS_FALSE(IS_FALSE(null)) = IS_FALSE(false) = true // IS_TRUE(null) = false - final RexNode isFalseIsFalse = rexBuilder.makeCall(SqlStdOperatorTable.IS_FALSE, isFalse); + final RexNode isFalseIsFalse = isFalse(isFalse); final RexCall result2 = (RexCall) simplify(isFalseIsFalse); assertThat(result2.getType().isNullable(), is(false)); - assertThat(result2.getOperator(), is((SqlOperator) SqlStdOperatorTable.IS_NOT_FALSE)); + assertThat(result2.getOperator(), is(SqlStdOperatorTable.IS_NOT_FALSE)); assertThat(result2.getOperands().size(), is(1)); assertThat(result2.getOperands().get(0), is(booleanInput)); } + @Test public void testSimplifyNot() { + // "NOT(NOT(x))" => "x" + checkSimplify(not(not(vBool())), "?0.bool0"); + // "NOT(true)" => "false" + checkSimplify(not(trueLiteral), "false"); + // "NOT(false)" => "true" + checkSimplify(not(falseLiteral), "true"); + // "NOT(IS FALSE(x))" => "IS NOT FALSE(x)" + checkSimplify(not(isFalse(vBool())), "IS NOT FALSE(?0.bool0)"); + // "NOT(IS TRUE(x))" => "IS NOT TRUE(x)" + checkSimplify(not(isTrue(vBool())), "IS NOT TRUE(?0.bool0)"); + // "NOT(IS NULL(x))" => "IS NOT NULL(x)" + checkSimplify(not(isNull(vBool())), "IS NOT NULL(?0.bool0)"); + // "NOT(IS NOT NULL(x)) => "IS NULL(x)" + checkSimplify(not(isNotNull(vBool())), "IS NULL(?0.bool0)"); + // "NOT(AND(x0,x1))" => "OR(NOT(x0),NOT(x1))" + checkSimplify(not(and(vBool(0), vBool(1))), + "OR(NOT(?0.bool0), NOT(?0.bool1))"); + // "NOT(OR(x0,x1))" => "AND(NOT(x0),NOT(x1))" + checkSimplify(not(or(vBool(0), vBool(1))), + "AND(NOT(?0.bool0), NOT(?0.bool1))"); + } + private RexNode simplify(RexNode e) { final RexSimplify simplify = new RexSimplify(rexBuilder, RelOptPredicateList.EMPTY, false,
