You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@storm.apache.org by sr...@apache.org on 2015/11/10 19:39:52 UTC

[3/3] storm git commit: STORM-1159. Support nullable operations in StormSQL.

STORM-1159. Support nullable operations in StormSQL.


Project: http://git-wip-us.apache.org/repos/asf/storm/repo
Commit: http://git-wip-us.apache.org/repos/asf/storm/commit/1d0155aa
Tree: http://git-wip-us.apache.org/repos/asf/storm/tree/1d0155aa
Diff: http://git-wip-us.apache.org/repos/asf/storm/diff/1d0155aa

Branch: refs/heads/STORM-1040
Commit: 1d0155aa8b9d9cb2a0ccb364252c22a30b28c66f
Parents: 8890de3
Author: Haohui Mai <wh...@apache.org>
Authored: Wed Nov 4 18:36:59 2015 -0800
Committer: Haohui Mai <wh...@apache.org>
Committed: Thu Nov 5 09:00:34 2015 -0800

----------------------------------------------------------------------
 .../apache/storm/sql/compiler/ExprCompiler.java | 54 ++++++++++++++------
 .../storm/sql/compiler/TestExprCompiler.java    | 10 ++--
 .../storm/sql/compiler/TestExprSemantic.java    |  9 ++++
 .../storm/sql/compiler/TestRelNodeCompiler.java |  7 ++-
 4 files changed, 59 insertions(+), 21 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/storm/blob/1d0155aa/external/sql/storm-sql-core/src/jvm/org/apache/storm/sql/compiler/ExprCompiler.java
----------------------------------------------------------------------
diff --git a/external/sql/storm-sql-core/src/jvm/org/apache/storm/sql/compiler/ExprCompiler.java b/external/sql/storm-sql-core/src/jvm/org/apache/storm/sql/compiler/ExprCompiler.java
index db97d43..6617ef6 100644
--- a/external/sql/storm-sql-core/src/jvm/org/apache/storm/sql/compiler/ExprCompiler.java
+++ b/external/sql/storm-sql-core/src/jvm/org/apache/storm/sql/compiler/ExprCompiler.java
@@ -17,10 +17,7 @@
  */
 package org.apache.storm.sql.compiler;
 
-import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableMap;
-import org.apache.calcite.adapter.enumerable.CallImplementor;
-import org.apache.calcite.adapter.enumerable.RexImpTable;
 import org.apache.calcite.adapter.java.JavaTypeFactory;
 import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.rex.RexCall;
@@ -42,7 +39,6 @@ import java.io.PrintWriter;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
 import java.util.AbstractMap;
-import java.util.IdentityHashMap;
 import java.util.Map;
 
 import static org.apache.calcite.sql.fun.SqlStdOperatorTable.AND;
