You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@druid.apache.org by gi...@apache.org on 2018/07/09 15:58:45 UTC

[incubator-druid] branch master updated: Support limit for timeseries query (#5894) (#5931)

This is an automated email from the ASF dual-hosted git repository.

gian pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-druid.git


The following commit(s) were added to refs/heads/master by this push:
     new 441c981  Support limit for timeseries query (#5894) (#5931)
441c981 is described below

commit 441c9819d99677a5cb7b810ad126894ed3bf8eca
Author: Surekha <su...@imply.io>
AuthorDate: Mon Jul 9 08:58:42 2018 -0700

    Support limit for timeseries query (#5894) (#5931)
    
    * Support limit for timeseries query (#5894)
    
    * Fix tests
    
    * Address PR comments
    
    * Try to fix teamcity inspection checks
    
    * Remove unused method from VirtualColumns
    
    * Remove unused import statement
---
 .../src/main/java/io/druid/query/Druids.java       |  10 ++
 .../timeseries/DefaultTimeseriesQueryMetrics.java  |   7 ++
 .../io/druid/query/timeseries/TimeseriesQuery.java |  17 +++-
 .../query/timeseries/TimeseriesQueryEngine.java    |  10 +-
 .../query/timeseries/TimeseriesQueryMetrics.java   |   7 ++
 .../timeseries/TimeseriesQueryQueryToolChest.java  |   8 +-
 .../main/java/io/druid/segment/VirtualColumns.java |   6 --
 .../DefaultTimeseriesQueryMetricsTest.java         |   2 +-
 .../TimeseriesQueryQueryToolChestTest.java         |   1 +
 .../timeseries/TimeseriesQueryRunnerTest.java      |  32 +++++++
 .../java/io/druid/sql/calcite/rel/DruidQuery.java  |  21 ++++-
 .../druid/sql/avatica/DruidAvaticaHandlerTest.java |   2 +-
 .../io/druid/sql/calcite/CalciteQueryTest.java     | 101 +++++++--------------
 .../io/druid/sql/calcite/http/SqlResourceTest.java |   2 +-
 14 files changed, 141 insertions(+), 85 deletions(-)

diff --git a/processing/src/main/java/io/druid/query/Druids.java b/processing/src/main/java/io/druid/query/Druids.java
index e235a99..4383080 100644
--- a/processing/src/main/java/io/druid/query/Druids.java
+++ b/processing/src/main/java/io/druid/query/Druids.java
@@ -105,6 +105,7 @@ public class Druids
     private List<AggregatorFactory> aggregatorSpecs;
     private List<PostAggregator> postAggregatorSpecs;
     private Map<String, Object> context;
+    private int limit;
 
     private TimeseriesQueryBuilder()
     {
@@ -116,6 +117,7 @@ public class Druids
       granularity = Granularities.ALL;
       aggregatorSpecs = Lists.newArrayList();
       postAggregatorSpecs = Lists.newArrayList();
+      limit = 0;
       context = null;
     }
 
@@ -130,6 +132,7 @@ public class Druids
           granularity,
           aggregatorSpecs,
           postAggregatorSpecs,
+          limit,
           context
       );
     }
@@ -145,6 +148,7 @@ public class Druids
           .granularity(query.getGranularity())
           .aggregators(query.getAggregatorSpecs())
           .postAggregators(query.getPostAggregatorSpecs())
+          .limit(query.getLimit())
           .context(query.getContext());
     }
 
@@ -254,6 +258,12 @@ public class Druids
       context = c;
       return this;
     }
+
+    public TimeseriesQueryBuilder limit(int lim)
+    {
+      limit = lim;
+      return this;
+    }
   }
 
   public static TimeseriesQueryBuilder newTimeseriesQueryBuilder()
diff --git a/processing/src/main/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetrics.java b/processing/src/main/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetrics.java
index b7f0f9a..7650180 100644
--- a/processing/src/main/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetrics.java
+++ b/processing/src/main/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetrics.java
@@ -35,12 +35,19 @@ public class DefaultTimeseriesQueryMetrics extends DefaultQueryMetrics<Timeserie
   public void query(TimeseriesQuery query)
   {
     super.query(query);
+    limit(query);
     numMetrics(query);
     numComplexMetrics(query);
     granularity(query);
   }
 
   @Override
