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

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


The following commit(s) were added to refs/heads/master by this push:
     new ca94f7146f Planning correctly for order by queries on time which 
previously thre… (#13965)
ca94f7146f is described below

commit ca94f7146f50900aeab2e520bec032ad3ded4368
Author: Soumyava <[email protected]>
AuthorDate: Mon Apr 3 18:30:19 2023 -0700

    Planning correctly for order by queries on time which previously thre… 
(#13965)
    
    * Planning correctly for order by queries on time which previously threw a 
planning error
    * Updating toDruidQueryForExplaining on a query data source if there is a 
window on the partial query
---
 .../druid/sql/calcite/rel/DruidOuterQueryRel.java  |   7 +-
 .../apache/druid/sql/calcite/rel/DruidQuery.java   |  12 +--
 .../druid/sql/calcite/CalciteExplainQueryTest.java |   2 +-
 .../druid/sql/calcite/CalciteJoinQueryTest.java    |  58 ++++++++++++
 .../apache/druid/sql/calcite/CalciteQueryTest.java | 103 +++++++++++++++++++--
 5 files changed, 162 insertions(+), 20 deletions(-)

diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidOuterQueryRel.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidOuterQueryRel.java
index 3171eb58c0..c49fc6bd04 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidOuterQueryRel.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidOuterQueryRel.java
@@ -34,6 +34,7 @@ import org.apache.calcite.rel.type.RelDataType;
 import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.query.Druids;
 import org.apache.druid.query.QueryDataSource;
+import org.apache.druid.query.TableDataSource;
 import org.apache.druid.segment.column.RowSignature;
 import org.apache.druid.sql.calcite.planner.PlannerContext;
 import org.apache.druid.sql.calcite.table.RowSignatures;
@@ -46,7 +47,9 @@ import java.util.Set;
  */
 public class DruidOuterQueryRel extends DruidRel<DruidOuterQueryRel>
 {
-  private static final QueryDataSource DUMMY_DATA_SOURCE = new QueryDataSource(
+  private static final TableDataSource DUMMY_DATA_SOURCE = new 
TableDataSource("__subquery__");
+
+  private static final QueryDataSource DUMMY_QUERY_DATA_SOURCE = new 
QueryDataSource(
       
Druids.newScanQueryBuilder().dataSource("__subquery__").eternityInterval().build()
   );
 
@@ -117,7 +120,7 @@ public class DruidOuterQueryRel extends 
DruidRel<DruidOuterQueryRel>
   public DruidQuery toDruidQueryForExplaining()
   {
     return partialQuery.build(
-        DUMMY_DATA_SOURCE,
+        partialQuery.getWindow() == null ? DUMMY_DATA_SOURCE : 
DUMMY_QUERY_DATA_SOURCE,
         RowSignatures.fromRelDataType(
             sourceRel.getRowType().getFieldNames(),
             sourceRel.getRowType()
diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
index 2a093e6a30..f24f038145 100644
--- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
+++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidQuery.java
@@ -1439,7 +1439,8 @@ public class DruidQuery
     }
 
     if (!plannerContext.featureAvailable(EngineFeature.SCAN_ORDER_BY_NON_TIME) 
&& !orderByColumns.isEmpty()) {
-      if (orderByColumns.size() > 1 || 
!ColumnHolder.TIME_COLUMN_NAME.equals(orderByColumns.get(0).getColumnName())) {
+      if (orderByColumns.size() > 1 || orderByColumns.stream()
+                                                     .anyMatch(orderBy -> 
!orderBy.getColumnName().equals(ColumnHolder.TIME_COLUMN_NAME))) {
         // Cannot handle this ordering.
         // Scan cannot ORDER BY non-time columns.
         plannerContext.setPlanningError(
@@ -1448,15 +1449,6 @@ public class DruidQuery
         );
         return null;
       }
-      if (!dataSource.isConcrete()) {
-        // Cannot handle this ordering.
-        // Scan cannot ORDER BY non-concrete datasources on _any_ column.
-        plannerContext.setPlanningError(
-            "SQL query requires order by on non-concrete datasource [%s], 
which is not supported.",
-            dataSource
-        );
-        return null;
-      }
     }
 
     // Compute the list of columns to select, sorted and deduped.
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java
index 70e0320e3a..480fca6aeb 100644
--- 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java
+++ 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java
@@ -109,7 +109,7 @@ public class CalciteExplainQueryTest extends 
BaseCalciteQueryTest
                          + "  )\n"
                          + ")";
     final String legacyExplanation =
-        
"DruidOuterQueryRel(query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"query\",\"query\":{\"queryType\":\"scan\",\"dataSource\":{\"type\":\"table\",\"name\":\"__subquery__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"resultFormat\":\"list\",\"granularity\":{\"type\":\"all\"}}},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\
 [...]
+        
"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\"]},\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dum
 [...]
         + "  DruidJoinQueryRel(condition=[=(SUBSTRING($2, 1, 1), $8)], 
joinType=[inner], 
query=[{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"table\",\"name\":\"__join__\"},\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]},\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"default\",\"dimension\":\"dim2\",\"outputName\":\"d0\",\"outputType\":\"STRING\"}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"
 [...]
         + "    
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\"]},\"resultFormat\":\"compactedList\",\"columns\":[\"__time\",\"cnt\",\"dim1\",\"dim2\",\"dim3\",\"m1\",\"m2\",\"unique_dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-0
 [...]
         + "    
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\"]},\"filter\":{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":null}},\"granularity\":{\"type\":\"all\"},\"dimensions\":[{\"type\":\"extraction\",\"dimension\":\"dim1\",\"outputName\":\"d0\",\"outputType\":\"STRING\",\"extra
 [...]
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
index 32007ed7ab..be65a64e80 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteJoinQueryTest.java
@@ -5264,4 +5264,62 @@ public class CalciteJoinQueryTest extends 
BaseCalciteQueryTest
         )
     );
   }
+
+  @Test
+  public void testJoinWithAliasAndOrderByNoGroupBy()
+  {
+    minTopNThreshold = 1;
+    Map<String, Object> context = new HashMap<>(QUERY_CONTEXT_DEFAULT);
+    context.put(PlannerConfig.CTX_KEY_USE_APPROXIMATE_TOPN, false);
+    testQuery(
+        "select t1.__time from druid.foo as t1 join\n"
+        + "  druid.numfoo as t2 on t1.dim2 = t2.dim2\n"
+        + " order by t1.__time ASC ",
+        context, // turn on exact topN
+        ImmutableList.of(
+            newScanQueryBuilder()
+                .intervals(querySegmentSpec(Filtration.eternity()))
+                .dataSource(
+                    JoinDataSource.create(
+                        new TableDataSource(CalciteTests.DATASOURCE1),
+                        new QueryDataSource(
+                            newScanQueryBuilder()
+                                .dataSource(CalciteTests.DATASOURCE3)
+                                .intervals(querySegmentSpec(Intervals.of(
+                                    
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z")))
+                                .columns("dim2")
+                                .context(context)
+                                .build()
+                        ),
+                        "j0.",
+                        "(\"dim2\" == \"j0.dim2\")",
+                        JoinType.INNER,
+                        null,
+                        ExprMacroTable.nil(),
+                        CalciteTests.createJoinableFactoryWrapper()
+                    )
+                )
+                .columns("__time")
+                .order(ScanQuery.Order.ASCENDING)
+                .context(context)
+                .build()
+        ),
+        NullHandling.sqlCompatible()
+        ? ImmutableList.of(
+            new Object[]{946684800000L},
+            new Object[]{946684800000L},
+            new Object[]{946857600000L},
+            new Object[]{978307200000L},
+            new Object[]{978307200000L},
+            new Object[]{978393600000L}
+        )
+        : ImmutableList.of(
+            new Object[]{946684800000L},
+            new Object[]{946684800000L},
+            new Object[]{978307200000L},
+            new Object[]{978307200000L},
+            new Object[]{978393600000L}
+        )
+    );
+  }
 }
diff --git 
a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java 
b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
index 78e2e50f3b..f086aa8fe0 100644
--- a/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteQueryTest.java
@@ -7306,14 +7306,9 @@ public class CalciteQueryTest extends 
BaseCalciteQueryTest
                             )
                         )
                         .setInterval(querySegmentSpec(Filtration.eternity()))
-                        .setLimitSpec(
-                            new DefaultLimitSpec(
-                                ImmutableList.of(),
-                                1
-                            )
-                        )
                         .setGranularity(Granularities.ALL)
                         .setAggregatorSpecs(
+                            useDefault ?
                             aggregators(
                                 new LongMaxAggregatorFactory("_a0", "a0"),
                                 new LongMinAggregatorFactory("_a1", "a0"),
@@ -7321,6 +7316,16 @@ public class CalciteQueryTest extends 
BaseCalciteQueryTest
                                 new CountAggregatorFactory("_a2:count"),
                                 new LongMaxAggregatorFactory("_a3", "d0"),
                                 new CountAggregatorFactory("_a4")
+                            ) : aggregators(
+                                new LongMaxAggregatorFactory("_a0", "a0"),
+                                new LongMinAggregatorFactory("_a1", "a0"),
+                                new LongSumAggregatorFactory("_a2:sum", "a0"),
+                                new FilteredAggregatorFactory(
+                                    new CountAggregatorFactory("_a2:count"),
+                                    not(selector("a0", null, null))
+                                ),
+                                new LongMaxAggregatorFactory("_a3", "d0"),
+                                new CountAggregatorFactory("_a4")
                             )
                         )
                         .setPostAggregatorSpecs(
@@ -7333,7 +7338,7 @@ public class CalciteQueryTest extends BaseCalciteQueryTest
                                         new FieldAccessPostAggregator(null, 
"_a2:count")
                                     )
                                 ),
-                                expressionPostAgg("s0", 
"timestamp_extract(\"_a3\",'EPOCH','UTC')")
+                                expressionPostAgg("p0", 
"timestamp_extract(\"_a3\",'EPOCH','UTC')")
                             )
                         )
                         .setContext(QUERY_CONTEXT_DEFAULT)
@@ -14604,4 +14609,88 @@ public class CalciteQueryTest extends 
BaseCalciteQueryTest
         )
     );
   }
