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