+  public void limit(TimeseriesQuery query)
+  {
+    setDimension("limit", String.valueOf(query.getLimit()));
+  }
+
+  @Override
   public void numMetrics(TimeseriesQuery query)
   {
     setDimension("numMetrics", String.valueOf(query.getAggregatorSpecs().size()));
diff --git a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQuery.java b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQuery.java
index 3e6452d..dd4a3b2 100644
--- a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQuery.java
+++ b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQuery.java
@@ -22,6 +22,7 @@ package io.druid.query.timeseries;
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableList;
 import io.druid.java.util.common.granularity.Granularity;
 import io.druid.query.BaseQuery;
@@ -52,6 +53,7 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
   private final DimFilter dimFilter;
   private final List<AggregatorFactory> aggregatorSpecs;
   private final List<PostAggregator> postAggregatorSpecs;
+  private final int limit;
 
   @JsonCreator
   public TimeseriesQuery(
@@ -63,6 +65,7 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
       @JsonProperty("granularity") Granularity granularity,
       @JsonProperty("aggregations") List<AggregatorFactory> aggregatorSpecs,
       @JsonProperty("postAggregations") List<PostAggregator> postAggregatorSpecs,
+      @JsonProperty("limit") int limit,
       @JsonProperty("context") Map<String, Object> context
   )
   {
@@ -76,6 +79,8 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
         this.aggregatorSpecs,
         postAggregatorSpecs == null ? ImmutableList.of() : postAggregatorSpecs
     );
+    this.limit = (limit == 0) ? Integer.MAX_VALUE : limit;
+    Preconditions.checkArgument(this.limit > 0, "limit must be greater than 0");
   }
 
   @Override
@@ -120,6 +125,12 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
     return postAggregatorSpecs;
   }
 
+  @JsonProperty("limit")
+  public int getLimit()
+  {
+    return limit;
+  }
+
   public boolean isGrandTotal()
   {
     return getContextBoolean(CTX_GRAND_TOTAL, false);
@@ -171,6 +182,7 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
            ", granularity='" + getGranularity() + '\'' +
            ", aggregatorSpecs=" + aggregatorSpecs +
            ", postAggregatorSpecs=" + postAggregatorSpecs +
+           ", limit=" + limit +
            ", context=" + getContext() +
            '}';
   }
@@ -188,7 +200,8 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
       return false;
     }
     final TimeseriesQuery that = (TimeseriesQuery) o;
-    return Objects.equals(virtualColumns, that.virtualColumns) &&
+    return limit == that.limit &&
+           Objects.equals(virtualColumns, that.virtualColumns) &&
            Objects.equals(dimFilter, that.dimFilter) &&
            Objects.equals(aggregatorSpecs, that.aggregatorSpecs) &&
            Objects.equals(postAggregatorSpecs, that.postAggregatorSpecs);
@@ -197,6 +210,6 @@ public class TimeseriesQuery extends BaseQuery<Result<TimeseriesResultValue>>
   @Override
   public int hashCode()
   {
-    return Objects.hash(super.hashCode(), virtualColumns, dimFilter, aggregatorSpecs, postAggregatorSpecs);
+    return Objects.hash(super.hashCode(), virtualColumns, dimFilter, aggregatorSpecs, postAggregatorSpecs, limit);
   }
 }
diff --git a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryEngine.java b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryEngine.java
index 8c2ae5f..3b8909e 100644
--- a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryEngine.java
+++ b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryEngine.java
@@ -46,7 +46,16 @@ public class TimeseriesQueryEngine
     }
 
     final Filter filter = Filters.convertToCNFFromQueryContext(query, Filters.toFilter(query.getDimensionsFilter()));
+    final int limit = query.getLimit();
+    Sequence<Result<TimeseriesResultValue>> result = generateTimeseriesResult(adapter, query, filter);
+    if (limit < Integer.MAX_VALUE) {
+      return result.limit(limit);
+    }
+    return result;
+  }
 
