Repository: calcite
Updated Branches:
  refs/heads/master 93a3aaedd -> e07e8ad9f


[CALCITE-2019] Druid's time column is not Null all the time thus Push 
count(druid_time_column) as count(*) (Slim Bouguerra)

Close apache/calcite#551


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

Branch: refs/heads/master
Commit: e07e8ad9fa9357b954cf967b95c7130a15c17b20
Parents: 93a3aae
Author: Slim <[email protected]>
Authored: Fri Oct 20 14:29:39 2017 -0700
Committer: Michael Mior <[email protected]>
Committed: Wed Nov 8 11:07:50 2017 -0500

----------------------------------------------------------------------
 .../calcite/adapter/druid/DruidTable.java       | 23 ++++++++++++++++----
 .../org/apache/calcite/test/DruidAdapterIT.java | 19 +++++++++++-----
 2 files changed, 33 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/calcite/blob/e07e8ad9/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
----------------------------------------------------------------------
diff --git 
a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java 
b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
index ff1f3e8..1993789 100644
--- a/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
+++ b/druid/src/main/java/org/apache/calcite/adapter/druid/DruidTable.java
@@ -136,9 +136,14 @@ public class DruidTable extends AbstractTable implements 
TranslatableTable {
                       Map<String, List<ComplexMetric>> complexMetrics) {
     final ImmutableMap<String, SqlTypeName> fields =
             ImmutableMap.copyOf(fieldMap);
-    return new DruidTable(druidSchema, dataSourceName,
-            new MapRelProtoDataType(fields), 
ImmutableSet.copyOf(metricNameSet),
-            timestampColumnName, intervals, complexMetrics, fieldMap);
+    return new DruidTable(druidSchema,
+        dataSourceName,
+        new MapRelProtoDataType(fields, timestampColumnName),
+        ImmutableSet.copyOf(metricNameSet),
+        timestampColumnName,
+        intervals,
+        complexMetrics,
+        fieldMap);
   }
 
   /**
@@ -244,15 +249,25 @@ public class DruidTable extends AbstractTable implements 
TranslatableTable {
    * field names and types. */
   private static class MapRelProtoDataType implements RelProtoDataType {
     private final ImmutableMap<String, SqlTypeName> fields;
+    private final String timestampColumn;
 
     MapRelProtoDataType(ImmutableMap<String, SqlTypeName> fields) {
       this.fields = fields;
+      this.timestampColumn = DruidTable.DEFAULT_TIMESTAMP_COLUMN;
+    }
+
+    MapRelProtoDataType(ImmutableMap<String, SqlTypeName> fields, String 
timestampColumn) {
+      this.fields = fields;
+      this.timestampColumn = timestampColumn;
     }
 
     public RelDataType apply(RelDataTypeFactory typeFactory) {
       final RelDataTypeFactory.Builder builder = typeFactory.builder();
       for (Map.Entry<String, SqlTypeName> field : fields.entrySet()) {
-        builder.add(field.getKey(), field.getValue()).nullable(true);
+        final String key = field.getKey();
+        builder.add(key, field.getValue())
+            // Druid's time column is always not null and the only column 
called __time.
+            .nullable(!timestampColumn.equals(key));
       }
       return builder.build();
     }

http://git-wip-us.apache.org/repos/asf/calcite/blob/e07e8ad9/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 a8d0203..36c866e 100644
--- a/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
+++ b/druid/src/test/java/org/apache/calcite/test/DruidAdapterIT.java
@@ -280,7 +280,7 @@ public class DruidAdapterIT {
         + "group by \"page\", floor(\"__time\" to DAY)\n"
         + "order by \"s\" desc";
     final String explain = "PLAN=EnumerableInterpreter\n"
-        + "  BindableProject(s=[$2], page=[$0], day=[CAST($1):TIMESTAMP(0)])\n"
+        + "  BindableProject(s=[$2], page=[$0], day=[CAST($1):TIMESTAMP(0) NOT 
NULL])\n"
         + "    DruidQuery(table=[[wiki, wikiticker]], "
         + "intervals=[[1900-01-01T00:00:00.000/3000-01-01T00:00:00.000]], 
