This is an automated email from the ASF dual-hosted git repository.
jackie pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git
The following commit(s) were added to refs/heads/master by this push:
new 82252ed843 [Clean up] Do not count DISTINCT as aggregation (#10985)
82252ed843 is described below
commit 82252ed84340627223258ba1aaeb1b372a86c2f9
Author: Xiaotian (Jackie) Jiang <[email protected]>
AuthorDate: Wed Jun 28 13:07:25 2023 -0700
[Clean up] Do not count DISTINCT as aggregation (#10985)
---
.../pinot/sql/parsers/CalciteSqlCompilerTest.java | 12 +-
.../blocks/results/DistinctResultsBlock.java | 5 +-
.../operator/blocks/results/ResultsBlockUtils.java | 29 ++--
.../query/DictionaryBasedDistinctOperator.java | 122 ++++++----------
.../core/operator/query/DistinctOperator.java | 29 ++--
.../apache/pinot/core/plan/DistinctPlanNode.java | 31 ++--
.../function/AggregationFunctionFactory.java | 26 ++--
.../function/DistinctAggregationFunction.java | 161 ---------------------
.../query/distinct/DistinctExecutorFactory.java | 17 ++-
.../core/query/reduce/BaseGapfillProcessor.java | 6 +-
.../query/reduce/DistinctDataTableReducer.java | 23 +--
.../pinot/core/query/reduce/GapfillProcessor.java | 2 +-
.../core/query/reduce/ResultReducerFactory.java | 24 +--
.../core/query/request/context/QueryContext.java | 40 +++--
.../context/utils/QueryContextConverterUtils.java | 46 +++---
.../request/context/utils/QueryContextUtils.java | 16 +-
.../function/AggregationFunctionFactoryTest.java | 157 +++++++++-----------
.../BrokerRequestToQueryContextConverterTest.java | 44 +++---
.../query/parser/CalciteRexExpressionParser.java | 3 +-
.../LeafStageTransferableBlockOperatorTest.java | 11 +-
.../pinot/segment/spi/AggregationFunctionType.java | 1 -
21 files changed, 281 insertions(+), 524 deletions(-)
diff --git
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
index fd6c3b6ac3..891151f17c 100644
---
a/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
+++
b/pinot-common/src/test/java/org/apache/pinot/sql/parsers/CalciteSqlCompilerTest.java
@@ -1062,7 +1062,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
Function distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 1);
Identifier c1 = distinctFunction.getOperands().get(0).getIdentifier();
@@ -1076,7 +1076,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 2);
c1 = distinctFunction.getOperands().get(0).getIdentifier();
@@ -1093,7 +1093,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 3);
final Expression filter = pinotQuery.getFilterExpression();
@@ -1210,7 +1210,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 1);
Function add = distinctFunction.getOperands().get(0).getFunctionCall();
@@ -1229,7 +1229,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 2);
// check for DISTINCT's first operand ADD(....)
@@ -1272,7 +1272,7 @@ public class CalciteSqlCompilerTest {
Assert.assertEquals(selectListExpressions.get(0).getType(),
ExpressionType.FUNCTION);
distinctFunction = selectListExpressions.get(0).getFunctionCall();
- Assert.assertEquals(distinctFunction.getOperator(),
AggregationFunctionType.DISTINCT.getName());
+ Assert.assertEquals(distinctFunction.getOperator(), "distinct");
Assert.assertEquals(distinctFunction.getOperands().size(), 4);
// check for DISTINCT's first operand ADD(....)
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/DistinctResultsBlock.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/DistinctResultsBlock.java
index 0cbeebd176..b1d4fc3ade 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/DistinctResultsBlock.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/DistinctResultsBlock.java
@@ -25,7 +25,6 @@ import java.util.List;
import org.apache.pinot.common.datatable.DataTable;
import org.apache.pinot.common.utils.DataSchema;
import org.apache.pinot.core.data.table.Record;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctTable;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.core.query.selection.SelectionOperatorUtils;
@@ -35,11 +34,9 @@ import
org.apache.pinot.core.query.selection.SelectionOperatorUtils;
* Results block for distinct queries.
*/
public class DistinctResultsBlock extends BaseResultsBlock {
- private final DistinctAggregationFunction _distinctFunction;
private DistinctTable _distinctTable;
- public DistinctResultsBlock(DistinctAggregationFunction distinctFunction,
DistinctTable distinctTable) {
- _distinctFunction = distinctFunction;
+ public DistinctResultsBlock(DistinctTable distinctTable) {
_distinctTable = distinctTable;
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/ResultsBlockUtils.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/ResultsBlockUtils.java
index f760920923..ed59ffbcc6 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/ResultsBlockUtils.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/blocks/results/ResultsBlockUtils.java
@@ -29,7 +29,6 @@ import org.apache.pinot.common.utils.DataSchema;
import org.apache.pinot.common.utils.DataSchema.ColumnDataType;
import org.apache.pinot.core.query.aggregation.function.AggregationFunction;
import
org.apache.pinot.core.query.aggregation.function.AggregationFunctionUtils;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctTable;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.core.query.request.context.utils.QueryContextUtils;
@@ -43,16 +42,16 @@ public class ResultsBlockUtils {
public static BaseResultsBlock buildEmptyQueryResults(QueryContext
queryContext) {
if (QueryContextUtils.isSelectionQuery(queryContext)) {
return buildEmptySelectionQueryResults(queryContext);
- } else if (QueryContextUtils.isAggregationQuery(queryContext)) {
+ }
+ if (QueryContextUtils.isAggregationQuery(queryContext)) {
if (queryContext.getGroupByExpressions() == null) {
return buildEmptyAggregationQueryResults(queryContext);
} else {
return buildEmptyGroupByQueryResults(queryContext);
}
- } else {
- assert QueryContextUtils.isDistinctQuery(queryContext);
- return buildEmptyDistinctQueryResults(queryContext);
}
+ assert QueryContextUtils.isDistinctQuery(queryContext);
+ return buildEmptyDistinctQueryResults(queryContext);
}
private static SelectionResultsBlock
buildEmptySelectionQueryResults(QueryContext queryContext) {
@@ -105,17 +104,17 @@ public class ResultsBlockUtils {
}
private static DistinctResultsBlock
buildEmptyDistinctQueryResults(QueryContext queryContext) {
- AggregationFunction[] aggregationFunctions =
queryContext.getAggregationFunctions();
- assert aggregationFunctions != null && aggregationFunctions.length == 1
- && aggregationFunctions[0] instanceof DistinctAggregationFunction;
- DistinctAggregationFunction distinctAggregationFunction =
(DistinctAggregationFunction) aggregationFunctions[0];
- String[] columnNames = distinctAggregationFunction.getColumns();
- ColumnDataType[] columnDataTypes = new ColumnDataType[columnNames.length];
+ List<ExpressionContext> expressions = queryContext.getSelectExpressions();
+ int numExpressions = expressions.size();
+ String[] columns = new String[numExpressions];
+ for (int i = 0; i < numExpressions; i++) {
+ columns[i] = expressions.get(i).toString();
+ }
+ ColumnDataType[] columnDataTypes = new ColumnDataType[numExpressions];
// NOTE: Use STRING column data type as default for distinct query
Arrays.fill(columnDataTypes, ColumnDataType.STRING);
- DistinctTable distinctTable =
- new DistinctTable(new DataSchema(columnNames, columnDataTypes),
Collections.emptySet(),
- queryContext.isNullHandlingEnabled());
- return new DistinctResultsBlock(distinctAggregationFunction,
distinctTable);
+ DistinctTable distinctTable = new DistinctTable(new DataSchema(columns,
columnDataTypes), Collections.emptySet(),
+ queryContext.isNullHandlingEnabled());
+ return new DistinctResultsBlock(distinctTable);
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DictionaryBasedDistinctOperator.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DictionaryBasedDistinctOperator.java
index edb5f8a109..2ab339cb21 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DictionaryBasedDistinctOperator.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DictionaryBasedDistinctOperator.java
@@ -21,7 +21,6 @@ package org.apache.pinot.core.operator.query;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
-import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.OrderByExpressionContext;
import org.apache.pinot.common.utils.DataSchema;
import org.apache.pinot.core.common.Operator;
@@ -29,11 +28,11 @@ import org.apache.pinot.core.data.table.Record;
import org.apache.pinot.core.operator.BaseOperator;
import org.apache.pinot.core.operator.ExecutionStatistics;
import org.apache.pinot.core.operator.blocks.results.DistinctResultsBlock;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctTable;
-import org.apache.pinot.segment.spi.AggregationFunctionType;
+import org.apache.pinot.core.query.request.context.QueryContext;
+import org.apache.pinot.segment.spi.datasource.DataSource;
+import org.apache.pinot.segment.spi.datasource.DataSourceMetadata;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
-import org.apache.pinot.spi.data.FieldSpec;
import org.apache.pinot.spi.trace.Tracing;
@@ -43,103 +42,77 @@ import org.apache.pinot.spi.trace.Tracing;
public class DictionaryBasedDistinctOperator extends
BaseOperator<DistinctResultsBlock> {
private static final String EXPLAIN_NAME = "DISTINCT_DICTIONARY";
- private final DistinctAggregationFunction _distinctAggregationFunction;
- private final Dictionary _dictionary;
- private final int _numTotalDocs;
- private final boolean _nullHandlingEnabled;
- private final FieldSpec.DataType _dataType;
+ private final DataSource _dataSource;
+ private final QueryContext _queryContext;
- private boolean _hasOrderBy;
- private boolean _isAscending;
private int _numDocsScanned;
- public DictionaryBasedDistinctOperator(FieldSpec.DataType dataType,
- DistinctAggregationFunction distinctAggregationFunction, Dictionary
dictionary, int numTotalDocs,
- boolean nullHandlingEnabled) {
- _dataType = dataType;
- _distinctAggregationFunction = distinctAggregationFunction;
- _dictionary = dictionary;
- _numTotalDocs = numTotalDocs;
- _nullHandlingEnabled = nullHandlingEnabled;
-
- List<OrderByExpressionContext> orderByExpressionContexts =
_distinctAggregationFunction.getOrderByExpressions();
- if (orderByExpressionContexts != null) {
- OrderByExpressionContext orderByExpressionContext =
orderByExpressionContexts.get(0);
- _isAscending = orderByExpressionContext.isAsc();
- _hasOrderBy = true;
- }
+ public DictionaryBasedDistinctOperator(DataSource dataSource, QueryContext
queryContext) {
+ _dataSource = dataSource;
+ _queryContext = queryContext;
}
@Override
protected DistinctResultsBlock getNextBlock() {
- return new DistinctResultsBlock(_distinctAggregationFunction,
buildResult());
- }
-
- /**
- * Build the final result for this operation
- */
- private DistinctTable buildResult() {
-
- assert _distinctAggregationFunction.getType() ==
AggregationFunctionType.DISTINCT;
-
- List<ExpressionContext> expressions =
_distinctAggregationFunction.getInputExpressions();
- ExpressionContext expression = expressions.get(0);
- DataSchema dataSchema = new DataSchema(new String[]{expression.toString()},
- new
DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.fromDataTypeSV(_dataType)});
- int dictLength = _dictionary.length();
- List<Record> records;
-
- int limit = _distinctAggregationFunction.getLimit();
- int actualLimit = Math.min(limit, dictLength);
+ String column =
_queryContext.getSelectExpressions().get(0).getIdentifier();
+ Dictionary dictionary = _dataSource.getDictionary();
+ assert dictionary != null;
+ DataSourceMetadata dataSourceMetadata =
_dataSource.getDataSourceMetadata();
+ DataSchema dataSchema = new DataSchema(new String[]{column},
+ new
DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.fromDataTypeSV(dataSourceMetadata.getDataType())});
+ int limit = _queryContext.getLimit();
+ int dictLength = dictionary.length();
+ int numValuesToKeep = Math.min(limit, dictLength);
+ boolean nullHandlingEnabled = _queryContext.isNullHandlingEnabled();
// If ORDER BY is not present, we read the first limit values from the
dictionary and return.
// If ORDER BY is present and the dictionary is sorted, then we read the
first/last limit values
// from the dictionary. If not sorted, then we read the entire dictionary
and return it.
- if (!_hasOrderBy) {
- records = new ArrayList<>(actualLimit);
-
- _numDocsScanned = actualLimit;
- iterateOnDictionary(dictLength, actualLimit, records);
+ DistinctTable distinctTable;
+ List<OrderByExpressionContext> orderByExpressions =
_queryContext.getOrderByExpressions();
+ if (orderByExpressions == null) {
+ distinctTable =
+ new DistinctTable(dataSchema, iterateOnDictionary(dictionary,
numValuesToKeep), nullHandlingEnabled);
+ _numDocsScanned = numValuesToKeep;
} else {
- if (_dictionary.isSorted()) {
- records = new ArrayList<>(actualLimit);
- if (_isAscending) {
- _numDocsScanned = actualLimit;
- iterateOnDictionary(dictLength, actualLimit, records);
+ if (dictionary.isSorted()) {
+ if (orderByExpressions.get(0).isAsc()) {
+ distinctTable =
+ new DistinctTable(dataSchema, iterateOnDictionary(dictionary,
numValuesToKeep), nullHandlingEnabled);
} else {
- _numDocsScanned = actualLimit;
- iterateOnDictionaryDesc(dictLength, actualLimit, records);
+ distinctTable =
+ new DistinctTable(dataSchema,
iterateOnDictionaryDesc(dictionary, numValuesToKeep), nullHandlingEnabled);
}
+ _numDocsScanned = numValuesToKeep;
} else {
- // DictionaryBasedDistinctOperator cannot handle nulls.
- DistinctTable distinctTable =
- new DistinctTable(dataSchema,
_distinctAggregationFunction.getOrderByExpressions(), limit,
- _nullHandlingEnabled);
-
- _numDocsScanned = dictLength;
+ distinctTable = new DistinctTable(dataSchema, orderByExpressions,
limit, nullHandlingEnabled);
for (int i = 0; i < dictLength; i++) {
- distinctTable.addWithOrderBy(new Record(new
Object[]{_dictionary.getInternal(i)}));
+ distinctTable.addWithOrderBy(new Record(new
Object[]{dictionary.getInternal(i)}));
}
-
- return distinctTable;
+ _numDocsScanned = dictLength;
}
}
- return new DistinctTable(dataSchema, records, _nullHandlingEnabled);
+ return new DistinctResultsBlock(distinctTable);
}
- private void iterateOnDictionary(int dictLength, int actualLimit,
List<Record> records) {
- for (int i = 0; i < actualLimit; i++) {
+ private static List<Record> iterateOnDictionary(Dictionary dictionary, int
length) {
+ List<Record> records = new ArrayList<>(length);
+ for (int i = 0; i < length; i++) {
Tracing.ThreadAccountantOps.sampleAndCheckInterruptionPeriodically(i);
- records.add(new Record(new Object[]{_dictionary.getInternal(i)}));
+ records.add(new Record(new Object[]{dictionary.getInternal(i)}));
}
+ return records;
}
- private void iterateOnDictionaryDesc(int dictLength, int actualLimit,
List<Record> records) {
- for (int i = dictLength - 1, j = 0; i >= (dictLength - actualLimit); i--,
j++) {
+ private static List<Record> iterateOnDictionaryDesc(Dictionary dictionary,
int length) {
+ List<Record> records = new ArrayList<>(length);
+ int dictLength = dictionary.length();
+ for (int i = dictLength - 1, j = 0; i >= (dictLength - length); i--, j++) {
Tracing.ThreadAccountantOps.sampleAndCheckInterruptionPeriodically(j);
- records.add(new Record(new Object[]{_dictionary.getInternal(i)}));
+ records.add(new Record(new Object[]{dictionary.getInternal(i)}));
}
+ return records;
}
@Override
@@ -155,6 +128,7 @@ public class DictionaryBasedDistinctOperator extends
BaseOperator<DistinctResult
@Override
public ExecutionStatistics getExecutionStatistics() {
// NOTE: Set numDocsScanned to numTotalDocs for backward compatibility.
- return new ExecutionStatistics(_numDocsScanned, 0, _numDocsScanned,
_numTotalDocs);
+ return new ExecutionStatistics(_numDocsScanned, 0, _numDocsScanned,
+ _dataSource.getDataSourceMetadata().getNumDocs());
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DistinctOperator.java
b/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DistinctOperator.java
index 30e135223f..3d95a0c547 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DistinctOperator.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/operator/query/DistinctOperator.java
@@ -20,12 +20,12 @@ package org.apache.pinot.core.operator.query;
import java.util.Collections;
import java.util.List;
+import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.core.operator.BaseOperator;
import org.apache.pinot.core.operator.BaseProjectOperator;
import org.apache.pinot.core.operator.ExecutionStatistics;
import org.apache.pinot.core.operator.blocks.ValueBlock;
import org.apache.pinot.core.operator.blocks.results.DistinctResultsBlock;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctExecutor;
import org.apache.pinot.core.query.distinct.DistinctExecutorFactory;
import org.apache.pinot.core.query.request.context.QueryContext;
@@ -39,31 +39,29 @@ public class DistinctOperator extends
BaseOperator<DistinctResultsBlock> {
private static final String EXPLAIN_NAME = "DISTINCT";
private final IndexSegment _indexSegment;
- private final DistinctAggregationFunction _distinctAggregationFunction;
private final BaseProjectOperator<?> _projectOperator;
- private final DistinctExecutor _distinctExecutor;
+ private final QueryContext _queryContext;
private int _numDocsScanned = 0;
- public DistinctOperator(IndexSegment indexSegment,
DistinctAggregationFunction distinctAggregationFunction,
- BaseProjectOperator<?> projectOperator, QueryContext queryContext) {
+ public DistinctOperator(IndexSegment indexSegment, BaseProjectOperator<?>
projectOperator,
+ QueryContext queryContext) {
_indexSegment = indexSegment;
- _distinctAggregationFunction = distinctAggregationFunction;
_projectOperator = projectOperator;
- _distinctExecutor =
DistinctExecutorFactory.getDistinctExecutor(distinctAggregationFunction,
projectOperator,
- queryContext.isNullHandlingEnabled());
+ _queryContext = queryContext;
}
@Override
protected DistinctResultsBlock getNextBlock() {
+ DistinctExecutor executor =
DistinctExecutorFactory.getDistinctExecutor(_projectOperator, _queryContext);
ValueBlock valueBlock;
while ((valueBlock = _projectOperator.nextBlock()) != null) {
_numDocsScanned += valueBlock.getNumDocs();
- if (_distinctExecutor.process(valueBlock)) {
+ if (executor.process(valueBlock)) {
break;
}
}
- return new DistinctResultsBlock(_distinctAggregationFunction,
_distinctExecutor.getResult());
+ return new DistinctResultsBlock(executor.getResult());
}
@Override
@@ -87,13 +85,12 @@ public class DistinctOperator extends
BaseOperator<DistinctResultsBlock> {
@Override
public String toExplainString() {
- String[] keys = _distinctAggregationFunction.getColumns();
+ List<ExpressionContext> expressions = _queryContext.getSelectExpressions();
+ int numExpressions = expressions.size();
StringBuilder stringBuilder = new
StringBuilder(EXPLAIN_NAME).append("(keyColumns:");
- if (keys.length > 0) {
- stringBuilder.append(keys[0]);
- for (int i = 1; i < keys.length; i++) {
- stringBuilder.append(", ").append(keys[i]);
- }
+ stringBuilder.append(expressions.get(0).toString());
+ for (int i = 1; i < numExpressions; i++) {
+ stringBuilder.append(", ").append(expressions.get(i).toString());
}
return stringBuilder.append(')').toString();
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/plan/DistinctPlanNode.java
b/pinot-core/src/main/java/org/apache/pinot/core/plan/DistinctPlanNode.java
index 81182535cc..be8b92e833 100644
--- a/pinot-core/src/main/java/org/apache/pinot/core/plan/DistinctPlanNode.java
+++ b/pinot-core/src/main/java/org/apache/pinot/core/plan/DistinctPlanNode.java
@@ -25,20 +25,15 @@ import org.apache.pinot.core.operator.BaseProjectOperator;
import org.apache.pinot.core.operator.blocks.results.DistinctResultsBlock;
import org.apache.pinot.core.operator.query.DictionaryBasedDistinctOperator;
import org.apache.pinot.core.operator.query.DistinctOperator;
-import org.apache.pinot.core.query.aggregation.function.AggregationFunction;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.IndexSegment;
import org.apache.pinot.segment.spi.datasource.DataSource;
-import org.apache.pinot.segment.spi.datasource.DataSourceMetadata;
-import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.segment.spi.index.reader.NullValueVectorReader;
/**
* Execution plan for distinct queries on a single segment.
*/
-@SuppressWarnings("rawtypes")
public class DistinctPlanNode implements PlanNode {
private final IndexSegment _indexSegment;
private final QueryContext _queryContext;
@@ -50,20 +45,17 @@ public class DistinctPlanNode implements PlanNode {
@Override
public Operator<DistinctResultsBlock> run() {
- AggregationFunction[] aggregationFunctions =
_queryContext.getAggregationFunctions();
- assert aggregationFunctions != null && aggregationFunctions.length == 1
- && aggregationFunctions[0] instanceof DistinctAggregationFunction;
- DistinctAggregationFunction distinctAggregationFunction =
(DistinctAggregationFunction) aggregationFunctions[0];
- List<ExpressionContext> expressions =
distinctAggregationFunction.getInputExpressions();
+ List<ExpressionContext> expressions = _queryContext.getSelectExpressions();
// Use dictionary to solve the query if possible
- if (_queryContext.getFilter() == null &&
!_queryContext.isNullHandlingEnabled() && expressions.size() == 1) {
- ExpressionContext expression = expressions.get(0);
- if (expression.getType() == ExpressionContext.Type.IDENTIFIER) {
- DataSource dataSource =
_indexSegment.getDataSource(expression.getIdentifier());
- Dictionary dictionary = dataSource.getDictionary();
- if (dictionary != null) {
- DataSourceMetadata dataSourceMetadata =
dataSource.getDataSourceMetadata();
+ if (_queryContext.getFilter() == null && expressions.size() == 1) {
+ String column = expressions.get(0).getIdentifier();
+ if (column != null) {
+ DataSource dataSource = _indexSegment.getDataSource(column);
+ if (dataSource.getDictionary() != null) {
+ if (!_queryContext.isNullHandlingEnabled()) {
+ return new DictionaryBasedDistinctOperator(dataSource,
_queryContext);
+ }
// If nullHandlingEnabled is set to true, and the column contains
null values, call DistinctOperator instead
// of DictionaryBasedDistinctOperator since nullValueVectorReader is
a form of a filter.
// TODO: reserve special value in dictionary (e.g. -1) for null in
the future so
@@ -71,8 +63,7 @@ public class DistinctPlanNode implements PlanNode {
// dictionary-encoded columns.
NullValueVectorReader nullValueReader =
dataSource.getNullValueVector();
if (nullValueReader == null ||
nullValueReader.getNullBitmap().isEmpty()) {
- return new
DictionaryBasedDistinctOperator(dataSourceMetadata.getDataType(),
distinctAggregationFunction,
- dictionary, dataSourceMetadata.getNumDocs(),
_queryContext.isNullHandlingEnabled());
+ return new DictionaryBasedDistinctOperator(dataSource,
_queryContext);
}
}
}
@@ -80,6 +71,6 @@ public class DistinctPlanNode implements PlanNode {
BaseProjectOperator<?> projectOperator =
new ProjectPlanNode(_indexSegment, _queryContext, expressions,
DocIdSetPlanNode.MAX_DOC_PER_CALL).run();
- return new DistinctOperator(_indexSegment, distinctAggregationFunction,
projectOperator, _queryContext);
+ return new DistinctOperator(_indexSegment, projectOperator, _queryContext);
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactory.java
index 7f96072c9e..4a01580e61 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactory.java
@@ -24,7 +24,6 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.datasketches.tuple.aninteger.IntegerSummary;
import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.FunctionContext;
-import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.AggregationFunctionType;
import org.apache.pinot.spi.data.FieldSpec.DataType;
import org.apache.pinot.spi.exception.BadQueryRequestException;
@@ -41,12 +40,8 @@ public class AggregationFunctionFactory {
/**
* Given the function information, returns a new instance of the
corresponding aggregation function.
* <p>NOTE: Underscores in the function name are ignored.
- * <p>NOTE: We pass the query context to this method because DISTINCT is
currently modeled as an aggregation function
- * and requires the order-by and limit information from the query.
- * <p>TODO: Consider modeling DISTINCT as unique selection instead of
aggregation so that early-termination, limit and
- * offset can be applied easier
*/
- public static AggregationFunction getAggregationFunction(FunctionContext
function, QueryContext queryContext) {
+ public static AggregationFunction getAggregationFunction(FunctionContext
function, boolean nullHandlingEnabled) {
try {
String upperCaseFunctionName =
StringUtils.remove(function.getFunctionName(), '_').toUpperCase();
List<ExpressionContext> arguments = function.getArguments();
@@ -187,17 +182,17 @@ public class AggregationFunctionFactory {
} else {
switch (AggregationFunctionType.valueOf(upperCaseFunctionName)) {
case COUNT:
- return new CountAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new CountAggregationFunction(firstArgument,
nullHandlingEnabled);
case MIN:
- return new MinAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new MinAggregationFunction(firstArgument,
nullHandlingEnabled);
case MAX:
- return new MaxAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new MaxAggregationFunction(firstArgument,
nullHandlingEnabled);
case SUM:
- return new SumAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new SumAggregationFunction(firstArgument,
nullHandlingEnabled);
case SUMPRECISION:
- return new SumPrecisionAggregationFunction(arguments,
queryContext.isNullHandlingEnabled());
+ return new SumPrecisionAggregationFunction(arguments,
nullHandlingEnabled);
case AVG:
- return new AvgAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new AvgAggregationFunction(firstArgument,
nullHandlingEnabled);
case MODE:
return new ModeAggregationFunction(arguments);
case FIRSTWITHTIME:
@@ -308,9 +303,6 @@ public class AggregationFunctionFactory {
return new DistinctSumMVAggregationFunction(firstArgument);
case DISTINCTAVGMV:
return new DistinctAvgMVAggregationFunction(firstArgument);
- case DISTINCT:
- return new DistinctAggregationFunction(arguments,
queryContext.getOrderByExpressions(),
- queryContext.getLimit());
case STUNION:
return new StUnionAggregationFunction(firstArgument);
case HISTOGRAM:
@@ -320,9 +312,9 @@ public class AggregationFunctionFactory {
case COVARSAMP:
return new CovarianceAggregationFunction(arguments, true);
case BOOLAND:
- return new BooleanAndAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new BooleanAndAggregationFunction(firstArgument,
nullHandlingEnabled);
case BOOLOR:
- return new BooleanOrAggregationFunction(firstArgument,
queryContext.isNullHandlingEnabled());
+ return new BooleanOrAggregationFunction(firstArgument,
nullHandlingEnabled);
case VARPOP:
return new VarianceAggregationFunction(firstArgument, false,
false);
case VARSAMP:
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/DistinctAggregationFunction.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/DistinctAggregationFunction.java
deleted file mode 100644
index 6035ca5a03..0000000000
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/aggregation/function/DistinctAggregationFunction.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/**
- * 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.pinot.core.query.aggregation.function;
-
-import java.util.List;
-import java.util.Map;
-import javax.annotation.Nullable;
-import org.apache.pinot.common.request.context.ExpressionContext;
-import org.apache.pinot.common.request.context.OrderByExpressionContext;
-import org.apache.pinot.common.utils.DataSchema.ColumnDataType;
-import org.apache.pinot.core.common.BlockValSet;
-import org.apache.pinot.core.query.aggregation.AggregationResultHolder;
-import org.apache.pinot.core.query.aggregation.groupby.GroupByResultHolder;
-import org.apache.pinot.segment.spi.AggregationFunctionType;
-
-
-/**
- * The DISTINCT clause in SQL is represented as the DISTINCT aggregation
function. Currently it is only used to wrap the
- * information for the distinct queries.
- * TODO: Use a separate way to represent DISTINCT instead of aggregation.
- */
-@SuppressWarnings("rawtypes")
-public class DistinctAggregationFunction implements
AggregationFunction<Object, Comparable> {
- private final List<ExpressionContext> _expressions;
- private final String[] _columns;
- private final List<OrderByExpressionContext> _orderByExpressions;
- private final int _limit;
-
- /**
- * Constructor for the class.
- *
- * @param expressions Distinct columns to return
- * @param orderByExpressions Order By clause
- * @param limit Limit clause
- */
- public DistinctAggregationFunction(List<ExpressionContext> expressions,
- @Nullable List<OrderByExpressionContext> orderByExpressions, int limit) {
- _expressions = expressions;
- int numExpressions = expressions.size();
- _columns = new String[numExpressions];
- for (int i = 0; i < numExpressions; i++) {
- _columns[i] = expressions.get(i).toString();
- }
- _orderByExpressions = orderByExpressions;
- _limit = limit;
- }
-
- public String[] getColumns() {
- return _columns;
- }
-
- public List<OrderByExpressionContext> getOrderByExpressions() {
- return _orderByExpressions;
- }
-
- public int getLimit() {
- return _limit;
- }
-
- @Override
- public AggregationFunctionType getType() {
- return AggregationFunctionType.DISTINCT;
- }
-
- @Override
- public List<ExpressionContext> getInputExpressions() {
- return _expressions;
- }
-
- @Override
- public String getResultColumnName() {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public ColumnDataType getIntermediateResultColumnType() {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public AggregationResultHolder createAggregationResultHolder() {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public GroupByResultHolder createGroupByResultHolder(int initialCapacity,
int maxCapacity) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public void aggregate(int length, AggregationResultHolder
aggregationResultHolder,
- Map<ExpressionContext, BlockValSet> blockValSetMap) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public void aggregateGroupBySV(int length, int[] groupKeyArray,
GroupByResultHolder groupByResultHolder,
- Map<ExpressionContext, BlockValSet> blockValSetMap) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public void aggregateGroupByMV(int length, int[][] groupKeysArray,
GroupByResultHolder groupByResultHolder,
- Map<ExpressionContext, BlockValSet> blockValSetMap) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public Object extractAggregationResult(AggregationResultHolder
aggregationResultHolder) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public Object extractGroupByResult(GroupByResultHolder groupByResultHolder,
int groupKey) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public Object merge(Object intermediateResult1, Object intermediateResult2) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public ColumnDataType getFinalResultColumnType() {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public Comparable extractFinalResult(Object intermediateResult) {
- throw new UnsupportedOperationException("Operation not supported for
DISTINCT aggregation function");
- }
-
- @Override
- public String toExplainString() {
- StringBuilder stringBuilder = new
StringBuilder(getType().getName()).append('(');
- int numArguments = getInputExpressions().size();
- if (numArguments > 0) {
- stringBuilder.append(getInputExpressions().get(0).toString());
- for (int i = 1; i < numArguments; i++) {
- stringBuilder.append(",
").append(getInputExpressions().get(i).toString());
- }
- }
- return stringBuilder.append(')').toString();
- }
-}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/distinct/DistinctExecutorFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/distinct/DistinctExecutorFactory.java
index 4a89147c05..5a3e052c15 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/distinct/DistinctExecutorFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/distinct/DistinctExecutorFactory.java
@@ -24,7 +24,6 @@ import
org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.OrderByExpressionContext;
import org.apache.pinot.core.operator.BaseProjectOperator;
import org.apache.pinot.core.operator.ColumnContext;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import
org.apache.pinot.core.query.distinct.dictionary.DictionaryBasedMultiColumnDistinctOnlyExecutor;
import
org.apache.pinot.core.query.distinct.dictionary.DictionaryBasedMultiColumnDistinctOrderByExecutor;
import
org.apache.pinot.core.query.distinct.dictionary.DictionaryBasedSingleColumnDistinctOnlyExecutor;
@@ -44,6 +43,7 @@ import
org.apache.pinot.core.query.distinct.raw.RawLongSingleColumnDistinctOrder
import org.apache.pinot.core.query.distinct.raw.RawMultiColumnDistinctExecutor;
import
org.apache.pinot.core.query.distinct.raw.RawStringSingleColumnDistinctOnlyExecutor;
import
org.apache.pinot.core.query.distinct.raw.RawStringSingleColumnDistinctOrderByExecutor;
+import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.segment.spi.index.reader.Dictionary;
import org.apache.pinot.spi.data.FieldSpec.DataType;
@@ -58,15 +58,16 @@ public class DistinctExecutorFactory {
/**
* Returns the {@link DistinctExecutor} for the given distinct query.
*/
- public static DistinctExecutor
getDistinctExecutor(DistinctAggregationFunction distinctAggregationFunction,
- BaseProjectOperator<?> projectOperator, boolean nullHandlingEnabled) {
- List<ExpressionContext> expressions =
distinctAggregationFunction.getInputExpressions();
- List<OrderByExpressionContext> orderByExpressions =
distinctAggregationFunction.getOrderByExpressions();
- int limit = distinctAggregationFunction.getLimit();
+ public static DistinctExecutor getDistinctExecutor(BaseProjectOperator<?>
projectOperator,
+ QueryContext queryContext) {
+ List<ExpressionContext> expressions = queryContext.getSelectExpressions();
+ List<OrderByExpressionContext> orderByExpressions =
queryContext.getOrderByExpressions();
+ int limit = queryContext.getLimit();
if (orderByExpressions == null) {
- return getDistinctOnlyExecutor(expressions, limit, projectOperator,
nullHandlingEnabled);
+ return getDistinctOnlyExecutor(expressions, limit, projectOperator,
queryContext.isNullHandlingEnabled());
} else {
- return getDistinctOrderByExecutor(expressions, orderByExpressions,
limit, projectOperator, nullHandlingEnabled);
+ return getDistinctOrderByExecutor(expressions, orderByExpressions,
limit, projectOperator,
+ queryContext.isNullHandlingEnabled());
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/BaseGapfillProcessor.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/BaseGapfillProcessor.java
index b7da1d674f..25106858ea 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/BaseGapfillProcessor.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/BaseGapfillProcessor.java
@@ -201,7 +201,7 @@ abstract class BaseGapfillProcessor {
} else {
FunctionContext functionContext = expressionContext.getFunction();
AggregationFunction aggregationFunction =
- AggregationFunctionFactory.getAggregationFunction(functionContext,
_queryContext);
+ AggregationFunctionFactory.getAggregationFunction(functionContext,
_queryContext.isNullHandlingEnabled());
columnDataTypes[i] = aggregationFunction.getFinalResultColumnType();
columnNames[i] = functionContext.toString();
}
@@ -222,8 +222,8 @@ abstract class BaseGapfillProcessor {
return epoch / sz * sz;
}
- protected List<Object[]> gapFillAndAggregate(
- List<Object[]> rows, DataSchema dataSchema, DataSchema
resultTableSchema) {
+ protected List<Object[]> gapFillAndAggregate(List<Object[]> rows, DataSchema
dataSchema,
+ DataSchema resultTableSchema) {
throw new UnsupportedOperationException("Not supported");
}
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/DistinctDataTableReducer.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/DistinctDataTableReducer.java
index d7bc3574df..5adc021bba 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/DistinctDataTableReducer.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/DistinctDataTableReducer.java
@@ -27,13 +27,13 @@ import java.util.Map;
import org.apache.pinot.common.CustomObject;
import org.apache.pinot.common.datatable.DataTable;
import org.apache.pinot.common.metrics.BrokerMetrics;
+import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.response.broker.BrokerResponseNative;
import org.apache.pinot.common.response.broker.ResultTable;
import org.apache.pinot.common.utils.DataSchema;
import org.apache.pinot.common.utils.DataSchema.ColumnDataType;
import org.apache.pinot.core.common.ObjectSerDeUtils;
import org.apache.pinot.core.data.table.Record;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctTable;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.core.query.selection.SelectionOperatorUtils;
@@ -46,11 +46,9 @@ import org.roaringbitmap.RoaringBitmap;
* Helper class to reduce data tables and set results of distinct query into
the BrokerResponseNative
*/
public class DistinctDataTableReducer implements DataTableReducer {
- private final DistinctAggregationFunction _distinctAggregationFunction;
private final QueryContext _queryContext;
- DistinctDataTableReducer(DistinctAggregationFunction
distinctAggregationFunction, QueryContext queryContext) {
- _distinctAggregationFunction = distinctAggregationFunction;
+ DistinctDataTableReducer(QueryContext queryContext) {
_queryContext = queryContext;
}
@@ -115,18 +113,21 @@ public class DistinctDataTableReducer implements
DataTableReducer {
// All the DistinctTables are empty, construct an empty response
// TODO: This returns schema with all STRING data types.
// There's no way currently to get the data types of the distinct
columns for empty results
- String[] columns = _distinctAggregationFunction.getColumns();
-
- int numColumns = columns.length;
- ColumnDataType[] columnDataTypes = new ColumnDataType[numColumns];
+ List<ExpressionContext> expressions =
_queryContext.getSelectExpressions();
+ int numExpressions = expressions.size();
+ String[] columns = new String[numExpressions];
+ for (int i = 0; i < numExpressions; i++) {
+ columns[i] = expressions.get(i).toString();
+ }
+ ColumnDataType[] columnDataTypes = new ColumnDataType[numExpressions];
Arrays.fill(columnDataTypes, ColumnDataType.STRING);
brokerResponseNative.setResultTable(
new ResultTable(new DataSchema(columns, columnDataTypes),
Collections.emptyList()));
} else {
// Construct a main DistinctTable and merge all non-empty DistinctTables
into it
- DistinctTable mainDistinctTable = new
DistinctTable(nonEmptyDistinctTables.get(0).getDataSchema(),
- _distinctAggregationFunction.getOrderByExpressions(),
_distinctAggregationFunction.getLimit(),
- _queryContext.isNullHandlingEnabled());
+ DistinctTable mainDistinctTable =
+ new DistinctTable(nonEmptyDistinctTables.get(0).getDataSchema(),
_queryContext.getOrderByExpressions(),
+ _queryContext.getLimit(), _queryContext.isNullHandlingEnabled());
for (DistinctTable distinctTable : nonEmptyDistinctTables) {
mainDistinctTable.mergeTable(distinctTable);
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/GapfillProcessor.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/GapfillProcessor.java
index 9523ea4e65..9b14c51700 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/GapfillProcessor.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/GapfillProcessor.java
@@ -280,7 +280,7 @@ public class GapfillProcessor extends BaseGapfillProcessor {
if (expressionContext.getType() == ExpressionContext.Type.FUNCTION) {
FunctionContext functionContext = expressionContext.getFunction();
AggregationFunction aggregationFunction =
- AggregationFunctionFactory.getAggregationFunction(functionContext,
_queryContext);
+ AggregationFunctionFactory.getAggregationFunction(functionContext,
_queryContext.isNullHandlingEnabled());
GroupByResultHolder groupByResultHolder =
aggregationFunction.createGroupByResultHolder(groupKeyIndexes.size(),
groupKeyIndexes.size());
if (aggregationFunction instanceof CountAggregationFunction) {
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/ResultReducerFactory.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/ResultReducerFactory.java
index 529cad24db..24d991d4b4 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/ResultReducerFactory.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/reduce/ResultReducerFactory.java
@@ -18,17 +18,13 @@
*/
package org.apache.pinot.core.query.reduce;
-import org.apache.pinot.core.query.aggregation.function.AggregationFunction;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.request.context.QueryContext;
import org.apache.pinot.core.query.request.context.utils.QueryContextUtils;
-import org.apache.pinot.segment.spi.AggregationFunctionType;
/**
* Factory class to construct the right result reducer based on the query
context.
*/
-@SuppressWarnings("rawtypes")
public final class ResultReducerFactory {
private ResultReducerFactory() {
}
@@ -40,26 +36,18 @@ public final class ResultReducerFactory {
if (queryContext.isExplain()) {
return new ExplainPlanDataTableReducer(queryContext);
}
-
- AggregationFunction[] aggregationFunctions =
queryContext.getAggregationFunctions();
- if (aggregationFunctions == null) {
- // Selection query
+ if (QueryContextUtils.isSelectionQuery(queryContext)) {
return new SelectionDataTableReducer(queryContext);
- } else {
- // Aggregation query
+ }
+ if (QueryContextUtils.isAggregationQuery(queryContext)) {
if (queryContext.getGroupByExpressions() == null) {
- // Aggregation only query
- if (aggregationFunctions.length == 1 &&
aggregationFunctions[0].getType() == AggregationFunctionType.DISTINCT) {
- // Distinct query
- return new DistinctDataTableReducer((DistinctAggregationFunction)
aggregationFunctions[0], queryContext);
- } else {
- return new AggregationDataTableReducer(queryContext);
- }
+ return new AggregationDataTableReducer(queryContext);
} else {
- // Aggregation group-by query
return new GroupByDataTableReducer(queryContext);
}
}
+ assert QueryContextUtils.isDistinctQuery(queryContext);
+ return new DistinctDataTableReducer(queryContext);
}
public static StreamingReducer getStreamingReducer(QueryContext
queryContext) {
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/QueryContext.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/QueryContext.java
index fcc97dd6fd..5d5e9a3718 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/QueryContext.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/QueryContext.java
@@ -73,6 +73,7 @@ public class QueryContext {
private final String _tableName;
private final QueryContext _subquery;
private final List<ExpressionContext> _selectExpressions;
+ private final boolean _distinct;
private final List<String> _aliasList;
private final FilterContext _filter;
private final List<ExpressionContext> _groupByExpressions;
@@ -124,14 +125,15 @@ public class QueryContext {
private boolean _serverReturnFinalResult;
private QueryContext(@Nullable String tableName, @Nullable QueryContext
subquery,
- List<ExpressionContext> selectExpressions, List<String> aliasList,
@Nullable FilterContext filter,
- @Nullable List<ExpressionContext> groupByExpressions, @Nullable
FilterContext havingFilter,
- @Nullable List<OrderByExpressionContext> orderByExpressions, int limit,
int offset,
- Map<String, String> queryOptions, @Nullable Map<ExpressionContext,
ExpressionContext> expressionOverrideHints,
- boolean explain) {
+ List<ExpressionContext> selectExpressions, boolean distinct,
List<String> aliasList,
+ @Nullable FilterContext filter, @Nullable List<ExpressionContext>
groupByExpressions,
+ @Nullable FilterContext havingFilter, @Nullable
List<OrderByExpressionContext> orderByExpressions, int limit,
+ int offset, Map<String, String> queryOptions,
+ @Nullable Map<ExpressionContext, ExpressionContext>
expressionOverrideHints, boolean explain) {
_tableName = tableName;
_subquery = subquery;
_selectExpressions = selectExpressions;
+ _distinct = distinct;
_aliasList = Collections.unmodifiableList(aliasList);
_filter = filter;
_groupByExpressions = groupByExpressions;
@@ -167,6 +169,13 @@ public class QueryContext {
return _selectExpressions;
}
+ /**
+ * Returns whether the query is a DISTINCT query.
+ */
+ public boolean isDistinct() {
+ return _distinct;
+ }
+
/**
* Returns an unmodifiable list from the expression to its alias.
*/
@@ -413,9 +422,9 @@ public class QueryContext {
@Override
public String toString() {
return "QueryContext{" + "_tableName='" + _tableName + '\'' + ",
_subquery=" + _subquery + ", _selectExpressions="
- + _selectExpressions + ", _aliasList=" + _aliasList + ", _filter=" +
_filter + ", _groupByExpressions="
- + _groupByExpressions + ", _havingFilter=" + _havingFilter + ",
_orderByExpressions=" + _orderByExpressions
- + ", _limit=" + _limit + ", _offset=" + _offset + ", _queryOptions=" +
_queryOptions
+ + _selectExpressions + ", _distinct=" + _distinct + ", _aliasList=" +
_aliasList + ", _filter=" + _filter
+ + ", _groupByExpressions=" + _groupByExpressions + ", _havingFilter="
+ _havingFilter + ", _orderByExpressions="
+ + _orderByExpressions + ", _limit=" + _limit + ", _offset=" + _offset
+ ", _queryOptions=" + _queryOptions
+ ", _expressionOverrideHints=" + _expressionOverrideHints + ",
_explain=" + _explain + '}';
}
@@ -423,6 +432,7 @@ public class QueryContext {
private String _tableName;
private QueryContext _subquery;
private List<ExpressionContext> _selectExpressions;
+ private boolean _distinct;
private List<String> _aliasList;
private FilterContext _filter;
private List<ExpressionContext> _groupByExpressions;
@@ -450,6 +460,11 @@ public class QueryContext {
return this;
}
+ public Builder setDistinct(boolean distinct) {
+ _distinct = distinct;
+ return this;
+ }
+
public Builder setAliasList(List<String> aliasList) {
_aliasList = aliasList;
return this;
@@ -507,8 +522,9 @@ public class QueryContext {
_queryOptions = Collections.emptyMap();
}
QueryContext queryContext =
- new QueryContext(_tableName, _subquery, _selectExpressions,
_aliasList, _filter, _groupByExpressions,
- _havingFilter, _orderByExpressions, _limit, _offset,
_queryOptions, _expressionOverrideHints, _explain);
+ new QueryContext(_tableName, _subquery, _selectExpressions,
_distinct, _aliasList, _filter,
+ _groupByExpressions, _havingFilter, _orderByExpressions, _limit,
_offset, _queryOptions,
+ _expressionOverrideHints, _explain);
queryContext.setNullHandlingEnabled(QueryOptionsUtils.isNullHandlingEnabled(_queryOptions));
queryContext.setServerReturnFinalResult(QueryOptionsUtils.isServerReturnFinalResult(_queryOptions));
@@ -540,7 +556,7 @@ public class QueryContext {
}
int functionIndex = filteredAggregationFunctions.size();
AggregationFunction aggregationFunction =
- AggregationFunctionFactory.getAggregationFunction(aggregation,
queryContext);
+ AggregationFunctionFactory.getAggregationFunction(aggregation,
queryContext._nullHandlingEnabled);
filteredAggregationFunctions.add(Pair.of(aggregationFunction, filter));
filteredAggregationsIndexMap.put(Pair.of(aggregation, filter),
functionIndex);
}
@@ -561,7 +577,7 @@ public class QueryContext {
FilterContext filter = pair.getRight();
int functionIndex = filteredAggregationFunctions.size();
AggregationFunction aggregationFunction =
- AggregationFunctionFactory.getAggregationFunction(aggregation,
queryContext);
+ AggregationFunctionFactory.getAggregationFunction(aggregation,
queryContext._nullHandlingEnabled);
filteredAggregationFunctions.add(Pair.of(aggregationFunction,
filter));
filteredAggregationsIndexMap.put(Pair.of(aggregation, filter),
functionIndex);
}
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextConverterUtils.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextConverterUtils.java
index f2b08eafaa..7d16ed1cc4 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextConverterUtils.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextConverterUtils.java
@@ -28,7 +28,6 @@ import javax.annotation.Nullable;
import org.apache.commons.collections.CollectionUtils;
import org.apache.pinot.common.request.DataSource;
import org.apache.pinot.common.request.Expression;
-import org.apache.pinot.common.request.ExpressionType;
import org.apache.pinot.common.request.Function;
import org.apache.pinot.common.request.PinotQuery;
import org.apache.pinot.common.request.context.ExpressionContext;
@@ -65,40 +64,29 @@ public class QueryContextConverterUtils {
// SELECT
List<ExpressionContext> selectExpressions;
+ boolean distinct = false;
List<Expression> selectList = pinotQuery.getSelectList();
+ // Handle DISTINCT
+ if (selectList.size() == 1) {
+ Function function = selectList.get(0).getFunctionCall();
+ if (function != null && function.getOperator().equals("distinct")) {
+ distinct = true;
+ selectList = function.getOperands();
+ }
+ }
List<String> aliasList = new ArrayList<>(selectList.size());
selectExpressions = new ArrayList<>(selectList.size());
for (Expression thriftExpression : selectList) {
// Handle alias
- Expression expressionWithoutAlias = thriftExpression;
- if (thriftExpression.getType() == ExpressionType.FUNCTION) {
- Function function = thriftExpression.getFunctionCall();
+ Function function = thriftExpression.getFunctionCall();
+ Expression expressionWithoutAlias;
+ if (function != null && function.getOperator().equals("as")) {
List<Expression> operands = function.getOperands();
- switch (function.getOperator().toUpperCase()) {
- case "AS":
- expressionWithoutAlias = operands.get(0);
- aliasList.add(operands.get(1).getIdentifier().getName());
- break;
- case "DISTINCT":
- int numOperands = operands.size();
- for (int i = 0; i < numOperands; i++) {
- Expression operand = operands.get(i);
- Function operandFunction = operand.getFunctionCall();
- if (operandFunction != null &&
operandFunction.getOperator().equalsIgnoreCase("AS")) {
- operands.set(i, operandFunction.getOperands().get(0));
-
aliasList.add(operandFunction.getOperands().get(1).getIdentifier().getName());
- } else {
- aliasList.add(null);
- }
- }
- break;
- default:
- // Add null as a placeholder for alias.
- aliasList.add(null);
- break;
- }
+ expressionWithoutAlias = operands.get(0);
+ aliasList.add(operands.get(1).getIdentifier().getName());
} else {
- // Add null as a placeholder for alias.
+ expressionWithoutAlias = thriftExpression;
+ // Add null as a placeholder for alias
aliasList.add(null);
}
selectExpressions.add(RequestContextUtils.getExpression(expressionWithoutAlias));
@@ -161,7 +149,7 @@ public class QueryContextConverterUtils {
}
return new
QueryContext.Builder().setTableName(tableName).setSubquery(subquery)
-
.setSelectExpressions(selectExpressions).setAliasList(aliasList).setFilter(filter)
+
.setSelectExpressions(selectExpressions).setDistinct(distinct).setAliasList(aliasList).setFilter(filter)
.setGroupByExpressions(groupByExpressions).setOrderByExpressions(orderByExpressions)
.setHavingFilter(havingFilter).setLimit(pinotQuery.getLimit()).setOffset(pinotQuery.getOffset())
.setQueryOptions(pinotQuery.getQueryOptions()).setExpressionOverrideHints(expressionContextOverrideHints)
diff --git
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextUtils.java
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextUtils.java
index 7a468c438b..b5beee1a40 100644
---
a/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextUtils.java
+++
b/pinot-core/src/main/java/org/apache/pinot/core/query/request/context/utils/QueryContextUtils.java
@@ -24,12 +24,9 @@ import
org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.FilterContext;
import org.apache.pinot.common.request.context.FunctionContext;
import org.apache.pinot.common.request.context.OrderByExpressionContext;
-import org.apache.pinot.core.query.aggregation.function.AggregationFunction;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.request.context.QueryContext;
-@SuppressWarnings("rawtypes")
public class QueryContextUtils {
private QueryContextUtils() {
}
@@ -38,7 +35,7 @@ public class QueryContextUtils {
* Returns {@code true} if the given query is a selection query, {@code
false} otherwise.
*/
public static boolean isSelectionQuery(QueryContext query) {
- return query.getAggregationFunctions() == null;
+ return !query.isDistinct() && query.getAggregationFunctions() == null;
}
/**
@@ -47,25 +44,21 @@ public class QueryContextUtils {
* Selection-only query at this moment means selection query without
order-by.
*/
public static boolean isSelectionOnlyQuery(QueryContext query) {
- return query.getAggregationFunctions() == null &&
query.getOrderByExpressions() == null;
+ return isSelectionQuery(query) && query.getOrderByExpressions() == null;
}
/**
* Returns {@code true} if the given query is an aggregation query, {@code
false} otherwise.
*/
public static boolean isAggregationQuery(QueryContext query) {
- AggregationFunction[] aggregationFunctions =
query.getAggregationFunctions();
- return aggregationFunctions != null && (aggregationFunctions.length != 1
- || !(aggregationFunctions[0] instanceof DistinctAggregationFunction));
+ return query.getAggregationFunctions() != null;
}
/**
* Returns {@code true} if the given query is a distinct query, {@code
false} otherwise.
*/
public static boolean isDistinctQuery(QueryContext query) {
- AggregationFunction[] aggregationFunctions =
query.getAggregationFunctions();
- return aggregationFunctions != null && aggregationFunctions.length == 1
- && aggregationFunctions[0] instanceof DistinctAggregationFunction;
+ return query.isDistinct();
}
/** Collect aggregation functions (except for the ones in filter). */
@@ -96,7 +89,6 @@ public class QueryContextUtils {
}
}
-
/** Collect aggregation functions from an ExpressionContext. */
public static void collectPostAggregations(ExpressionContext expression,
Set<String> postAggregations) {
FunctionContext function = expression.getFunction();
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactoryTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactoryTest.java
index a4eaa1f991..de8abca960 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactoryTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/query/aggregation/function/AggregationFunctionFactoryTest.java
@@ -18,12 +18,8 @@
*/
package org.apache.pinot.core.query.aggregation.function;
-import java.util.Arrays;
-import org.apache.pinot.common.request.context.ExpressionContext;
import org.apache.pinot.common.request.context.FunctionContext;
import org.apache.pinot.common.request.context.RequestContextUtils;
-import org.apache.pinot.core.query.request.context.QueryContext;
-import
org.apache.pinot.core.query.request.context.utils.QueryContextConverterUtils;
import org.apache.pinot.segment.spi.AggregationFunctionType;
import org.testng.annotations.Test;
@@ -35,416 +31,413 @@ import static org.testng.Assert.assertTrue;
public class AggregationFunctionFactoryTest {
private static final String ARGUMENT_COLUMN = "(column)";
private static final String ARGUMENT_STAR = "(*)";
- private static final QueryContext DUMMY_QUERY_CONTEXT =
- QueryContextConverterUtils.getQueryContext("SELECT * FROM testTable");
@Test
public void testGetAggregationFunction() {
FunctionContext function = getFunction("CoUnT", ARGUMENT_STAR);
- AggregationFunction aggregationFunction =
- AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ AggregationFunction aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof CountAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.COUNT);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MiN");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof MinAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.MIN);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MaX");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof MaxAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.MAX);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("SuM");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof SumAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.SUM);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("SuMPreCIsiON");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof SumPrecisionAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.SUMPRECISION);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("AvG");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof AvgAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.AVG);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MoDe");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof ModeAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.MODE);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'BOOLEAN')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstIntValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'INT')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstIntValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'LONG')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstLongValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'FLOAT')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstFloatValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'DOUBLE')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstDoubleValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FiRsTwItHtImE", "(column,timeColumn,'STRING')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
FirstStringValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FIRSTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'BOOLEAN')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastIntValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'INT')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastIntValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'LONG')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastLongValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'FLOAT')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastFloatValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'DOUBLE')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastDoubleValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("LaStWiThTiMe", "(column,timeColumn,'STRING')");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
LastStringValueWithTimeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.LASTWITHTIME);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MiNmAxRaNgE");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof MinMaxRangeAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.MINMAXRANGE);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnT");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNT);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnThLl");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountHLLAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTHLL);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnTrAwHlL");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountRawHLLAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTRAWHLL);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("FaStHlL");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof FastHLLAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.FASTHLL);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLe5");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof PercentileAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILE);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeEsT50");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEEST);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeRaWEsT50");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWEST);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeTdIgEsT99");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeRaWTdIgEsT99");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWTDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLe", "(column, 5)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof PercentileAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILE);
assertEquals(aggregationFunction.getResultColumnName(),
"percentile(column, 5.0)");
function = getFunction("PeRcEnTiLe", "(column, 5.5)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof PercentileAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILE);
assertEquals(aggregationFunction.getResultColumnName(),
"percentile(column, 5.5)");
function = getFunction("PeRcEnTiLeEsT", "(column, 50)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentileest(column, 50.0)");
function = getFunction("PeRcEnTiLeRaWeSt", "(column, 50)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawest(column, 50.0)");
function = getFunction("PeRcEnTiLeEsT", "(column, 55.555)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentileest(column, 55.555)");
function = getFunction("PeRcEnTiLeRaWeSt", "(column, 55.555)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawEstAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawest(column, 55.555)");
function = getFunction("PeRcEnTiLeTdIgEsT", "(column, 99)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigest(column, 99.0)");
function = getFunction("PeRcEnTiLeTdIgEsT", "(column, 99.9999)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigest(column, 99.9999)");
function = getFunction("PeRcEnTiLeTdIgEsT", "(column, 99.9999, 1000)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigest(column, 99.9999, 1000)");
function = getFunction("PeRcEnTiLeRaWtDiGeSt", "(column, 99)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWTDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawtdigest(column, 99.0)");
function = getFunction("PeRcEnTiLeRaWtDiGeSt", "(column, 99.9999)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWTDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawtdigest(column, 99.9999)");
function = getFunction("PeRcEntiLEkll", "(column, 99.9999)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileKLLAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEKLL);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilekll(column, 99.9999)");
function = getFunction("PeRcEnTiLeRaWtDiGeSt", "(column, 99.9999, 500)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWTDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawtdigest(column, 99.9999, 500)");
function = getFunction("PeRcEnTiLeRaWtDiGeSt", "(column, 99.9999, 100)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileRawTDigestAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILERAWTDIGEST);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilerawtdigest(column, 99.9999)");
function = getFunction("CoUnTmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof CountMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.COUNTMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MiNmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof MinMVAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.MINMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MaXmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof MaxMVAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.MAXMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("SuMmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof SumMVAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.SUMMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("AvGmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof AvgMVAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.AVGMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("AvG_mV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof AvgMVAggregationFunction);
assertEquals(aggregationFunction.getType(), AggregationFunctionType.AVGMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("MiNmAxRaNgEmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
MinMaxRangeMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.MINMAXRANGEMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnTmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnThLlMv");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountHLLMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTHLLMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCt_CoUnT_hLl_Mv");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountHLLMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTHLLMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("DiStInCtCoUnTrAwHlLmV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
DistinctCountRawHLLMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCTCOUNTRAWHLLMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLe10Mv");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof PercentileMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeEsT90mV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileEstMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeTdIgEsT95mV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLe_TdIgEsT_95_mV");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("PeRcEnTiLeMv", "(column, 10)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof PercentileMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentilemv(column, 10.0)");
function = getFunction("PeRcEnTiLeEsTmV", "(column, 90)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileEstMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILEESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentileestmv(column, 90.0)");
function = getFunction("PeRcEnTiLeTdIgEsTmV", "(column, 95)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigestmv(column, 95.0)");
function = getFunction("PeRcEnTiLeTdIgEsTmV", "(column, 95, 1000)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigestmv(column, 95.0, 1000)");
function = getFunction("PeRcEnTiLe_TdIgEsT_mV", "(column, 95)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigestmv(column, 95.0)");
function = getFunction("PeRcEnTiLe_TdIgEsT_mV", "(column, 95, 200)");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof
PercentileTDigestMVAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.PERCENTILETDIGESTMV);
assertEquals(aggregationFunction.getResultColumnName(),
"percentiletdigestmv(column, 95.0, 200)");
function = getFunction("bool_and");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof BooleanAndAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.BOOLAND);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("bool_or");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof BooleanOrAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.BOOLOR);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("skewness");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof FourthMomentAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.SKEWNESS);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
function = getFunction("kurtosis");
- aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function,
DUMMY_QUERY_CONTEXT);
+ aggregationFunction =
AggregationFunctionFactory.getAggregationFunction(function, false);
assertTrue(aggregationFunction instanceof FourthMomentAggregationFunction);
assertEquals(aggregationFunction.getType(),
AggregationFunctionType.KURTOSIS);
assertEquals(aggregationFunction.getResultColumnName(),
function.toString());
@@ -457,18 +450,4 @@ public class AggregationFunctionFactoryTest {
private FunctionContext getFunction(String functionName, String args) {
return RequestContextUtils.getExpression(functionName +
args).getFunction();
}
-
- @Test
- public void testAggregationFunctionWithMultipleArgs() {
- QueryContext queryContext =
- QueryContextConverterUtils.getQueryContext("SELECT DISTINCT column1,
column2, column3 FROM testTable");
- AggregationFunction aggregationFunction =
-
AggregationFunctionFactory.getAggregationFunction(queryContext.getSelectExpressions().get(0).getFunction(),
- queryContext);
- assertTrue(aggregationFunction instanceof DistinctAggregationFunction);
- assertEquals(aggregationFunction.getType(),
AggregationFunctionType.DISTINCT);
- assertEquals(aggregationFunction.getInputExpressions(),
- Arrays.asList(ExpressionContext.forIdentifier("column1"),
ExpressionContext.forIdentifier("column2"),
- ExpressionContext.forIdentifier("column3")));
- }
}
diff --git
a/pinot-core/src/test/java/org/apache/pinot/core/query/request/context/utils/BrokerRequestToQueryContextConverterTest.java
b/pinot-core/src/test/java/org/apache/pinot/core/query/request/context/utils/BrokerRequestToQueryContextConverterTest.java
index 817a03c9a5..f430c2abf4 100644
---
a/pinot-core/src/test/java/org/apache/pinot/core/query/request/context/utils/BrokerRequestToQueryContextConverterTest.java
+++
b/pinot-core/src/test/java/org/apache/pinot/core/query/request/context/utils/BrokerRequestToQueryContextConverterTest.java
@@ -67,6 +67,7 @@ public class BrokerRequestToQueryContextConverterTest {
assertEquals(selectExpressions.size(), 1);
assertEquals(selectExpressions.get(0),
ExpressionContext.forIdentifier("*"));
assertEquals(selectExpressions.get(0).toString(), "*");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
assertNull(queryContext.getGroupByExpressions());
@@ -91,6 +92,7 @@ public class BrokerRequestToQueryContextConverterTest {
new FunctionContext(FunctionContext.Type.AGGREGATION, "count",
Collections.singletonList(ExpressionContext.forIdentifier("*")))));
assertEquals(selectExpressions.get(0).toString(), "count(*)");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
assertNull(queryContext.getGroupByExpressions());
@@ -115,6 +117,7 @@ public class BrokerRequestToQueryContextConverterTest {
assertEquals(selectExpressions.get(0).toString(), "foo");
assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
assertEquals(selectExpressions.get(1).toString(), "bar");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
List<OrderByExpressionContext> orderByExpressions =
queryContext.getOrderByExpressions();
@@ -139,12 +142,14 @@ public class BrokerRequestToQueryContextConverterTest {
QueryContext queryContext =
QueryContextConverterUtils.getQueryContext(query);
assertEquals(queryContext.getTableName(), "testTable");
List<ExpressionContext> selectExpressions =
queryContext.getSelectExpressions();
- assertEquals(selectExpressions.size(), 1);
- assertEquals(selectExpressions.get(0), ExpressionContext.forFunction(
- new FunctionContext(FunctionContext.Type.AGGREGATION, "distinct",
- Arrays.asList(ExpressionContext.forIdentifier("foo"),
ExpressionContext.forIdentifier("bar"),
- ExpressionContext.forIdentifier("foobar")))));
- assertEquals(selectExpressions.get(0).toString(),
"distinct(foo,bar,foobar)");
+ assertEquals(selectExpressions.size(), 3);
+ assertEquals(selectExpressions.get(0),
ExpressionContext.forIdentifier("foo"));
+ assertEquals(selectExpressions.get(0).toString(), "foo");
+ assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
+ assertEquals(selectExpressions.get(1).toString(), "bar");
+ assertEquals(selectExpressions.get(2),
ExpressionContext.forIdentifier("foobar"));
+ assertEquals(selectExpressions.get(2).toString(), "foobar");
+ assertTrue(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
assertNull(queryContext.getGroupByExpressions());
@@ -186,6 +191,7 @@ public class BrokerRequestToQueryContextConverterTest {
Arrays.asList(ExpressionContext.forLiteralContext(FieldSpec.DataType.STRING,
"456"),
ExpressionContext.forIdentifier("foobar")))));
assertEquals(selectExpressions.get(1).toString(), "sub('456',foobar)");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
assertNull(queryContext.getGroupByExpressions());
@@ -225,22 +231,19 @@ public class BrokerRequestToQueryContextConverterTest {
QueryContext queryContext =
QueryContextConverterUtils.getQueryContext(query);
assertEquals(queryContext.getTableName(), "testTable");
List<ExpressionContext> selectExpressions =
queryContext.getSelectExpressions();
- int numSelectExpressions = selectExpressions.size();
- assertTrue(numSelectExpressions == 1 || numSelectExpressions == 3);
- ExpressionContext aggregationExpression =
selectExpressions.get(numSelectExpressions - 1);
- assertEquals(aggregationExpression, ExpressionContext.forFunction(
+ assertEquals(selectExpressions.size(), 3);
+ assertEquals(selectExpressions.get(0), ExpressionContext.forFunction(
+ new FunctionContext(FunctionContext.Type.TRANSFORM, "sub",
+ Arrays.asList(ExpressionContext.forIdentifier("foo"),
ExpressionContext.forIdentifier("bar")))));
+ assertEquals(selectExpressions.get(0).toString(), "sub(foo,bar)");
+ assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
+ assertEquals(selectExpressions.get(1).toString(), "bar");
+ assertEquals(selectExpressions.get(2), ExpressionContext.forFunction(
new FunctionContext(FunctionContext.Type.AGGREGATION, "sum",
Collections.singletonList(
ExpressionContext.forFunction(new
FunctionContext(FunctionContext.Type.TRANSFORM, "add",
Arrays.asList(ExpressionContext.forIdentifier("foo"),
ExpressionContext.forIdentifier("bar"))))))));
- assertEquals(aggregationExpression.toString(), "sum(add(foo,bar))");
- if (numSelectExpressions == 3) {
- assertEquals(selectExpressions.get(0), ExpressionContext.forFunction(
- new FunctionContext(FunctionContext.Type.TRANSFORM, "sub",
- Arrays.asList(ExpressionContext.forIdentifier("foo"),
ExpressionContext.forIdentifier("bar")))));
- assertEquals(selectExpressions.get(0).toString(), "sub(foo,bar)");
- assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
- assertEquals(selectExpressions.get(1).toString(), "bar");
- }
+ assertEquals(selectExpressions.get(2).toString(), "sum(add(foo,bar))");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
List<ExpressionContext> groupByExpressions =
queryContext.getGroupByExpressions();
@@ -284,6 +287,7 @@ public class BrokerRequestToQueryContextConverterTest {
assertEquals(selectExpressions.size(), 1);
assertEquals(selectExpressions.get(0),
ExpressionContext.forIdentifier("*"));
assertEquals(selectExpressions.get(0).toString(), "*");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
FilterContext filter = queryContext.getFilter();
assertNotNull(filter);
@@ -328,6 +332,7 @@ public class BrokerRequestToQueryContextConverterTest {
assertEquals(selectExpressions.get(0).toString(), "sum(foo)");
assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
assertEquals(selectExpressions.get(1).toString(), "bar");
+ assertFalse(queryContext.isDistinct());
List<String> aliasList = queryContext.getAliasList();
assertEquals(aliasList.size(), 2);
assertEquals(aliasList.get(0), "a");
@@ -371,6 +376,7 @@ public class BrokerRequestToQueryContextConverterTest {
assertEquals(selectExpressions.get(0).toString(), "sum(foo)");
assertEquals(selectExpressions.get(1),
ExpressionContext.forIdentifier("bar"));
assertEquals(selectExpressions.get(1).toString(), "bar");
+ assertFalse(queryContext.isDistinct());
assertEquals(getAliasCount(queryContext.getAliasList()), 0);
assertNull(queryContext.getFilter());
List<ExpressionContext> groupByExpressions =
queryContext.getGroupByExpressions();
diff --git
a/pinot-query-planner/src/main/java/org/apache/pinot/query/parser/CalciteRexExpressionParser.java
b/pinot-query-planner/src/main/java/org/apache/pinot/query/parser/CalciteRexExpressionParser.java
index 34dc84805f..9bd4d39e35 100644
---
a/pinot-query-planner/src/main/java/org/apache/pinot/query/parser/CalciteRexExpressionParser.java
+++
b/pinot-query-planner/src/main/java/org/apache/pinot/query/parser/CalciteRexExpressionParser.java
@@ -145,8 +145,7 @@ public class CalciteRexExpressionParser {
private static Expression
convertDistinctAndSelectListToFunctionExpression(RexExpression.FunctionCall
rexCall,
PinotQuery pinotQuery) {
- String functionName = AggregationFunctionType.DISTINCT.getName();
- Expression functionExpression = getFunctionExpression(functionName);
+ Expression functionExpression = getFunctionExpression("distinct");
for (RexExpression node : rexCall.getFunctionOperands()) {
Expression columnExpression = toExpression(node, pinotQuery);
if (columnExpression.getType() == ExpressionType.IDENTIFIER &&
columnExpression.getIdentifier().getName()
diff --git
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
index dc2d2dcb75..2c3b1704da 100644
---
a/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
+++
b/pinot-query-runtime/src/test/java/org/apache/pinot/query/runtime/operator/LeafStageTransferableBlockOperatorTest.java
@@ -33,7 +33,6 @@ import
org.apache.pinot.core.operator.blocks.results.AggregationResultsBlock;
import org.apache.pinot.core.operator.blocks.results.DistinctResultsBlock;
import org.apache.pinot.core.operator.blocks.results.GroupByResultsBlock;
import org.apache.pinot.core.operator.blocks.results.SelectionResultsBlock;
-import
org.apache.pinot.core.query.aggregation.function.DistinctAggregationFunction;
import org.apache.pinot.core.query.distinct.DistinctTable;
import org.apache.pinot.core.query.request.ServerQueryRequest;
import org.apache.pinot.core.query.request.context.QueryContext;
@@ -210,7 +209,7 @@ public class LeafStageTransferableBlockOperatorTest {
DataSchema schema = new DataSchema(new String[]{"intCol", "strCol"},
new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.INT,
DataSchema.ColumnDataType.STRING});
List<InstanceResponseBlock> resultsBlockList =
Collections.singletonList(new InstanceResponseBlock(
- new DistinctResultsBlock(mock(DistinctAggregationFunction.class), new
DistinctTable(schema,
+ new DistinctResultsBlock(new DistinctTable(schema,
Arrays.asList(new Record(new Object[]{1, "foo"}), new Record(new
Object[]{2, "bar"})))), queryContext));
LeafStageTransferableBlockOperator operator =
new
LeafStageTransferableBlockOperator(OperatorTestUtil.getDefaultContext(),
@@ -232,7 +231,7 @@ public class LeafStageTransferableBlockOperatorTest {
DataSchema schema = new DataSchema(new String[]{"strCol", "intCol"},
new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.STRING,
DataSchema.ColumnDataType.INT});
List<InstanceResponseBlock> resultsBlockList =
Collections.singletonList(new InstanceResponseBlock(
- new DistinctResultsBlock(mock(DistinctAggregationFunction.class), new
DistinctTable(schema,
+ new DistinctResultsBlock(new DistinctTable(schema,
Arrays.asList(new Record(new Object[]{"foo", 1}), new Record(new
Object[]{"bar", 2})))), queryContext));
LeafStageTransferableBlockOperator operator =
new
LeafStageTransferableBlockOperator(OperatorTestUtil.getDefaultContext(),
@@ -348,9 +347,9 @@ public class LeafStageTransferableBlockOperatorTest {
new DataSchema.ColumnDataType[]{DataSchema.ColumnDataType.STRING,
DataSchema.ColumnDataType.INT});
// When:
- List<InstanceResponseBlock> responseBlockList =
Collections.singletonList(new InstanceResponseBlock(
- new DistinctResultsBlock(mock(DistinctAggregationFunction.class),
- new DistinctTable(resultSchema, Collections.emptyList())),
queryContext));
+ List<InstanceResponseBlock> responseBlockList = Collections.singletonList(
+ new InstanceResponseBlock(new DistinctResultsBlock(new
DistinctTable(resultSchema, Collections.emptyList())),
+ queryContext));
LeafStageTransferableBlockOperator operator =
new
LeafStageTransferableBlockOperator(OperatorTestUtil.getDefaultContext(),
getStaticBlockProcessor(responseBlockList),
getStaticServerQueryRequests(responseBlockList.size()),
diff --git
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
index 5201fdcd2b..a58e76f1f8 100644
---
a/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
+++
b/pinot-segment-spi/src/main/java/org/apache/pinot/segment/spi/AggregationFunctionType.java
@@ -104,7 +104,6 @@ public enum AggregationFunctionType {
PERCENTILERAWTDIGESTMV("percentileRawTDigestMV"),
PERCENTILEKLLMV("percentileKLLMV"),
PERCENTILERAWKLLMV("percentileRawKLLMV"),
- DISTINCT("distinct"),
// boolean aggregate functions
BOOLAND("boolAnd"),
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]