@@ -80,7 +76,7 @@ class ExprCompiler implements RexVisitor<String> {
 
   @Override
   public String visitInputRef(RexInputRef rexInputRef) {
-    String name = reserveName(rexInputRef);
+    String name = reserveName();
     String typeName = javaTypeName(rexInputRef);
     pw.print(String.format("%s %s = (%s)(_data.get(%d));\n", typeName, name,
                            typeName, rexInputRef.getIndex()));
@@ -164,9 +160,8 @@ class ExprCompiler implements RexVisitor<String> {
     return ((Class<?>)ty).getCanonicalName();
   }
 
-  private String reserveName(RexNode node) {
-    String name = "t" + ++nameCount;
-    return name;
+  private String reserveName() {
+    return "t" + ++nameCount;
   }
 
   private interface CallExprPrinter {
@@ -223,11 +218,38 @@ class ExprCompiler implements RexVisitor<String> {
             ExprCompiler compiler, RexCall call) {
           int size = call.getOperands().size();
           assert size == 2;
-          String[] ops = new String[size];
-          for (int i = 0; i < size; ++i) {
-            ops[i] = call.getOperands().get(i).accept(compiler);
+          String val = compiler.reserveName();
+          RexNode op0 = call.getOperands().get(0);
+          RexNode op1 = call.getOperands().get(1);
+          boolean lhsNullable = op0.getType().isNullable();
+          boolean rhsNullable = op1.getType().isNullable();
+
+          PrintWriter pw = compiler.pw;
+          String lhs = op0.accept(compiler);
+          pw.print(String.format("final %s %s;\n", compiler.javaTypeName(call), val));
+          if (!lhsNullable) {
+            String rhs = op1.accept(compiler);
+            String calc = foldNullExpr(String.format("%s %s %s", lhs, javaOperator, rhs), "null", rhs);
+            if (!rhsNullable) {
+              pw.print(String.format("%s = %s;\n", val, calc));
+            } else {
+              pw.print(
+                  String.format("%s = %s == null ? null : (%s);\n",
+                      val, rhs, calc));
+            }
+          } else {
+            pw.print(String.format("if (%2$s == null) { %1$s = null; }\n",
+                val, lhs));
+            pw.print("else {\n");
+            String rhs = op1.accept(compiler);
+            String calc = foldNullExpr(String.format("%s %s %s", lhs, javaOperator, rhs), "null", lhs);
+            if (!rhsNullable) {
+              pw.print(String.format("%s = %s;\n}\n", val, calc));
+            } else {
+              pw.print(String.format("%1$s = %2$s == null ? null : (%3$s);\n}\n", val, rhs, calc));
+            }
           }
-          return String.format("%s %s %s", ops[0], javaOperator, ops[1]);
+          return val;
         }
       };
       return new AbstractMap.SimpleImmutableEntry<>(op, trans);
@@ -250,7 +272,7 @@ class ExprCompiler implements RexVisitor<String> {
         public String translate(
             ExprCompiler compiler, RexCall call) {
           assert call.getOperands().size() == 1;
-          String val = compiler.reserveName(call);
+          String val = compiler.reserveName();
           RexNode operand = call.getOperands().get(0);
           boolean nullable = operand.getType().isNullable();
           String op = operand.accept(compiler);
@@ -289,7 +311,7 @@ class ExprCompiler implements RexVisitor<String> {
       @Override
       public String translate(
           ExprCompiler compiler, RexCall call) {
-        String val = compiler.reserveName(call);
+        String val = compiler.reserveName();
         PrintWriter pw = compiler.pw;
         pw.print(String.format("final %s %s;\n", compiler.javaTypeName(call),
                                val));
@@ -331,7 +353,7 @@ class ExprCompiler implements RexVisitor<String> {
       @Override
       public String translate(
           ExprCompiler compiler, RexCall call) {
-        String val = compiler.reserveName(call);
+        String val = compiler.reserveName();
         PrintWriter pw = compiler.pw;
         pw.print(String.format("final %s %s;\n", compiler.javaTypeName(call),
                                val));
@@ -369,7 +391,7 @@ class ExprCompiler implements RexVisitor<String> {
       @Override
       public String translate(
           ExprCompiler compiler, RexCall call) {
-        String val = compiler.reserveName(call);
+        String val = compiler.reserveName();
         PrintWriter pw = compiler.pw;
         RexNode op = call.getOperands().get(0);
         String lhs = op.accept(compiler);

http://git-wip-us.apache.org/repos/asf/storm/blob/1d0155aa/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprCompiler.java
----------------------------------------------------------------------
diff --git a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprCompiler.java b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprCompiler.java
index 9f516d4..f03cff8 100644
--- a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprCompiler.java
+++ b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprCompiler.java
@@ -28,8 +28,10 @@ import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.List;
 
+import static org.hamcrest.CoreMatchers.containsString;
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
 
 public class TestExprCompiler {
   @Test
@@ -62,7 +64,7 @@ public class TestExprCompiler {
       project.getChildExps().get(0).accept(compiler);
     }
 
-    assertEquals("int t0 = (int)(_data.get(0));\n", sw.toString());
+    assertThat(sw.toString(), containsString("(int)(_data.get(0));"));
   }
 
   @Test
@@ -83,7 +85,9 @@ public class TestExprCompiler {
         res[i] = project.getChildExps().get(i).accept(compiler);
       }
     }
-    assertArrayEquals(new String[]{"1 > 2", "3 + 5", "1 - 1.0E0", "3 + t0"},
-                      res);
+    assertThat(sw.get(0).toString(), containsString("1 > 2"));
+    assertThat(sw.get(1).toString(), containsString("3 + 5"));
+    assertThat(sw.get(2).toString(), containsString("1 - 1.0E0"));
+    assertThat(sw.get(3).toString(), containsString("3 +"));
   }
 }

http://git-wip-us.apache.org/repos/asf/storm/blob/1d0155aa/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprSemantic.java
----------------------------------------------------------------------
diff --git a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprSemantic.java b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprSemantic.java
index 7bde092..8454d7e 100644
--- a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprSemantic.java
+++ b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestExprSemantic.java
@@ -58,6 +58,15 @@ public class TestExprSemantic {
   }
 
   @Test
+  public void testArithmeticWithNull() throws Exception {
+    Values v = testExpr(
+      Lists.newArrayList(
+          "1 + CAST(NULL AS INT)", "CAST(NULL AS INT) + 1", "CAST(NULL AS INT) + CAST(NULL AS INT)", "1 + 2"
+      ));
+    assertEquals(new Values(null, null, null, 3), v);
+  }
+
+  @Test
   public void testNotWithNull() throws Exception {
     Values v = testExpr(
         Lists.newArrayList(

http://git-wip-us.apache.org/repos/asf/storm/blob/1d0155aa/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestRelNodeCompiler.java
----------------------------------------------------------------------
diff --git a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestRelNodeCompiler.java b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestRelNodeCompiler.java
index cedb48b..d820f22 100644
--- a/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestRelNodeCompiler.java
+++ b/external/sql/storm-sql-core/src/test/org/apache/storm/sql/compiler/TestRelNodeCompiler.java
@@ -23,12 +23,15 @@ import org.apache.calcite.rel.core.TableScan;
 import org.apache.calcite.rel.logical.LogicalFilter;
 import org.apache.calcite.rel.logical.LogicalProject;
 import org.apache.calcite.rel.type.RelDataTypeSystem;
+import org.hamcrest.CoreMatchers;
 import org.junit.Assert;
 import org.junit.Test;
 
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
+import static org.hamcrest.CoreMatchers.*;
+
 public class TestRelNodeCompiler {
   @Test
   public void testFilter() throws Exception {
@@ -45,7 +48,7 @@ public class TestRelNodeCompiler {
       RelNodeCompiler compiler = new RelNodeCompiler(pw, typeFactory);
       compiler.visitFilter(filter);
       pw.flush();
-      Assert.assertTrue(sw.toString().contains("t0 > 3"));
+      Assert.assertThat(sw.toString(), containsString("> 3"));
     }
 
     try (StringWriter sw = new StringWriter();
@@ -54,7 +57,7 @@ public class TestRelNodeCompiler {
       RelNodeCompiler compiler = new RelNodeCompiler(pw, typeFactory);
       compiler.visitProject(project);
       pw.flush();
-      Assert.assertTrue(sw.toString().contains("t0 + 1"));
+      Assert.assertThat(sw.toString(), containsString("+ 1"));
     }
   }
 }