+  private Sequence<Result<TimeseriesResultValue>> generateTimeseriesResult(StorageAdapter adapter, TimeseriesQuery query, Filter filter)
+  {
     return QueryRunnerHelper.makeCursorBasedQuery(
         adapter,
         query.getQuerySegmentSpec().getIntervals(),
@@ -81,7 +90,6 @@ public class TimeseriesQueryEngine
                 }
                 cursor.advance();
               }
-
               TimeseriesResultBuilder bob = new TimeseriesResultBuilder(cursor.getTime());
 
               for (int i = 0; i < aggregatorSpecs.size(); i++) {
diff --git a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryMetrics.java b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryMetrics.java
index 84f4042..7bdaf11 100644
--- a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryMetrics.java
+++ b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryMetrics.java
@@ -29,6 +29,13 @@ import io.druid.query.QueryMetrics;
 @ExtensionPoint
 public interface TimeseriesQueryMetrics extends QueryMetrics<TimeseriesQuery>
 {
+
+  /**
+   * Sets {@link TimeseriesQuery#getLimit()} of the given query as dimension.
+   */
+  @PublicApi
+  void limit(TimeseriesQuery query);
+
   /**
    * Sets the number of metrics of the given timeseries query as dimension.
    */
diff --git a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChest.java b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChest.java
index ebdffc7..75817c5 100644
--- a/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChest.java
+++ b/processing/src/main/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChest.java
@@ -107,12 +107,17 @@ public class TimeseriesQueryQueryToolChest extends QueryToolChest<Result<Timeser
           Map<String, Object> context
       )
       {
-        return super.doRun(
+        int limit = ((TimeseriesQuery) queryPlus.getQuery()).getLimit();
+        Sequence<Result<TimeseriesResultValue>> result = super.doRun(
             baseRunner,
             // Don't do post aggs until makePostComputeManipulatorFn() is called
             queryPlus.withQuery(((TimeseriesQuery) queryPlus.getQuery()).withPostAggregatorSpecs(ImmutableList.of())),
             context
         );
+        if (limit < Integer.MAX_VALUE) {
+          return result.limit(limit);
+        }
+        return result;
       }
 
       @Override
@@ -264,6 +269,7 @@ public class TimeseriesQueryQueryToolChest extends QueryToolChest<Result<Timeser
             .appendCacheable(query.getDimensionsFilter())
             .appendCacheables(query.getAggregatorSpecs())
             .appendCacheable(query.getVirtualColumns())
+            .appendInt(query.getLimit())
             .build();
       }
 
diff --git a/processing/src/main/java/io/druid/segment/VirtualColumns.java b/processing/src/main/java/io/druid/segment/VirtualColumns.java
index 189f3cd..409e3d6 100644
--- a/processing/src/main/java/io/druid/segment/VirtualColumns.java
+++ b/processing/src/main/java/io/druid/segment/VirtualColumns.java
@@ -25,7 +25,6 @@ import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import io.druid.java.util.common.Cacheable;
@@ -71,11 +70,6 @@ public class VirtualColumns implements Cacheable
     }
   }
 
-  public static VirtualColumns create(VirtualColumn...virtualColumns)
-  {
-    return create(Lists.newArrayList(virtualColumns));
-  }
-
   @JsonCreator
   public static VirtualColumns create(List<VirtualColumn> virtualColumns)
   {
diff --git a/processing/src/test/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetricsTest.java b/processing/src/test/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetricsTest.java
index d5027bf..e76e0da 100644
--- a/processing/src/test/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetricsTest.java
+++ b/processing/src/test/java/io/druid/query/timeseries/DefaultTimeseriesQueryMetricsTest.java
@@ -60,7 +60,7 @@ public class DefaultTimeseriesQueryMetricsTest
 
     queryMetrics.reportQueryTime(0).emit(serviceEmitter);
     Map<String, Object> actualEvent = cachingEmitter.getLastEmittedEvent().toMap();
-    Assert.assertEquals(14, actualEvent.size());
+    Assert.assertEquals(15, actualEvent.size());
     Assert.assertTrue(actualEvent.containsKey("feed"));
     Assert.assertTrue(actualEvent.containsKey("timestamp"));
     Assert.assertEquals("", actualEvent.get("host"));
diff --git a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java
index 0c4c0e7..1498d4e 100644
--- a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java
+++ b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryQueryToolChestTest.java
@@ -79,6 +79,7 @@ public class TimeseriesQueryQueryToolChestTest
                     new LongSumAggregatorFactory("metric0", "metric0")
                 ),
                 ImmutableList.<PostAggregator>of(new ConstantPostAggregator("post", 10)),
