calcite-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jh...@apache.org
Subject [4/6] calcite git commit: [CALCITE-1638] Simplify "$x = $x" to "$x is not null"
Date Thu, 23 Feb 2017 16:50:53 GMT
[CALCITE-1638] Simplify "$x = $x" to "$x is not null"


Project: http://git-wip-us.apache.org/repos/asf/calcite/repo
Commit: http://git-wip-us.apache.org/repos/asf/calcite/commit/34997ad1
Tree: http://git-wip-us.apache.org/repos/asf/calcite/tree/34997ad1
Diff: http://git-wip-us.apache.org/repos/asf/calcite/diff/34997ad1

Branch: refs/heads/master
Commit: 34997ad1bb0b4ff0d4ed738859127872029ebf0e
Parents: 24c25fc
Author: Julian Hyde <jhyde@apache.org>
Authored: Wed Feb 22 21:26:26 2017 -0800
Committer: Julian Hyde <jhyde@apache.org>
Committed: Wed Feb 22 22:17:28 2017 -0800

----------------------------------------------------------------------
 .../java/org/apache/calcite/rex/RexCall.java    |  9 ++--
 .../java/org/apache/calcite/rex/RexUtil.java    | 18 ++++++++
 .../org/apache/calcite/test/RexProgramTest.java | 45 ++++++++++++++++++++
 .../org/apache/calcite/test/RelOptRulesTest.xml | 12 +++---
 core/src/test/resources/sql/misc.iq             | 14 ++++++
 core/src/test/resources/sql/sub-query.iq        |  6 +--
 6 files changed, 89 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/core/src/main/java/org/apache/calcite/rex/RexCall.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexCall.java b/core/src/main/java/org/apache/calcite/rex/RexCall.java
index 6ae235b..5a1f112 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexCall.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexCall.java
@@ -22,6 +22,7 @@ import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.util.Litmus;
 
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 
 import java.util.List;
@@ -55,14 +56,10 @@ public class RexCall extends RexNode {
       RelDataType type,
       SqlOperator op,
       List<? extends RexNode> operands) {
-    assert type != null : "precondition: type != null";
-    assert op != null : "precondition: op != null";
-    assert operands != null : "precondition: operands != null";
-    this.type = type;
-    this.op = op;
+    this.type = Preconditions.checkNotNull(type);
+    this.op = Preconditions.checkNotNull(op);
     this.operands = ImmutableList.copyOf(operands);
     assert op.getKind() != null : op;
-
     assert op.validRexOperands(operands.size(), Litmus.THROW) : this;
   }
 