projects=[[$17, FLOOR"
         + "($0, FLAG(DAY)), $1]], groups=[{0, 1}], aggs=[[SUM($2)]], 
sort0=[2], dir0=[DESC])";
@@ -361,7 +361,7 @@ public class DruidAdapterIT {
         + "where \"__time\" < '2015-10-12 00:00:00 UTC')";
     final String explain = "PLAN="
         + "EnumerableInterpreter\n"
-        + "  BindableProject(__time=[CAST($0):TIMESTAMP(0)])\n"
+        + "  BindableProject(__time=[CAST($0):TIMESTAMP(0) NOT NULL)\n"
         + "    DruidQuery(table=[[wiki, wikiticker]], "
         + "intervals=[[1900-01-01T00:00:00.000/2015-10-12T00:00:00.000]], "
         + "groups=[{0}], aggs=[[]])\n";
@@ -394,7 +394,7 @@ public class DruidAdapterIT {
                   // 1 timestamp, 2 float measure, 1 int measure, 88 dimensions
                   assertThat(map.keySet().size(), is(4));
                   assertThat(map.values().size(), is(92));
-                  
assertThat(map.get("TIMESTAMP_WITH_LOCAL_TIME_ZONE(0)").size(), is(1));
+                  assertThat(map.get("TIMESTAMP_WITH_LOCAL_TIME_ZONE(0) NOT 
NULL").size(), is(1));
                   assertThat(map.get("DOUBLE").size(), is(2));
                   assertThat(map.get("BIGINT").size(), is(1));
                   assertThat(map.get(VARCHAR_TYPE).size(), is(88));
@@ -1434,7 +1434,7 @@ public class DruidAdapterIT {
     String plan = "BindableProject(countryName=[$0], EXPR$1=[$1], 
C=[CAST($2):INTEGER NOT NULL])\n"
         + "    BindableSort(sort0=[$2], dir0=[ASC], fetch=[5])\n"
         + "      BindableAggregate(group=[{0, 1}], agg#0=[COUNT()])\n"
-        + "        BindableProject(countryName=[$1], 
EXPR$1=[FLOOR(CAST($0):TIMESTAMP(0), FLAG(DAY))])\n"
+        + "        BindableProject(countryName=[$1], 
EXPR$1=[FLOOR(CAST($0):TIMESTAMP(0) NOT NULL, FLAG(DAY))])\n"
         + "          BindableFilter(condition=[AND(>=(FLOOR($0, FLAG(DAY)), 
1997-01-01 00:00:00), <(FLOOR($0, FLAG(DAY)), 1997-09-01 00:00:00))])\n"
         + "            DruidQuery(table=[[wiki, wiki]], 
intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], projects=[[$0, 
$5]])";
     // NOTE: Druid query only has countryName as the dimension
@@ -1938,7 +1938,7 @@ public class DruidAdapterIT {
     sql(sqlQuery)
         .explainContains("PLAN=EnumerableInterpreter\n"
         + "  BindableSort(sort0=[$1], dir0=[DESC])\n"
-        + "    BindableProject(C=[$1], S=[$2], 
EXPR$2=[CAST($0):TIMESTAMP(0)])\n"
+        + "    BindableProject(C=[$1], S=[$2], EXPR$2=[CAST($0):TIMESTAMP(0) 
NOT NULL])\n"
         + "      DruidQuery(table=[[foodmart, foodmart]], "
         + "intervals=[[1900-01-09T00:00:00.000/2992-01-10T00:00:00.000]], 
projects=[[FLOOR($0, "
         + "FLAG(MONTH)), $89]], groups=[{0}], aggs=[[COUNT(), SUM($1)]])")
@@ -2901,6 +2901,15 @@ public class DruidAdapterIT {
         .explainContains(plan3);
   }
 
+  @Test
+  public void testCountWithNonNull() {
+    final String sql = "select count(\"timestamp\") from \"foodmart\"\n";
+    final String druidQuery = 
"{'queryType':'timeseries','dataSource':'foodmart'";
+    sql(sql)
+        .returnsUnordered("EXPR$0=86829")
+        .queryContains(druidChecker(druidQuery));
+  }
+
   /**
    * Test to make sure the "not" filter has only 1 field, rather than an array 
of fields.
    */

Reply via email to