+                0,
                 null
             )
         );
diff --git a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerTest.java b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerTest.java
index 5e0ab9a..2465726 100644
--- a/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerTest.java
+++ b/processing/src/test/java/io/druid/query/timeseries/TimeseriesQueryRunnerTest.java
@@ -2415,4 +2415,36 @@ public class TimeseriesQueryRunnerTest
     TestHelper.assertExpectedResults(expectedResults, results2);
 
   }
+
+  @Test
+  public void testTimeseriesWithLimit()
+  {
+    TimeseriesQuery query = Druids.newTimeseriesQueryBuilder()
+                                  .dataSource(QueryRunnerTestHelper.dataSource)
+                                  .granularity(QueryRunnerTestHelper.dayGran)
+                                  .intervals(QueryRunnerTestHelper.fullOnInterval)
+                                  .aggregators(
+                                      Arrays.<AggregatorFactory>asList(
+                                          QueryRunnerTestHelper.rowsCount,
+                                          QueryRunnerTestHelper.qualityUniques
+                                      )
+                                  )
+                                  .descending(descending)
+                                  .limit(10)
+                                  .build();
+
+    // Must create a toolChest so we can run mergeResults.
+    QueryToolChest<Result<TimeseriesResultValue>, TimeseriesQuery> toolChest = new TimeseriesQueryQueryToolChest(
+        QueryRunnerTestHelper.NoopIntervalChunkingQueryRunnerDecorator()
+    );
+
+    // Must wrapped in a results finalizer to stop the runner's builtin finalizer from being called.
+    final FinalizeResultsQueryRunner finalRunner = new FinalizeResultsQueryRunner(
+        toolChest.mergeResults(runner),
+        toolChest
+    );
+
+    final List list = finalRunner.run(QueryPlus.wrap(query), CONTEXT).toList();
+    Assert.assertEquals(10, list.size());
+  }
 }
diff --git a/sql/src/main/java/io/druid/sql/calcite/rel/DruidQuery.java b/sql/src/main/java/io/druid/sql/calcite/rel/DruidQuery.java
index 0d0532e..9eebbfb 100644
--- a/sql/src/main/java/io/druid/sql/calcite/rel/DruidQuery.java
+++ b/sql/src/main/java/io/druid/sql/calcite/rel/DruidQuery.java
@@ -103,12 +103,25 @@ public class DruidQuery
   private final RowSignature sourceRowSignature;
   private final PlannerContext plannerContext;
 
+  @Nullable
   private final DimFilter filter;
+
+  @Nullable
   private final SelectProjection selectProjection;
+
+  @Nullable
   private final Grouping grouping;
+
+  @Nullable
   private final SortProject sortProject;
+
+  @Nullable
   private final DefaultLimitSpec limitSpec;
+
+  @Nullable
   private final RowSignature outputRowSignature;
+
+  @Nullable
   private final RelDataType outputRowType;
 
   private final Query query;
@@ -731,7 +744,7 @@ public class DruidQuery
 
     final Granularity queryGranularity;
     final boolean descending;
-
+    int timeseriesLimit = 0;
     if (grouping.getDimensions().isEmpty()) {
       queryGranularity = Granularities.ALL;
       descending = false;
@@ -746,11 +759,10 @@ public class DruidQuery
         // Timeseries only applies if the single dimension is granular __time.
         return null;
       }
-
       if (limitSpec != null) {
-        // If there is a limit spec, timeseries cannot LIMIT; and must be ORDER BY time (or nothing).
+        // If there is a limit spec, set timeseriesLimit to given value if less than Integer.Max_VALUE
         if (limitSpec.isLimited()) {
-          return null;
+          timeseriesLimit = limitSpec.getLimit();
         }
 
         if (limitSpec.getColumns().isEmpty()) {
@@ -797,6 +809,7 @@ public class DruidQuery
         queryGranularity,
         grouping.getAggregatorFactories(),
         postAggregators,
+        timeseriesLimit,
         ImmutableSortedMap.copyOf(theContext)
     );
   }