http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/core/src/main/java/org/apache/calcite/rex/RexUtil.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/calcite/rex/RexUtil.java b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
index 4f7492d..fa19883 100644
--- a/core/src/main/java/org/apache/calcite/rex/RexUtil.java
+++ b/core/src/main/java/org/apache/calcite/rex/RexUtil.java
@@ -1615,6 +1615,24 @@ public class RexUtil {
     case LESS_THAN:
     case LESS_THAN_OR_EQUAL:
     case NOT_EQUALS:
+      final List<RexNode> operands = ((RexCall) e).getOperands();
+      if (RexUtil.eq(operands.get(0), operands.get(1))
+          && (unknownAsFalse
+          || (!operands.get(0).getType().isNullable()
+              && !operands.get(1).getType().isNullable()))) {
+        switch (e.getKind()) {
+        case EQUALS:
+        case GREATER_THAN_OR_EQUAL:
+        case LESS_THAN_OR_EQUAL:
+          // "x = x" simplifies to "x is not null" (similarly <= and >=)
+          return simplify(rexBuilder,
+              rexBuilder.makeCall(SqlStdOperatorTable.IS_NOT_NULL,
+                  operands.get(0)));
+        default:
+          // "x != x" simplifies to "false" (similarly < and >)
+          return rexBuilder.makeLiteral(false);
+        }
+      }
       return simplifyCall(rexBuilder, (RexCall) e);
     default:
       return e;

http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/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 7efa890..d021a5b 100644
--- a/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
+++ b/core/src/test/java/org/apache/calcite/test/RexProgramTest.java
@@ -195,6 +195,10 @@ public class RexProgramTest {
     return rexBuilder.makeCall(SqlStdOperatorTable.EQUALS, n1, n2);
   }
 
+  private RexNode ne(RexNode n1, RexNode n2) {
+    return rexBuilder.makeCall(SqlStdOperatorTable.NOT_EQUALS, n1, n2);
+  }
+
   private RexNode le(RexNode n1, RexNode n2) {
     return rexBuilder.makeCall(SqlStdOperatorTable.LESS_THAN_OR_EQUAL, n1, n2);
   }
@@ -850,6 +854,8 @@ public class RexProgramTest {
     final RelDataType booleanType =
         typeFactory.createSqlType(SqlTypeName.BOOLEAN);
     final RelDataType intType = typeFactory.createSqlType(SqlTypeName.INTEGER);
+    final RelDataType intNullableType =
+        typeFactory.createTypeWithNullability(intType, true);
     final RelDataType rowType = typeFactory.builder()
         .add("a", booleanType)
         .add("b", booleanType)
@@ -859,6 +865,7 @@ public class RexProgramTest {
         .add("f", booleanType)
         .add("g", booleanType)
         .add("h", intType)
+        .add("i", intNullableType)
         .build();
 
     final RexDynamicParam range = rexBuilder.makeDynamicParam(rowType, 0);
@@ -867,6 +874,8 @@ public class RexProgramTest {
     final RexNode cRef = rexBuilder.makeFieldAccess(range, 2);
     final RexNode dRef = rexBuilder.makeFieldAccess(range, 3);
     final RexNode eRef = rexBuilder.makeFieldAccess(range, 4);
+    final RexNode hRef = rexBuilder.makeFieldAccess(range, 7);
+    final RexNode iRef = rexBuilder.makeFieldAccess(range, 8);
     final RexLiteral literal1 = rexBuilder.makeExactLiteral(BigDecimal.ONE);
 
     // and: remove duplicates
@@ -985,6 +994,42 @@ public class RexProgramTest {
         or(lt(aRef, literal1),
             and(trueLiteral, or(falseLiteral, falseLiteral))),
         "<(?0.a, 1)");
+
+    // "x = x" simplifies to "x is not null"
+    checkSimplify(eq(literal1, literal1), "true");
+    checkSimplify(eq(hRef, hRef), "true");
+    checkSimplify2(eq(iRef, iRef), "=(?0.i, ?0.i)", "IS NOT NULL(?0.i)");
+    checkSimplify(eq(iRef, hRef), "=(?0.i, ?0.h)");
+
+    // "x <= x" simplifies to "x is not null"
+    checkSimplify(le(literal1, literal1), "true");
+    checkSimplify(le(hRef, hRef), "true");
+    checkSimplify2(le(iRef, iRef), "<=(?0.i, ?0.i)", "IS NOT NULL(?0.i)");
+    checkSimplify(le(iRef, hRef), "<=(?0.i, ?0.h)");
+
+    // "x >= x" simplifies to "x is not null"
+    checkSimplify(ge(literal1, literal1), "true");
+    checkSimplify(ge(hRef, hRef), "true");
+    checkSimplify2(ge(iRef, iRef), ">=(?0.i, ?0.i)", "IS NOT NULL(?0.i)");
+    checkSimplify(ge(iRef, hRef), ">=(?0.i, ?0.h)");
+
+    // "x != x" simplifies to "false"
+    checkSimplify(ne(literal1, literal1), "false");
+    checkSimplify(ne(hRef, hRef), "false");
+    checkSimplify2(ne(iRef, iRef), "<>(?0.i, ?0.i)", "false");
+    checkSimplify(ne(iRef, hRef), "<>(?0.i, ?0.h)");
+
+    // "x < x" simplifies to "false"
+    checkSimplify(lt(literal1, literal1), "false");
+    checkSimplify(lt(hRef, hRef), "false");
+    checkSimplify2(lt(iRef, iRef), "<(?0.i, ?0.i)", "false");
+    checkSimplify(lt(iRef, hRef), "<(?0.i, ?0.h)");
+
+    // "x > x" simplifies to "false"
+    checkSimplify(gt(literal1, literal1), "false");
+    checkSimplify(gt(hRef, hRef), "false");
+    checkSimplify2(gt(iRef, iRef), ">(?0.i, ?0.i)", "false");
+    checkSimplify(gt(iRef, hRef), ">(?0.i, ?0.h)");
   }
 
   @Test public void testSimplifyFilter() {

http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
----------------------------------------------------------------------
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 713a92c..6c03478 100644
--- a/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
+++ b/core/src/test/resources/org/apache/calcite/test/RelOptRulesTest.xml
@@ -3913,8 +3913,7 @@ ProjectRel(EXPR$0=[1])
             <![CDATA[
 LogicalProject(EXPR$0=[1])
   LogicalJoin(condition=[=($7, $16)], joinType=[inner])
-    LogicalFilter(condition=[=(1, 1)])
-      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalTableScan(table=[[CATALOG, SALES, EMP]])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
         </Resource>
@@ -3922,8 +3921,7 @@ LogicalProject(EXPR$0=[1])
             <![CDATA[
 LogicalProject(EXPR$0=[1])
   LogicalJoin(condition=[=($7, $16)], joinType=[inner])
-    LogicalFilter(condition=[=(1, 1)])
-      LogicalTableScan(table=[[CATALOG, SALES, EMP]])
+    LogicalTableScan(table=[[CATALOG, SALES, EMP]])
     LogicalTableScan(table=[[CATALOG, SALES, EMP]])
 ]]>
         </Resource>
@@ -4187,7 +4185,7 @@ LogicalProject(DEPTNO=[$0])
     <TestCase name="testCastInAggregateReduceFunctions">
         <Resource name="sql">
             <![CDATA[select name, stddev_pop(deptno), avg(deptno), stddev_samp(deptno),var_pop(deptno),
var_samp(deptno)
-            from sales.dept group by name]]>
+from sales.dept group by name]]>
         </Resource>
         <Resource name="planBefore">
             <![CDATA[
@@ -6693,7 +6691,9 @@ LogicalAggregate(group=[{0}], EXPR$1=[SUM($2)], EXPR$2=[AVG($1)])
     <TestCase name="testCastInAggregateExpandDistinctAggregatesRule">
         <Resource name="sql">
             <![CDATA[select name, sum(distinct cn), sum(distinct sm)
-from (select name, count(dept.deptno) as cn,sum(dept.deptno) as sm from sales.dept group
by name)
+from (
+  select name, count(dept.deptno) as cn,sum(dept.deptno) as sm
+  from sales.dept group by name)
 group by name]]>
         </Resource>
         <Resource name="planBefore">

http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/core/src/test/resources/sql/misc.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/misc.iq b/core/src/test/resources/sql/misc.iq
index 39a32d5..cbeb56a 100644
--- a/core/src/test/resources/sql/misc.iq
+++ b/core/src/test/resources/sql/misc.iq
@@ -1826,4 +1826,18 @@ select count(*) as c from "scott".emp where not (ename in ('Fred'));
 
 !ok
 
+# [CALCITE-1638] Simplify "$x = $x" to "$x is not null"
+select count(*) as c from "scott".emp where deptno > deptno;
++---+
+| C |
++---+
+| 0 |
++---+
+(1 row)
+
+!ok
+EnumerableAggregate(group=[{}], C=[COUNT()])
+  EnumerableValues(tuples=[[]])
+!plan
+
 # End misc.iq

http://git-wip-us.apache.org/repos/asf/calcite/blob/34997ad1/core/src/test/resources/sql/sub-query.iq
----------------------------------------------------------------------
diff --git a/core/src/test/resources/sql/sub-query.iq b/core/src/test/resources/sql/sub-query.iq
index 26329ec..ff1b824 100644
--- a/core/src/test/resources/sql/sub-query.iq
+++ b/core/src/test/resources/sql/sub-query.iq
@@ -40,20 +40,20 @@ EnumerableCalc(expr#0..4=[{inputs}], expr#5=[0], expr#6=[=($t1, $t5)],
expr#7=[f
           EnumerableValues(tuples=[[{ 0 }]])
         EnumerableCalc(expr#0=[{inputs}], expr#1=[2], EXPR$0=[$t1])
           EnumerableValues(tuples=[[{ 0 }]])
-        EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null],
expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+        EnumerableCalc(expr#0=[{inputs}], expr#1=[true], expr#2=[null], expr#3=[3], expr#4=[CASE($t1,
$t2, $t3)], EXPR$0=[$t4])
           EnumerableValues(tuples=[[{ 0 }]])
       EnumerableAggregate(group=[{}], c=[COUNT()], ck=[COUNT($0)])
         EnumerableUnion(all=[true])
           EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
             EnumerableValues(tuples=[[{ 0 }]])
-          EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null],
expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+          EnumerableCalc(expr#0=[{inputs}], expr#1=[true], expr#2=[null], expr#3=[3], expr#4=[CASE($t1,
$t2, $t3)], EXPR$0=[$t4])
             EnumerableValues(tuples=[[{ 0 }]])
     EnumerableAggregate(group=[{0, 1}])
       EnumerableCalc(expr#0=[{inputs}], expr#1=[true], proj#0..1=[{exprs}])
         EnumerableUnion(all=[true])
           EnumerableCalc(expr#0=[{inputs}], expr#1=[1], EXPR$0=[$t1])
             EnumerableValues(tuples=[[{ 0 }]])
-          EnumerableCalc(expr#0=[{inputs}], expr#1=[1], expr#2=[=($t1, $t1)], expr#3=[null],
expr#4=[3], expr#5=[CASE($t2, $t3, $t4)], EXPR$0=[$t5])
+          EnumerableCalc(expr#0=[{inputs}], expr#1=[true], expr#2=[null], expr#3=[3], expr#4=[CASE($t1,
$t2, $t3)], EXPR$0=[$t4])
             EnumerableValues(tuples=[[{ 0 }]])
 !plan
 


Mime
View raw message