+
+  @Test
+  public void testOrderByAlongWithInternalScanQuery()
+  {
+    testQuery(
+        "select __time as t, m1 from druid.foo where (m1 in (select distinct 
m1 from druid.foo)) order by 1 limit 1",
+        ImmutableList.of(
+            newScanQueryBuilder()
+                .intervals(querySegmentSpec(Filtration.eternity()))
+                .dataSource(
+                    JoinDataSource.create(
+                        new TableDataSource(CalciteTests.DATASOURCE1),
+                        new QueryDataSource(
+                            GroupByQuery.builder()
+                                        .setGranularity(Granularities.ALL)
+                                        
.setDataSource(CalciteTests.DATASOURCE1)
+                                        
.setInterval(querySegmentSpec(Intervals.of(
+                                            
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z")))
+                                        .setDimensions(new 
DefaultDimensionSpec("m1", "d0", ColumnType.FLOAT))
+                                        .build()
+                        ),
+                        "j0.",
+                        "(\"m1\" == \"j0.d0\")",
+                        JoinType.INNER,
+                        null,
+                        ExprMacroTable.nil(),
+                        CalciteTests.createJoinableFactoryWrapper()
+                    )
+                )
+                .context(QUERY_CONTEXT_DEFAULT)
+                .intervals(querySegmentSpec(Intervals.of(
+                    
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z")))
+                .limit(1)
+                .columns(ImmutableList.of("__time", "m1"))
+                .order(ScanQuery.Order.ASCENDING)
+                .build()
+        ),
+        ImmutableList.of(
+            new Object[]{946684800000L, 1.0f}
+        )
+    );
+  }
+
+  @Test
+  public void testOrderByAlongWithInternalScanQueryNoDistinct()
+  {
+    testQuery(
+        "select __time, m1 from druid.foo where (m1 in (select m1 from 
druid.foo)) order by __time DESC limit 1",
+        ImmutableList.of(
+            newScanQueryBuilder()
+                .intervals(querySegmentSpec(Filtration.eternity()))
+                .dataSource(
+                    JoinDataSource.create(
+                        new TableDataSource(CalciteTests.DATASOURCE1),
+                        new QueryDataSource(
+                            GroupByQuery.builder()
+                                        .setGranularity(Granularities.ALL)
+                                        
.setDataSource(CalciteTests.DATASOURCE1)
+                                        
.setInterval(querySegmentSpec(Intervals.of(
+                                            
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z")))
+                                        .setDimensions(new 
DefaultDimensionSpec("m1", "d0", ColumnType.FLOAT))
+                                        .build()
+                        ),
+                        "j0.",
+                        "(\"m1\" == \"j0.d0\")",
+                        JoinType.INNER,
+                        null,
+                        ExprMacroTable.nil(),
+                        CalciteTests.createJoinableFactoryWrapper()
+                    )
+                )
+                .context(QUERY_CONTEXT_DEFAULT)
+                .intervals(querySegmentSpec(Intervals.of(
+                    
"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z")))
+                .limit(1)
+                .columns(ImmutableList.of("__time", "m1"))
+                .order(ScanQuery.Order.DESCENDING)
+                .build()
+        ),
+        ImmutableList.of(
+            new Object[]{978480000000L, 6.0f}
+        )
+    );
+  }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to