diff --git a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java
index 1637369..705e483 100644
--- a/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java
+++ b/sql/src/test/java/io/druid/sql/avatica/DruidAvaticaHandlerTest.java
@@ -308,7 +308,7 @@ public class DruidAvaticaHandlerTest extends CalciteTestBase
         ImmutableList.of(
             ImmutableMap.of(
                 "PLAN",
-                "DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"context\":{\"skipEmptyBuckets\":true}}], signature=[{a0:LONG}])\n"
+                "DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"limit\":2147483647,\"context\":{\"skipEmptyBuckets\":true}}], signature=[{a [...]
             )
         ),
         getRows(resultSet)
diff --git a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java
index d558f77..5bf6f57 100644
--- a/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java
+++ b/sql/src/test/java/io/druid/sql/calcite/CalciteQueryTest.java
@@ -82,7 +82,6 @@ import io.druid.query.topn.DimensionTopNMetricSpec;
 import io.druid.query.topn.InvertedTopNMetricSpec;
 import io.druid.query.topn.NumericTopNMetricSpec;
 import io.druid.query.topn.TopNQueryBuilder;
-import io.druid.segment.VirtualColumns;
 import io.druid.segment.column.Column;
 import io.druid.segment.column.ValueType;
 import io.druid.segment.virtual.ExpressionVirtualColumn;
@@ -2129,6 +2128,7 @@ public class CalciteQueryTest extends CalciteTestBase
         + "\"granularity\":{\"type\":\"all\"},"
         + "\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],"
         + "\"postAggregations\":[],"
+        + "\"limit\":2147483647,"
         + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"skipEmptyBuckets\":true,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\"}}]"
         + ", signature=[{a0:LONG}])\n";
 
