From b6f8d7a1b39793f7941e450925952c50e53fba9f Mon Sep 17 00:00:00 2001 From: Kashif Faraz Date: Wed, 22 Jun 2022 15:33:50 +0530 Subject: [PATCH] Add query context param `forceExpressionVirtualColumns` to always use "expression"-type virtual columns in query plan (#12583) SQL expressions such as those containing `MV_FILTER_ONLY` and `MV_FILTER_NONE` are planned as specialized virtual columns instead of the default `expression`-type virtual columns. This commit adds a new context parameter to force the `expression`-type virtual columns. Changes - Add query context param `forceExpressionVirtualColumns` - Use context param to determine if specialized virtual columns should be used or not - Moved some tests into `CalciteExplainQueryTest` --- .../calcite/expression/DruidExpression.java | 9 + .../sql/calcite/planner/PlannerConfig.java | 23 +- .../sql/calcite/rel/DruidJoinQueryRel.java | 6 +- .../druid/sql/calcite/rel/DruidQuery.java | 35 +- .../calcite/rel/VirtualColumnRegistry.java | 29 +- .../sql/calcite/CalciteExplainQueryTest.java | 368 ++++++++++++++++++ .../druid/sql/calcite/CalciteQueryTest.java | 227 ----------- .../expression/ExpressionTestHelper.java | 2 +- .../druid/sql/calcite/rel/DruidQueryTest.java | 16 +- 9 files changed, 455 insertions(+), 260 deletions(-) create mode 100644 sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/expression/DruidExpression.java b/sql/src/main/java/org/apache/druid/sql/calcite/expression/DruidExpression.java index 950fc93783c..6e043eff2bd 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/expression/DruidExpression.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/expression/DruidExpression.java @@ -387,6 +387,15 @@ public class DruidExpression return virtualColumnCreator.create(name, outputType, expression.get(), macroTable); } + public VirtualColumn toExpressionVirtualColumn( + final String name, + final ColumnType outputType, + final ExprMacroTable macroTable + ) + { + return DEFAULT_VIRTUAL_COLUMN_BUILDER.create(name, outputType, expression.get(), macroTable); + } + public NodeType getType() { return nodeType; diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerConfig.java b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerConfig.java index 836477ce835..f7ceaf51f6b 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerConfig.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/planner/PlannerConfig.java @@ -34,6 +34,7 @@ public class PlannerConfig public static final String CTX_KEY_USE_APPROXIMATE_TOPN = "useApproximateTopN"; public static final String CTX_COMPUTE_INNER_JOIN_COST_AS_FILTER = "computeInnerJoinCostAsFilter"; public static final String CTX_KEY_USE_NATIVE_QUERY_EXPLAIN = "useNativeQueryExplain"; + public static final String CTX_KEY_FORCE_EXPRESSION_VIRTUAL_COLUMNS = "forceExpressionVirtualColumns"; public static final String CTX_MAX_NUMERIC_IN_FILTERS = "maxNumericInFilters"; public static final int NUM_FILTER_NOT_USED = -1; @@ -76,6 +77,9 @@ public class PlannerConfig @JsonProperty private boolean useNativeQueryExplain = false; + @JsonProperty + private boolean forceExpressionVirtualColumns = false; + @JsonProperty private int maxNumericInFilters = NUM_FILTER_NOT_USED; @@ -156,6 +160,15 @@ public class PlannerConfig return useNativeQueryExplain; } + /** + * @return true if special virtual columns should not be optimized and should + * always be of type "expressions", false otherwise. + */ + public boolean isForceExpressionVirtualColumns() + { + return forceExpressionVirtualColumns; + } + public PlannerConfig withOverrides(final QueryContext queryContext) { if (queryContext.isEmpty()) { @@ -185,6 +198,10 @@ public class PlannerConfig CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, isUseNativeQueryExplain() ); + newConfig.forceExpressionVirtualColumns = queryContext.getAsBoolean( + CTX_KEY_FORCE_EXPRESSION_VIRTUAL_COLUMNS, + isForceExpressionVirtualColumns() + ); final int systemConfigMaxNumericInFilters = getMaxNumericInFilters(); final int queryContextMaxNumericInFilters = queryContext.getAsInt( CTX_MAX_NUMERIC_IN_FILTERS, @@ -244,7 +261,8 @@ public class PlannerConfig serializeComplexValues == that.serializeComplexValues && Objects.equals(metadataRefreshPeriod, that.metadataRefreshPeriod) && Objects.equals(sqlTimeZone, that.sqlTimeZone) && - useNativeQueryExplain == that.useNativeQueryExplain; + useNativeQueryExplain == that.useNativeQueryExplain && + forceExpressionVirtualColumns == that.forceExpressionVirtualColumns; } @Override @@ -262,7 +280,8 @@ public class PlannerConfig metadataSegmentCacheEnable, metadataSegmentPollPeriod, serializeComplexValues, - useNativeQueryExplain + useNativeQueryExplain, + forceExpressionVirtualColumns ); } diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java index 87e2e21efe0..137803bb46e 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/DruidJoinQueryRel.java @@ -163,7 +163,11 @@ public class DruidJoinQueryRel extends DruidRel final Pair prefixSignaturePair = computeJoinRowSignature(leftSignature, rightSignature); - VirtualColumnRegistry virtualColumnRegistry = VirtualColumnRegistry.create(prefixSignaturePair.rhs, getPlannerContext().getExprMacroTable()); + VirtualColumnRegistry virtualColumnRegistry = VirtualColumnRegistry.create( + prefixSignaturePair.rhs, + getPlannerContext().getExprMacroTable(), + getPlannerContext().getPlannerConfig().isForceExpressionVirtualColumns() + ); getPlannerContext().setJoinExpressionVirtualColumnRegistry(virtualColumnRegistry); // Generate the condition for this join as a Druid expression. 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 08aa08ed87b..075401eff10 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 @@ -167,7 +167,11 @@ public class DruidQuery { final RelDataType outputRowType = partialQuery.leafRel().getRowType(); if (virtualColumnRegistry == null) { - virtualColumnRegistry = VirtualColumnRegistry.create(sourceRowSignature, plannerContext.getExprMacroTable()); + virtualColumnRegistry = VirtualColumnRegistry.create( + sourceRowSignature, + plannerContext.getExprMacroTable(), + plannerContext.getPlannerConfig().isForceExpressionVirtualColumns() + ); } // Now the fun begins. @@ -634,24 +638,25 @@ public class DruidQuery // implementation can be used instead of being composed as part of some expression tree in an expresson virtual // column Set specialized = new HashSet<>(); + final boolean forceExpressionVirtualColumns = + plannerContext.getPlannerConfig().isForceExpressionVirtualColumns(); virtualColumnRegistry.visitAllSubExpressions((expression) -> { - switch (expression.getType()) { - case SPECIALIZED: - // add the expression to the top level of the registry as a standalone virtual column - final String name = virtualColumnRegistry.getOrCreateVirtualColumnForExpression( - expression, - expression.getDruidType() - ); - specialized.add(name); - // replace with an identifier expression of the new virtual column name - return DruidExpression.ofColumn(expression.getDruidType(), name); - default: - // do nothing - return expression; + if (!forceExpressionVirtualColumns + && expression.getType() == DruidExpression.NodeType.SPECIALIZED) { + // add the expression to the top level of the registry as a standalone virtual column + final String name = virtualColumnRegistry.getOrCreateVirtualColumnForExpression( + expression, + expression.getDruidType() + ); + specialized.add(name); + // replace with an identifier expression of the new virtual column name + return DruidExpression.ofColumn(expression.getDruidType(), name); + } else { + // do nothing + return expression; } }); - // we always want to add any virtual columns used by the query level DimFilter if (filter != null) { for (String columnName : filter.getRequiredColumns()) { diff --git a/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java b/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java index 6ebb9d0457c..d07586ec2fb 100644 --- a/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java +++ b/sql/src/main/java/org/apache/druid/sql/calcite/rel/VirtualColumnRegistry.java @@ -49,11 +49,13 @@ public class VirtualColumnRegistry private final Map virtualColumnsByName; private final String virtualColumnPrefix; private int virtualColumnCounter; + private boolean forceExpressionVirtualColumns; private VirtualColumnRegistry( RowSignature baseRowSignature, ExprMacroTable macroTable, String virtualColumnPrefix, + boolean forceExpressionVirtualColumns, Map virtualColumnsByExpression, Map virtualColumnsByName ) @@ -63,14 +65,20 @@ public class VirtualColumnRegistry this.virtualColumnPrefix = virtualColumnPrefix; this.virtualColumnsByExpression = virtualColumnsByExpression; this.virtualColumnsByName = virtualColumnsByName; + this.forceExpressionVirtualColumns = forceExpressionVirtualColumns; } - public static VirtualColumnRegistry create(final RowSignature rowSignature, final ExprMacroTable macroTable) + public static VirtualColumnRegistry create( + final RowSignature rowSignature, + final ExprMacroTable macroTable, + final boolean forceExpressionVirtualColumns + ) { return new VirtualColumnRegistry( rowSignature, macroTable, Calcites.findUnusedPrefixForDigits("v", rowSignature.getColumnNames()), + forceExpressionVirtualColumns, new HashMap<>(), new HashMap<>() ); @@ -124,14 +132,23 @@ public class VirtualColumnRegistry } /** - * Get existing virtual column by column name + * Get existing virtual column by column name. + * + * @return null if a virtual column for the given name does not exist. */ @Nullable public VirtualColumn getVirtualColumn(String virtualColumnName) { - return Optional.ofNullable(virtualColumnsByName.get(virtualColumnName)) - .map(v -> v.getExpression().toVirtualColumn(virtualColumnName, v.getTypeHint(), macroTable)) - .orElse(null); + ExpressionAndTypeHint registeredColumn = virtualColumnsByName.get(virtualColumnName); + if (registeredColumn == null) { + return null; + } + + DruidExpression expression = registeredColumn.getExpression(); + ColumnType columnType = registeredColumn.getTypeHint(); + return forceExpressionVirtualColumns + ? expression.toExpressionVirtualColumn(virtualColumnName, columnType, macroTable) + : expression.toVirtualColumn(virtualColumnName, columnType, macroTable); } @Nullable @@ -223,7 +240,7 @@ public class VirtualColumnRegistry ) { final String name = getOrCreateVirtualColumnForExpression(expression, valueType); - return virtualColumnsByName.get(name).expression.toVirtualColumn(name, valueType, macroTable); + return getVirtualColumn(name); } /** 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 new file mode 100644 index 00000000000..f07f60980d5 --- /dev/null +++ b/sql/src/test/java/org/apache/druid/sql/calcite/CalciteExplainQueryTest.java @@ -0,0 +1,368 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.druid.sql.calcite; + +import com.google.common.collect.ImmutableList; +import org.apache.druid.sql.calcite.planner.PlannerConfig; +import org.apache.druid.sql.calcite.util.CalciteTests; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +/** + * Unit tests for EXPLAIN PLAN queries. + */ +public class CalciteExplainQueryTest extends BaseCalciteQueryTest +{ + @Test + public void testExplainCountStarOnView() throws Exception + { + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + + final String query = "EXPLAIN PLAN FOR SELECT COUNT(*) FROM view.aview WHERE dim1_firstchar <> 'z'"; + final String legacyExplanation = "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\"]},\"filter\":{\"type\":\"and\",\"fields\":[{\"type\":\"selector\",\"dimension\":\"dim2\",\"value\":\"a\"},{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"z\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}}]},\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{a0:LONG}])\n"; + final String explanation = "[{" + + "\"query\":{\"queryType\":\"timeseries\"," + + "\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"}," + + "\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]}," + + "\"filter\":{\"type\":\"and\",\"fields\":[{\"type\":\"selector\",\"dimension\":\"dim2\",\"value\":\"a\"},{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"z\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}}]}," + + "\"granularity\":{\"type\":\"all\"}," + + "\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}]," + + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}," + + "\"signature\":[{\"name\":\"a0\",\"type\":\"LONG\"}]" + + "}]"; + final String resources = "[{\"name\":\"aview\",\"type\":\"VIEW\"}]"; + + testQuery( + query, + ImmutableList.of(), + ImmutableList.of( + new Object[]{legacyExplanation, resources} + ) + ); + testQuery( + PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, + query, + CalciteTests.REGULAR_USER_AUTH_RESULT, + ImmutableList.of(), + ImmutableList.of( + new Object[]{explanation, resources} + ) + ); + } + + @Test + public void testExplainInformationSchemaColumns() throws Exception + { + final String explanation = + "BindableProject(COLUMN_NAME=[$3], DATA_TYPE=[$7])\n" + + " BindableFilter(condition=[AND(=($1, 'druid'), =($2, 'foo'))])\n" + + " BindableTableScan(table=[[INFORMATION_SCHEMA, COLUMNS]])\n"; + + final String resources = "[]"; + + testQuery( + "EXPLAIN PLAN FOR\n" + + "SELECT COLUMN_NAME, DATA_TYPE\n" + + "FROM INFORMATION_SCHEMA.COLUMNS\n" + + "WHERE TABLE_SCHEMA = 'druid' AND TABLE_NAME = 'foo'", + ImmutableList.of(), + ImmutableList.of( + new Object[]{explanation, resources} + ) + ); + } + + @Test + public void testExplainExactCountDistinctOfSemiJoinResult() throws Exception + { + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + + final String query = "EXPLAIN PLAN FOR SELECT COUNT(*)\n" + + "FROM (\n" + + " SELECT DISTINCT dim2\n" + + " FROM druid.foo\n" + + " WHERE SUBSTRING(dim2, 1, 1) IN (\n" + + " SELECT SUBSTRING(dim1, 1, 1) FROM druid.foo WHERE dim1 IS NOT NULL\n" + + " )\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\"]},\"granularity\":{\"type\":\"all\"},\"dimensions\":[],\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{a0:LONG}])\n" + + " DruidJoinQueryRel(condition=[=(SUBSTRING($3, 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\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{d0:STRING}])\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\"]},\"resultFormat\":\"compactedList\",\"columns\":[\"__time\",\"cnt\",\"dim1\",\"dim2\",\"dim3\",\"m1\",\"m2\",\"unique_dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n" + + " 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\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{d0:STRING}])\n"; + final String explanation = "[" + + "{\"query\":{\"queryType\":\"groupBy\"," + + "\"dataSource\":{\"type\":\"query\",\"query\":{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"join\",\"left\":{\"type\":\"table\",\"name\":\"foo\"},\"right\":{\"type\":\"query\",\"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\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}},\"rightPrefix\":\"j0.\",\"condition\":\"(substring(\\\"dim2\\\", 0, 1) == \\\"j0.d0\\\")\",\"joinType\":\"INNER\"},\"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\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}}," + + "\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]}," + + "\"granularity\":{\"type\":\"all\"}," + + "\"dimensions\":[]," + + "\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}]," + + "\"limitSpec\":{\"type\":\"NoopLimitSpec\"}," + + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}," + + "\"signature\":[{\"name\":\"a0\",\"type\":\"LONG\"}]" + + "}]"; + final String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; + + testQuery( + query, + ImmutableList.of(), + ImmutableList.of(new Object[]{legacyExplanation, resources}) + ); + + testQuery( + PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, + query, + CalciteTests.REGULAR_USER_AUTH_RESULT, + ImmutableList.of(), + ImmutableList.of(new Object[]{explanation, resources}) + ); + } + + // This testcase has been added here and not in CalciteSelectQueryTests since this checks if the overrides are working + // properly when displaying the output of "EXPLAIN PLAN FOR ..." queries + @Test + public void testExplainSelectStarWithOverrides() throws Exception + { + Map useRegularExplainContext = new HashMap<>(QUERY_CONTEXT_DEFAULT); + useRegularExplainContext.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, false); + + Map useNativeQueryExplain = new HashMap<>(QUERY_CONTEXT_DEFAULT); + useNativeQueryExplain.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, true); + + + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + String legacyExplanation = "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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n"; + String legacyExplanationWithContext = "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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":false},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n"; + String explanation = "[{" + + "\"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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," + + "\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"__time\",\"type\":\"LONG\"},{\"name\":\"cnt\",\"type\":\"LONG\"},{\"name\":\"dim1\",\"type\":\"STRING\"},{\"name\":\"dim2\",\"type\":\"STRING\"},{\"name\":\"dim3\",\"type\":\"STRING\"},{\"name\":\"m1\",\"type\":\"FLOAT\"},{\"name\":\"m2\",\"type\":\"DOUBLE\"},{\"name\":\"unique_dim1\",\"type\":\"COMPLEX\"}]" + + "}]"; + + String explanationWithContext = "[{" + + "\"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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":true,\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," + + "\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"__time\",\"type\":\"LONG\"},{\"name\":\"cnt\",\"type\":\"LONG\"},{\"name\":\"dim1\",\"type\":\"STRING\"},{\"name\":\"dim2\",\"type\":\"STRING\"},{\"name\":\"dim3\",\"type\":\"STRING\"},{\"name\":\"m1\",\"type\":\"FLOAT\"},{\"name\":\"m2\",\"type\":\"DOUBLE\"},{\"name\":\"unique_dim1\",\"type\":\"COMPLEX\"}]" + + "}]"; + String sql = "EXPLAIN PLAN FOR SELECT * FROM druid.foo"; + String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; + + // Test when default config and no overrides + testQuery(sql, ImmutableList.of(), ImmutableList.of(new Object[]{legacyExplanation, resources})); + + // Test when default config and useNativeQueryExplain is overridden in the context + testQuery( + sql, + useNativeQueryExplain, + ImmutableList.of(), + ImmutableList.of(new Object[]{explanationWithContext, resources}) + ); + + // Test when useNativeQueryExplain enabled by default and no overrides + testQuery( + PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, + sql, + CalciteTests.REGULAR_USER_AUTH_RESULT, + ImmutableList.of(), + ImmutableList.of(new Object[]{explanation, resources}) + ); + + // Test when useNativeQueryExplain enabled by default but is overriden in the context + testQuery( + PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, + useRegularExplainContext, + sql, + CalciteTests.REGULAR_USER_AUTH_RESULT, + ImmutableList.of(), + ImmutableList.of(new Object[]{legacyExplanationWithContext, resources}) + ); + } + + @Test + public void testExplainMultipleTopLevelUnionAllQueries() throws Exception + { + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + + final String query = "EXPLAIN PLAN FOR SELECT dim1 FROM druid.foo\n" + + "UNION ALL (SELECT dim1 FROM druid.foo WHERE dim1 = '42'\n" + + "UNION ALL SELECT dim1 FROM druid.foo WHERE dim1 = '44')"; + final String legacyExplanation = "DruidUnionRel(limit=[-1])\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\"]},\"resultFormat\":\"compactedList\",\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\n" + + " DruidUnionRel(limit=[-1])\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\"]},\"resultFormat\":\"compactedList\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"42\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\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\"]},\"resultFormat\":\"compactedList\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"44\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\n"; + final String explanation = "[" + + "{" + + "\"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\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" + + "}," + + "{" + + "\"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\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"42\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" + + "}," + + "{" + + "\"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\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"44\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" + + "}]"; + final String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; + + testQuery( + query, + ImmutableList.of(), + ImmutableList.of( + new Object[]{legacyExplanation, resources} + ) + ); + testQuery( + PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, + query, + CalciteTests.REGULAR_USER_AUTH_RESULT, + ImmutableList.of(), + ImmutableList.of( + new Object[]{explanation, resources} + ) + ); + } + + @Test + public void testExplainSelectMvfilterExpressions() throws Exception + { + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + + final String explainSql = "EXPLAIN PLAN FOR SELECT" + + " MV_FILTER_ONLY(\"dim1\", ARRAY['true', 'false'])," + + " MV_FILTER_NONE(\"dim1\", ARRAY['true', 'false'])" + + " FROM druid.foo"; + + // Test plan as default expressions + final Map defaultExprContext = new HashMap<>(QUERY_CONTEXT_DEFAULT); + defaultExprContext.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, true); + defaultExprContext.put(PlannerConfig.CTX_KEY_FORCE_EXPRESSION_VIRTUAL_COLUMNS, true); + + final String expectedPlanWithDefaultExpressions = "[{" + + "\"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\":[" + + "{\"type\":\"expression\",\"name\":\"v0\",\"expression\":\"filter((x) -> array_contains(array('true','false'), x), \\\"dim1\\\")\",\"outputType\":\"STRING\"}," + + "{\"type\":\"expression\",\"name\":\"v1\",\"expression\":\"filter((x) -> !array_contains(array('true','false'), x), \\\"dim1\\\")\",\"outputType\":\"STRING\"}" + + "]," + + "\"resultFormat\":\"compactedList\"," + + "\"columns\":[\"v0\",\"v1\"]," + + "\"legacy\":false," + + "\"context\":{\"defaultTimeout\":300000,\"forceExpressionVirtualColumns\":true,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":true,\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," + + "\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"v0\",\"type\":\"STRING\"},{\"name\":\"v1\",\"type\":\"STRING\"}]" + + "}]"; + final String expectedResources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; + + testQuery( + explainSql, + defaultExprContext, + ImmutableList.of(), + ImmutableList.of(new Object[]{expectedPlanWithDefaultExpressions, expectedResources}) + ); + + // Test plan as mv-filtered virtual columns + final String expectedPlanWithMvfiltered = "[{" + + "\"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\":[" + + "{\"type\":\"mv-filtered\",\"name\":\"v0\",\"delegate\":{\"type\":\"default\",\"dimension\":\"dim1\",\"outputName\":\"dim1\",\"outputType\":\"STRING\"},\"values\":[\"true\",\"false\"],\"isAllowList\":true}," + + "{\"type\":\"mv-filtered\",\"name\":\"v1\",\"delegate\":{\"type\":\"default\",\"dimension\":\"dim1\",\"outputName\":\"dim1\",\"outputType\":\"STRING\"},\"values\":[\"true\",\"false\"],\"isAllowList\":false}" + + "]," + + "\"resultFormat\":\"compactedList\"," + + "\"columns\":[\"v0\",\"v1\"]," + + "\"legacy\":false," + + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":true,\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," + + "\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"v0\",\"type\":\"STRING\"},{\"name\":\"v1\",\"type\":\"STRING\"}]" + + "}]"; + + final Map mvFilteredContext = new HashMap<>(QUERY_CONTEXT_DEFAULT); + mvFilteredContext.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, true); + + testQuery( + explainSql, + mvFilteredContext, + ImmutableList.of(), + ImmutableList.of(new Object[]{expectedPlanWithMvfiltered, expectedResources}) + ); + } + + @Test + public void testExplainSelectTimestampExpression() throws Exception + { + // Skip vectorization since otherwise the "context" will change for each subtest. + skipVectorize(); + + final String explainSql = "EXPLAIN PLAN FOR SELECT" + + " TIME_PARSE(dim1)" + + " FROM druid.foo"; + + final Map queryContext = new HashMap<>(QUERY_CONTEXT_DEFAULT); + queryContext.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, true); + + final String expectedPlan = "[{" + + "\"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\":[" + + "{\"type\":\"expression\",\"name\":\"v0\",\"expression\":\"timestamp_parse(\\\"dim1\\\",null,'UTC')\",\"outputType\":\"LONG\"}" + + "]," + + "\"resultFormat\":\"compactedList\"," + + "\"columns\":[\"v0\"]," + + "\"legacy\":false," + + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":true,\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," + + "\"granularity\":{\"type\":\"all\"}}," + + "\"signature\":[{\"name\":\"v0\",\"type\":\"LONG\"}]" + + "}]"; + final String expectedResources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; + + // Verify the query plan + testQuery( + explainSql, + queryContext, + ImmutableList.of(), + ImmutableList.of(new Object[]{expectedPlan, expectedResources}) + ); + } + +} 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 7aef54503f7..15680504c6d 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 @@ -353,28 +353,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest ); } - @Test - public void testExplainInformationSchemaColumns() throws Exception - { - final String explanation = - "BindableProject(COLUMN_NAME=[$3], DATA_TYPE=[$7])\n" - + " BindableFilter(condition=[AND(=($1, 'druid'), =($2, 'foo'))])\n" - + " BindableTableScan(table=[[INFORMATION_SCHEMA, COLUMNS]])\n"; - - final String resources = "[]"; - - testQuery( - "EXPLAIN PLAN FOR\n" - + "SELECT COLUMN_NAME, DATA_TYPE\n" - + "FROM INFORMATION_SCHEMA.COLUMNS\n" - + "WHERE TABLE_SCHEMA = 'druid' AND TABLE_NAME = 'foo'", - ImmutableList.of(), - ImmutableList.of( - new Object[]{explanation, resources} - ) - ); - } - @Test public void testAggregatorsOnInformationSchemaColumns() throws Exception { @@ -4361,44 +4339,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest ); } - @Test - public void testExplainCountStarOnView() throws Exception - { - // Skip vectorization since otherwise the "context" will change for each subtest. - skipVectorize(); - - final String query = "EXPLAIN PLAN FOR SELECT COUNT(*) FROM view.aview WHERE dim1_firstchar <> 'z'"; - final String legacyExplanation = "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\"]},\"filter\":{\"type\":\"and\",\"fields\":[{\"type\":\"selector\",\"dimension\":\"dim2\",\"value\":\"a\"},{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"z\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}}]},\"granularity\":{\"type\":\"all\"},\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{a0:LONG}])\n"; - final String explanation = "[{" - + "\"query\":{\"queryType\":\"timeseries\"," - + "\"dataSource\":{\"type\":\"table\",\"name\":\"foo\"}," - + "\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]}," - + "\"filter\":{\"type\":\"and\",\"fields\":[{\"type\":\"selector\",\"dimension\":\"dim2\",\"value\":\"a\"},{\"type\":\"not\",\"field\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"z\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}}]}," - + "\"granularity\":{\"type\":\"all\"}," - + "\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}]," - + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}," - + "\"signature\":[{\"name\":\"a0\",\"type\":\"LONG\"}]" - + "}]"; - final String resources = "[{\"name\":\"aview\",\"type\":\"VIEW\"}]"; - - testQuery( - query, - ImmutableList.of(), - ImmutableList.of( - new Object[]{legacyExplanation, resources} - ) - ); - testQuery( - PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, - query, - CalciteTests.REGULAR_USER_AUTH_RESULT, - ImmutableList.of(), - ImmutableList.of( - new Object[]{explanation, resources} - ) - ); - } - @Test public void testCountStarWithLikeFilter() throws Exception { @@ -7193,173 +7133,6 @@ public class CalciteQueryTest extends BaseCalciteQueryTest ); } - @Test - public void testExplainExactCountDistinctOfSemiJoinResult() throws Exception - { - // Skip vectorization since otherwise the "context" will change for each subtest. - skipVectorize(); - - final String query = "EXPLAIN PLAN FOR SELECT COUNT(*)\n" - + "FROM (\n" - + " SELECT DISTINCT dim2\n" - + " FROM druid.foo\n" - + " WHERE SUBSTRING(dim2, 1, 1) IN (\n" - + " SELECT SUBSTRING(dim1, 1, 1) FROM druid.foo WHERE dim1 IS NOT NULL\n" - + " )\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\"]},\"granularity\":{\"type\":\"all\"},\"dimensions\":[],\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{a0:LONG}])\n" - + " DruidJoinQueryRel(condition=[=(SUBSTRING($3, 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\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{d0:STRING}])\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\"]},\"resultFormat\":\"compactedList\",\"columns\":[\"__time\",\"cnt\",\"dim1\",\"dim2\",\"dim3\",\"m1\",\"m2\",\"unique_dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n" - + " 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\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}], signature=[{d0:STRING}])\n"; - final String explanation = "[" - + "{\"query\":{\"queryType\":\"groupBy\"," - + "\"dataSource\":{\"type\":\"query\",\"query\":{\"queryType\":\"groupBy\",\"dataSource\":{\"type\":\"join\",\"left\":{\"type\":\"table\",\"name\":\"foo\"},\"right\":{\"type\":\"query\",\"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\",\"extractionFn\":{\"type\":\"substring\",\"index\":0,\"length\":1}}],\"limitSpec\":{\"type\":\"NoopLimitSpec\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}},\"rightPrefix\":\"j0.\",\"condition\":\"(substring(\\\"dim2\\\", 0, 1) == \\\"j0.d0\\\")\",\"joinType\":\"INNER\"},\"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\"},\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}}," - + "\"intervals\":{\"type\":\"intervals\",\"intervals\":[\"-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z\"]}," - + "\"granularity\":{\"type\":\"all\"}," - + "\"dimensions\":[]," - + "\"aggregations\":[{\"type\":\"count\",\"name\":\"a0\"}]," - + "\"limitSpec\":{\"type\":\"NoopLimitSpec\"}," - + "\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}}," - + "\"signature\":[{\"name\":\"a0\",\"type\":\"LONG\"}]" - + "}]"; - final String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; - - testQuery( - query, - ImmutableList.of(), - ImmutableList.of(new Object[]{legacyExplanation, resources}) - ); - - testQuery( - PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, - query, - CalciteTests.REGULAR_USER_AUTH_RESULT, - ImmutableList.of(), - ImmutableList.of(new Object[]{explanation, resources}) - ); - } - - // This testcase has been added here and not in CalciteSelectQueryTests since this checks if the overrides are working - // properly when displaying the output of "EXPLAIN PLAN FOR ..." queries - @Test - public void testExplainSelectStarWithOverrides() throws Exception - { - Map useRegularExplainContext = new HashMap<>(QUERY_CONTEXT_DEFAULT); - useRegularExplainContext.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, false); - - Map useNativeQueryExplain = new HashMap<>(QUERY_CONTEXT_DEFAULT); - useNativeQueryExplain.put(PlannerConfig.CTX_KEY_USE_NATIVE_QUERY_EXPLAIN, true); - - - // Skip vectorization since otherwise the "context" will change for each subtest. - skipVectorize(); - String legacyExplanation = "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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n"; - String legacyExplanationWithContext = "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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":false},\"granularity\":{\"type\":\"all\"}}], signature=[{__time:LONG, cnt:LONG, dim1:STRING, dim2:STRING, dim3:STRING, m1:FLOAT, m2:DOUBLE, unique_dim1:COMPLEX}])\n"; - String explanation = "[{" - + "\"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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," - + "\"granularity\":{\"type\":\"all\"}}," - + "\"signature\":[{\"name\":\"__time\",\"type\":\"LONG\"},{\"name\":\"cnt\",\"type\":\"LONG\"},{\"name\":\"dim1\",\"type\":\"STRING\"},{\"name\":\"dim2\",\"type\":\"STRING\"},{\"name\":\"dim3\",\"type\":\"STRING\"},{\"name\":\"m1\",\"type\":\"FLOAT\"},{\"name\":\"m2\",\"type\":\"DOUBLE\"},{\"name\":\"unique_dim1\",\"type\":\"COMPLEX\"}]" - + "}]"; - - String explanationWithContext = "[{" - + "\"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-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"useNativeQueryExplain\":true,\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"}," - + "\"granularity\":{\"type\":\"all\"}}," - + "\"signature\":[{\"name\":\"__time\",\"type\":\"LONG\"},{\"name\":\"cnt\",\"type\":\"LONG\"},{\"name\":\"dim1\",\"type\":\"STRING\"},{\"name\":\"dim2\",\"type\":\"STRING\"},{\"name\":\"dim3\",\"type\":\"STRING\"},{\"name\":\"m1\",\"type\":\"FLOAT\"},{\"name\":\"m2\",\"type\":\"DOUBLE\"},{\"name\":\"unique_dim1\",\"type\":\"COMPLEX\"}]" - + "}]"; - String sql = "EXPLAIN PLAN FOR SELECT * FROM druid.foo"; - String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; - - // Test when default config and no overrides - testQuery(sql, ImmutableList.of(), ImmutableList.of(new Object[]{legacyExplanation, resources})); - - // Test when default config and useNativeQueryExplain is overridden in the context - testQuery( - sql, - useNativeQueryExplain, - ImmutableList.of(), - ImmutableList.of(new Object[]{explanationWithContext, resources}) - ); - - // Test when useNativeQueryExplain enabled by default and no overrides - testQuery( - PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, - sql, - CalciteTests.REGULAR_USER_AUTH_RESULT, - ImmutableList.of(), - ImmutableList.of(new Object[]{explanation, resources}) - ); - - // Test when useNativeQueryExplain enabled by default but is overriden in the context - testQuery( - PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, - useRegularExplainContext, - sql, - CalciteTests.REGULAR_USER_AUTH_RESULT, - ImmutableList.of(), - ImmutableList.of(new Object[]{legacyExplanationWithContext, resources}) - ); - } - - @Test - public void testExplainMultipleTopLevelUnionAllQueries() throws Exception - { - // Skip vectorization since otherwise the "context" will change for each subtest. - skipVectorize(); - - final String query = "EXPLAIN PLAN FOR SELECT dim1 FROM druid.foo\n" - + "UNION ALL (SELECT dim1 FROM druid.foo WHERE dim1 = '42'\n" - + "UNION ALL SELECT dim1 FROM druid.foo WHERE dim1 = '44')"; - final String legacyExplanation = "DruidUnionRel(limit=[-1])\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\"]},\"resultFormat\":\"compactedList\",\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\n" - + " DruidUnionRel(limit=[-1])\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\"]},\"resultFormat\":\"compactedList\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"42\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\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\"]},\"resultFormat\":\"compactedList\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"44\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}], signature=[{dim1:STRING}])\n"; - final String explanation = "[" - + "{" - + "\"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\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," - + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" - + "}," - + "{" - + "\"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\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"42\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," - + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" - + "}," - + "{" - + "\"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\",\"filter\":{\"type\":\"selector\",\"dimension\":\"dim1\",\"value\":\"44\"},\"columns\":[\"dim1\"],\"legacy\":false,\"context\":{\"defaultTimeout\":300000,\"maxScatterGatherBytes\":9223372036854775807,\"sqlCurrentTimestamp\":\"2000-01-01T00:00:00Z\",\"sqlQueryId\":\"dummy\",\"vectorize\":\"false\",\"vectorizeVirtualColumns\":\"false\"},\"granularity\":{\"type\":\"all\"}}," - + "\"signature\":[{\"name\":\"dim1\",\"type\":\"STRING\"}]" - + "}]"; - final String resources = "[{\"name\":\"foo\",\"type\":\"DATASOURCE\"}]"; - - testQuery( - query, - ImmutableList.of(), - ImmutableList.of( - new Object[]{legacyExplanation, resources} - ) - ); - testQuery( - PLANNER_CONFIG_NATIVE_QUERY_EXPLAIN, - query, - CalciteTests.REGULAR_USER_AUTH_RESULT, - ImmutableList.of(), - ImmutableList.of( - new Object[]{explanation, resources} - ) - ); - } - @Test public void testExactCountDistinctUsingSubqueryWithWherePushDown() throws Exception { diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java index df5002983df..3117610ec8d 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/expression/ExpressionTestHelper.java @@ -317,7 +317,7 @@ class ExpressionTestHelper ) { final RexNode rexNode = rexBuilder.makeCall(op, exprs); - final VirtualColumnRegistry virtualColumnRegistry = VirtualColumnRegistry.create(rowSignature, TestExprMacroTable.INSTANCE); + final VirtualColumnRegistry virtualColumnRegistry = VirtualColumnRegistry.create(rowSignature, TestExprMacroTable.INSTANCE, false); final DimFilter filter = Expressions.toFilter(PLANNER_CONTEXT, rowSignature, virtualColumnRegistry, rexNode); Assert.assertEquals("Filter for: " + rexNode, expectedFilter, filter); diff --git a/sql/src/test/java/org/apache/druid/sql/calcite/rel/DruidQueryTest.java b/sql/src/test/java/org/apache/druid/sql/calcite/rel/DruidQueryTest.java index 61a4118a1d0..68edf3f1f28 100644 --- a/sql/src/test/java/org/apache/druid/sql/calcite/rel/DruidQueryTest.java +++ b/sql/src/test/java/org/apache/druid/sql/calcite/rel/DruidQueryTest.java @@ -62,7 +62,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, selectorFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, dataSource, selectorFilter, Intervals.ETERNITY); } @@ -74,7 +74,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, filterWithInterval, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, dataSource, selectorFilter, Intervals.utc(100, 200)); } @@ -86,7 +86,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, filterWithInterval, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, dataSource, selectorFilter, Intervals.utc(100, 200)); } @@ -99,7 +99,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, otherFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, expectedDataSource, otherFilter, Intervals.utc(100, 200)); } @@ -112,7 +112,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, otherFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, expectedDataSource, otherFilter, Intervals.utc(100, 200)); } @@ -125,7 +125,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, otherFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, expectedDataSource, otherFilter, Intervals.utc(100, 200)); } @@ -138,7 +138,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, otherFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, expectedDataSource, otherFilter, Intervals.utc(100, 200)); } @@ -156,7 +156,7 @@ public class DruidQueryTest Pair pair = DruidQuery.getFiltration( dataSource, queryFilter, - VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE) + VirtualColumnRegistry.create(RowSignature.empty(), TestExprMacroTable.INSTANCE, false) ); verify(pair, expectedDataSource, otherFilter, Intervals.utc(150, 200)); }