You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@calcite.apache.org by jc...@apache.org on 2017/10/10 23:57:45 UTC

calcite git commit: [CALCITE-2006] Push IS NULL and IS NOT NULL predicates to Druid

Repository: calcite
Updated Branches:
  refs/heads/master 6971a3065 -> 453e928b6


[CALCITE-2006] Push IS NULL and IS NOT NULL predicates to Druid

Close apache/calcite#546


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

Branch: refs/heads/master
Commit: 453e928b67d56cc5d6384250c88bb809ec49041c
Parents: 6971a30
Author: Jesus Camacho Rodriguez <jc...@apache.org>
Authored: Tue Oct 10 15:56:12 2017 -0700
Committer: Jesus Camacho Rodriguez <jc...@apache.org>
Committed: Tue Oct 10 16:56:56 2017 -0700

----------------------------------------------------------------------
 .../calcite/adapter/druid/DruidQuery.java       | 14 ++++++++-
 .../org/apache/calcite/test/DruidAdapterIT.java | 32 ++++++++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/453e928b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
----------------------------------------------------------------------
diff --git a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
index 20cdb7c..012d272 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidQuery.java
@@ -225,6 +225,8 @@ public class DruidQuery extends AbstractRelNode implements BindableRel {
     case OR:
     case NOT:
     case IN:
+    case IS_NULL:
+    case IS_NOT_NULL:
       return areValidFilters(((RexCall) e).getOperands(), false, input);
     case EQUALS:
     case NOT_EQUALS:
@@ -1151,10 +1153,15 @@ public class DruidQuery extends AbstractRelNode implements BindableRel {
       case LESS_THAN_OR_EQUAL:
       case IN:
       case BETWEEN:
+      case IS_NULL:
+      case IS_NOT_NULL:
         call = (RexCall) e;
         int posRef;
         int posConstant;
-        if (RexUtil.isConstant(call.getOperands().get(1))) {
+        if (call.getOperands().size() == 1) { // IS NULL and IS NOT NULL
+          posRef = 0;
+          posConstant = -1;
+        } else if (RexUtil.isConstant(call.getOperands().get(1))) {
           posRef = 0;
           posConstant = 1;
         } else if (RexUtil.isConstant(call.getOperands().get(0))) {
@@ -1228,6 +1235,11 @@ public class DruidQuery extends AbstractRelNode implements BindableRel {
         case BETWEEN:
           return new JsonBound(dimName, tr(e, 2), false,
               tr(e, 3), false, numeric, extractionFunction);
+        case IS_NULL:
+          return new JsonSelector(dimName, null, extractionFunction);
+        case IS_NOT_NULL:
+          return new JsonCompositeFilter(JsonFilter.Type.NOT,
+              new JsonSelector(dimName, null, extractionFunction));
         default:
           throw new AssertionError();
         }

http://git-wip-us.apache.org/repos/asf/calcite/blob/453e928b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
----------------------------------------------------------------------
diff --git a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
index 1f6b895..a8d0203 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -1410,7 +1410,9 @@ public class DruidAdapterIT {
         + " 'Germany', 'India', 'Italy', 'Russia', 'United Kingdom',\n"
         + " 'United States') or \"wikiticker\".\"countryName\" is null)\n"
         + "group by \"wikiticker\".\"countryName\"";
+    String druidQuery = "{'type':'selector','dimension':'countryName','value':null}";
     sql(sql, WIKI)
+        .queryContains(druidChecker(druidQuery))
         .returnsCount(9);
   }
 
@@ -3242,6 +3244,36 @@ public class DruidAdapterIT {
         .returnsUnordered("A=225541.91732536256");
   }
 
+  @Test public void testIsNull() {
+    final String sql = "select count(*) as c "
+        + "from \"foodmart\" "
+        + "where \"product_id\" is null";
+    final String druidQuery =
+        "{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
+            + "'filter':{'type':'selector','dimension':'product_id','value':null},"
+            + "'aggregations':[{'type':'count','name':'C'}],"
+            + "'intervals':['1900-01-09T00:00:00.000/2992-01-10T00:00:00.000'],"
+            + "'context':{'skipEmptyBuckets':true}}";
+    sql(sql, FOODMART)
+        .queryContains(druidChecker(druidQuery))
+        .returnsCount(0);
+  }
+
+  @Test public void testIsNotNull() {
+    final String sql = "select count(*) as c "
+        + "from \"foodmart\" "
+        + "where \"product_id\" is not null";
+    final String druidQuery =
+        "{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
+            + "'filter':{'type':'not','field':{'type':'selector','dimension':'product_id','value':null}},"
+            + "'aggregations':[{'type':'count','name':'C'}],"
+            + "'intervals':['1900-01-09T00:00:00.000/2992-01-10T00:00:00.000'],"
+            + "'context':{'skipEmptyBuckets':true}}";
+    sql(sql, FOODMART)
+        .queryContains(druidChecker(druidQuery))
+        .returnsUnordered("C=86829");
+  }
+
 }
 
 // End DruidAdapterIT.java