Repository: calcite
Updated Branches:
  refs/heads/master 914b5cfbf -> e0eeb1b45


[CALCITE-1983] Push EQUALS and NOT EQUALS operations with numeric cast on 
dimensions

Close apache/calcite#536


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

Branch: refs/heads/master
Commit: e0eeb1b4585df70af147ab7df9ab385c1bc6012b
Parents: 914b5cf
Author: Jesus Camacho Rodriguez <[email protected]>
Authored: Tue Sep 12 14:53:59 2017 -0700
Committer: Jesus Camacho Rodriguez <[email protected]>
Committed: Tue Oct 3 15:41:18 2017 -0700

----------------------------------------------------------------------
 .../calcite/adapter/druid/DruidQuery.java       | 23 ++++++++++-
 .../org/apache/calcite/test/DruidAdapterIT.java | 40 ++++++++++++++++++++
 2 files changed, 61 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/e0eeb1b4/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 b4a069b..272a7c8 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
@@ -224,10 +224,10 @@ public class DruidQuery extends AbstractRelNode 
implements BindableRel {
     case AND:
     case OR:
     case NOT:
-    case EQUALS:
-    case NOT_EQUALS:
     case IN:
       return areValidFilters(((RexCall) e).getOperands(), false, input);
+    case EQUALS:
+    case NOT_EQUALS:
     case LESS_THAN:
     case LESS_THAN_OR_EQUAL:
     case GREATER_THAN:
@@ -1182,8 +1182,27 @@ public class DruidQuery extends AbstractRelNode 
implements BindableRel {
 
         switch (e.getKind()) {
         case EQUALS:
+          // extractionFunction should be null because if we are using an 
extraction function
+          // we have guarantees about the format of the output and thus we can 
apply the
+          // normal selector
+          if (numeric && extractionFunction == null) {
+            String constantValue = tr(e, posConstant);
+            return new JsonBound(dimName, constantValue, true, constantValue, 
true,
+                numeric, extractionFunction);
+          }
           return new JsonSelector(dimName, tr(e, posConstant), 
extractionFunction);
         case NOT_EQUALS:
+          // extractionFunction should be null because if we are using an 
extraction function
+          // we have guarantees about the format of the output and thus we can 
apply the
+          // normal selector
+          if (numeric && extractionFunction == null) {
+            String constantValue = tr(e, posConstant);
+            return new JsonCompositeFilter(JsonFilter.Type.OR,
+                new JsonBound(dimName, constantValue, false, null, false,
+                    numeric, extractionFunction),
+                new JsonBound(dimName, null, false, constantValue, false,
+                    numeric, extractionFunction));
+          }
           return new JsonCompositeFilter(JsonFilter.Type.NOT,
               new JsonSelector(dimName, tr(e, posConstant), 
extractionFunction));
         case GREATER_THAN:

http://git-wip-us.apache.org/repos/asf/calcite/blob/e0eeb1b4/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 c167e06..a6902cf 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -3186,6 +3186,46 @@ public class DruidAdapterIT {
     AbstractSchema schema = new DruidSchema("http://localhost:8082";, 
"http://localhost:8081";, true);
     assertSame(schema.getTable("wikiticker"), schema.getTable("wikiticker"));
   }
+
+  @Test public void testPushEqualsCastDimension() {
+    final String sqlQuery = "select sum(\"store_cost\") as a "
+        + "from \"foodmart\" "
+        + "where cast(\"customer_id\" as double) = 1.0";
+    final String plan = "PLAN=EnumerableInterpreter\n"
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+        + "filter=[=(CAST($20):DOUBLE, 1.0)], groups=[{}], aggs=[[SUM($91)]])";
+    sql(sqlQuery, FOODMART)
+        .explainContains(plan)
+        .queryContains(
+            druidChecker(
+                
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
+                + 
"'filter':{'type':'bound','dimension':'customer_id','lower':'1.0','lowerStrict':true,"
+                + "'upper':'1.0','upperStrict':true,'ordering':'numeric'},"
+                + 
"'aggregations':[{'type':'doubleSum','name':'A','fieldName':'store_cost'}],"
+                + 
"'intervals':['1900-01-09T00:00:00.000/2992-01-10T00:00:00.000'],"
+                + "'context':{'skipEmptyBuckets':true}}"));
+  }
+
+  @Test public void testPushNotEqualsCastDimension() {
+    final String sqlQuery = "select sum(\"store_cost\") as a "
+        + "from \"foodmart\" "
+        + "where cast(\"customer_id\" as double) <> 1.0";
+    final String plan = "PLAN=EnumerableInterpreter\n"
+        + "  DruidQuery(table=[[foodmart, foodmart]], 
intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], "
+        + "filter=[<>(CAST($20):DOUBLE, 1.0)], groups=[{}], 
aggs=[[SUM($91)]])";
+    sql(sqlQuery, FOODMART)
+        .explainContains(plan)
+        .queryContains(
+            druidChecker(
+                
"{'queryType':'timeseries','dataSource':'foodmart','descending':false,'granularity':'all',"
+                + 
"'filter':{'type':'or','fields':[{'type':'bound','dimension':'customer_id','lower':'1.0',"
+                + 
"'lowerStrict':false,'ordering':'numeric'},{'type':'bound','dimension':'customer_id',"
+                + "'upper':'1.0','upperStrict':false,'ordering':'numeric'}]},"
+                + 
"'aggregations':[{'type':'doubleSum','name':'A','fieldName':'store_cost'}],"
+                + 
"'intervals':['1900-01-09T00:00:00.000/2992-01-10T00:00:00.000'],"
+                + "'context':{'skipEmptyBuckets':true}}"));
+  }
+
 }
 
 // End DruidAdapterIT.java

Reply via email to