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 <[email protected]> Authored: Tue Oct 10 15:56:12 2017 -0700 Committer: Jesus Camacho Rodriguez <[email protected]> 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