@@ -4128,7 +4128,7 @@ public class CalciteQueryTest extends CalciteTestBase
   public void testExplainDoubleNestedGroupBy() throws Exception
   {
     final String explanation =
-        "DruidOuterQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"longSum\",\"name\":\"a0\",\"fieldName\":\"cnt\",\"expression\":null},{\"type\":\"count\",\"name\":\"a1\"}],\"postAggregat [...]
+        "DruidOuterQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"longSum\",\"name\":\"a0\",\"fieldName\":\"cnt\",\"expression\":null},{\"type\":\"count\",\"name\":\"a1\"}],\"postAggregat [...]
         + "  DruidOuterQueryRel(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"default\",\"dimension\":\"dim2\",\"outputName\":\"d0\",\"outputType\":\"STRING\"}],\"aggregations\":[{\"type\":\"longSum\",\"name\":\"a0\",\"fi [...]
         + "    DruidQueryRel(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"default\",\"dimension\":\"dim1\",\"outputName\":\"d0\",\"outputType\":\"STRING\"},{\"type\":\"default\",\"dimension\":\"dim2\",\"outputName\":\"d1\",\"outp [...]
 
@@ -4425,7 +4425,7 @@ public class CalciteQueryTest extends CalciteTestBase
   public void testExplainExactCountDistinctOfSemiJoinResult() throws Exception
   {
     final String explanation =
-        "DruidOuterQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":922337 [...]
+        "DruidOuterQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"limit\":2147483647,\"context\":{\"defaultTimeout\":300000,\"maxScatte [...]
         + "  DruidSemiJoin(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"default\",\"dimension\":\"dim2\",\"outputName\":\"d0\",\"outputType\":\"STRING\"}],\"aggregations\":[],\"postAggregations\":[],\"having\":null,\"limitSpec\": [...]
         + "    DruidQueryRel(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[],\"filter\":{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"\",\"extractionFn\":null}},\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"extraction\",\"dimension\":\"dim1\",\"outputNam [...]
 
@@ -6118,33 +6118,14 @@ public class CalciteQueryTest extends CalciteTestBase
         + "LIMIT 1",
         CalciteTests.REGULAR_USER_AUTH_RESULT,
         ImmutableList.of(
-            GroupByQuery.builder()
-                        .setDataSource(CalciteTests.DATASOURCE1)
-                        .setInterval(QSS(Filtration.eternity()))
-                        .setGranularity(Granularities.ALL)
-                        .setVirtualColumns(
-                            EXPRESSION_VIRTUAL_COLUMN(
-                                "d0:v",
-                                "timestamp_floor(\"__time\",'P1M','','UTC')",
-                                ValueType.LONG
-                            )
-                        )
-                        .setDimensions(DIMS(new DefaultDimensionSpec("d0:v", "d0", ValueType.LONG)))
-                        .setAggregatorSpecs(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
-                        .setLimitSpec(
-                            new DefaultLimitSpec(
-                                ImmutableList.of(
-                                    new OrderByColumnSpec(
-                                        "d0",
-                                        OrderByColumnSpec.Direction.ASCENDING,
-                                        StringComparators.NUMERIC
-                                    )
-                                ),
-                                1
-                            )
-                        )
-                        .setContext(QUERY_CONTEXT_DEFAULT)
-                        .build()
+            Druids.newTimeseriesQueryBuilder()
+                  .dataSource(CalciteTests.DATASOURCE1)
+                  .intervals(QSS(Filtration.eternity()))
+                  .granularity(Granularities.MONTH)
+                  .aggregators(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
+                  .limit(1)
+                  .context(TIMESERIES_CONTEXT_DEFAULT)
+                  .build()
         ),
         ImmutableList.of(
             new Object[]{T("2000-01-01"), 3L}
@@ -6164,19 +6145,14 @@ public class CalciteQueryTest extends CalciteTestBase
         + "GROUP BY gran\n"
         + "LIMIT 1",
         ImmutableList.of(
-            new TopNQueryBuilder()
-                .dataSource(CalciteTests.DATASOURCE1)
-                .intervals(QSS(Filtration.eternity()))
-                .granularity(Granularities.ALL)
-                .virtualColumns(
-                    EXPRESSION_VIRTUAL_COLUMN("d0:v", "timestamp_floor(\"__time\",'P1M','','UTC')", ValueType.LONG)
-                )
-                .dimension(new DefaultDimensionSpec("d0:v", "d0", ValueType.LONG))
-                .aggregators(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
-                .metric(new DimensionTopNMetricSpec(null, StringComparators.NUMERIC))
-                .threshold(1)
-                .context(QUERY_CONTEXT_DEFAULT)
-                .build()
+            Druids.newTimeseriesQueryBuilder()
+                  .dataSource(CalciteTests.DATASOURCE1)
+                  .intervals(QSS(Filtration.eternity()))
+                  .granularity(Granularities.MONTH)
+                  .aggregators(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
+                  .limit(1)
+                  .context(TIMESERIES_CONTEXT_DEFAULT)
+                  .build()
         ),
         ImmutableList.of(
             new Object[]{T("2000-01-01"), 3L}
@@ -6197,19 +6173,14 @@ public class CalciteQueryTest extends CalciteTestBase
         + "ORDER BY gran\n"
         + "LIMIT 1",
         ImmutableList.of(
-            new TopNQueryBuilder()
-                .dataSource(CalciteTests.DATASOURCE1)
-                .intervals(QSS(Filtration.eternity()))
-                .granularity(Granularities.ALL)
-                .virtualColumns(
-                    EXPRESSION_VIRTUAL_COLUMN("d0:v", "timestamp_floor(\"__time\",'P1M','','UTC')", ValueType.LONG)
-                )
-                .dimension(new DefaultDimensionSpec("d0:v", "d0", ValueType.LONG))
-                .aggregators(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
-                .metric(new DimensionTopNMetricSpec(null, StringComparators.NUMERIC))
-                .threshold(1)
-                .context(QUERY_CONTEXT_DEFAULT)
-                .build()
+            Druids.newTimeseriesQueryBuilder()
+                  .dataSource(CalciteTests.DATASOURCE1)
+                  .intervals(QSS(Filtration.eternity()))
+                  .granularity(Granularities.MONTH)
+                  .aggregators(AGGS(new LongSumAggregatorFactory("a0", "cnt")))
+                  .limit(1)
+                  .context(TIMESERIES_CONTEXT_DEFAULT)
+                  .build()
         ),
         ImmutableList.of(
             new Object[]{T("2000-01-01"), 3L}
@@ -6334,7 +6305,7 @@ public class CalciteQueryTest extends CalciteTestBase
         + "      BindableJoin(condition=[=($1, $3)], joinType=[left])\n"
         + "        BindableJoin(condition=[true], joinType=[inner])\n"
         + "          DruidQueryRel(query=[{\"queryType\":\"scan\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[],\"resultFormat\":\"compactedList\",\"batchSize\":20480,\"limit\":9223372036854775807,\"filter\":null,\"columns\":[\"dim1\",\"dim2\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775 [...]
-        + "          DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":{\"type\":\"like\",\"dimension\":\"dim1\",\"pattern\":\"%bc\",\"escape\":null,\"extractionFn\":null},\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\ [...]
+        + "          DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":{\"type\":\"like\",\"dimension\":\"dim1\",\"pattern\":\"%bc\",\"escape\":null,\"extractionFn\":null},\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\ [...]
         + "        DruidQueryRel(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"virtualColumns\":[{\"type\":\"expression\",\"name\":\"d1:v\",\"expression\":\"1\",\"outputType\":\"LONG\"}],\"filter\":{\"type\":\"like\",\"dimension\":\"dim1\",\"pattern\":\"%bc\",\"escape\":null,\"extractionFn\":null},\"granularity\":{\"type\":\"al [...]
 
     final String theQuery = "SELECT dim1, dim2, COUNT(*) FROM druid.foo\n"
@@ -6767,27 +6738,21 @@ public class CalciteQueryTest extends CalciteTestBase
   {
     testQuery(
         "SELECT "
-        + "  FLOOR(__time TO SECOND), "
         + "  AVG(m2), "
         + "  SUM(m1) + SUM(m2) "
         + "FROM "
         + "  druid.foo "
         + "WHERE "
         + "  dim2 = 'a' "
-        + "GROUP BY FLOOR(__time TO SECOND) "
-        + "ORDER BY FLOOR(__time TO SECOND) "
+        + "GROUP BY m1 "
+        + "ORDER BY m1 "
         + "LIMIT 5",
         Collections.singletonList(
             new TopNQueryBuilder()
                 .dataSource(CalciteTests.DATASOURCE1)
                 .intervals(QSS(Filtration.eternity()))
                 .granularity(Granularities.ALL)
-                .dimension(new DefaultDimensionSpec("d0:v", "d0", ValueType.LONG))
-                .virtualColumns(
-                    VirtualColumns.create(
-                        EXPRESSION_VIRTUAL_COLUMN("d0:v", "timestamp_floor(\"__time\",'PT1S','','UTC')", ValueType.LONG)
-                    )
-                )
+                .dimension(new DefaultDimensionSpec("m1", "d0", ValueType.FLOAT))
                 .filters("dim2", "a")
                 .aggregators(AGGS(
                     new DoubleSumAggregatorFactory("a0:sum", "m2"),
@@ -6814,8 +6779,8 @@ public class CalciteQueryTest extends CalciteTestBase
                 .build()
         ),
         ImmutableList.of(
-            new Object[]{946684800000L, 1.0, 2.0},
-            new Object[]{978307200000L, 4.0, 8.0}
+            new Object[]{1.0, 2.0},
+            new Object[]{4.0, 8.0}
         )
     );
   }
diff --git a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java
index c80a4d0..7ca2f3c 100644
--- a/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java
+++ b/sql/src/test/java/io/druid/sql/calcite/http/SqlResourceTest.java
@@ -235,7 +235,7 @@ public class SqlResourceTest extends CalciteTestBase
         ImmutableList.of(
             ImmutableMap.<String, Object>of(
                 "PLAN",
-                "DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"context\":{\"skipEmptyBuckets\":true}}], signature=[{a0:LONG}])\n"
+                "DruidQueryRel(query=[{\"queryType\":\"timeseries\",\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"descending\":false,\"virtualColumns\":[],\"filter\":null,\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"postAggregations\":[],\"limit\":2147483647,\"context\":{\"skipEmptyBuckets\":true}}], signature=[{a [...]
             )
         ),
         rows


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@druid.apache.org
For additional commands, e-mail: dev-help@druid.apache.org