use of io.trino.type.TypeCoercion in project trino by trinodb.
the class ExpressionInterpreter method evaluateConstantExpression.
public static Object evaluateConstantExpression(Expression expression, Type expectedType, PlannerContext plannerContext, Session session, AccessControl accessControl, Map<NodeRef<Parameter>, Expression> parameters) {
ExpressionAnalyzer analyzer = createConstantAnalyzer(plannerContext, accessControl, session, parameters, WarningCollector.NOOP);
analyzer.analyze(expression, Scope.create());
Type actualType = analyzer.getExpressionTypes().get(NodeRef.of(expression));
if (!new TypeCoercion(plannerContext.getTypeManager()::getType).canCoerce(actualType, expectedType)) {
throw semanticException(TYPE_MISMATCH, expression, "Cannot cast type %s to %s", actualType.getDisplayName(), expectedType.getDisplayName());
}
Map<NodeRef<Expression>, Type> coercions = ImmutableMap.<NodeRef<Expression>, Type>builder().putAll(analyzer.getExpressionCoercions()).put(NodeRef.of(expression), expectedType).buildOrThrow();
return evaluateConstantExpression(expression, coercions, analyzer.getTypeOnlyCoercions(), plannerContext, session, accessControl, ImmutableSet.of(), parameters);
}
use of io.trino.type.TypeCoercion in project trino by trinodb.
the class QueryPlanner method plan.
public UpdateNode plan(Update node) {
Table table = node.getTable();
TableHandle handle = analysis.getTableHandle(table);
TableSchema tableSchema = plannerContext.getMetadata().getTableSchema(session, handle);
Map<String, ColumnHandle> columnMap = plannerContext.getMetadata().getColumnHandles(session, handle);
List<ColumnSchema> columnsSchemas = tableSchema.getColumns();
List<String> targetColumnNames = node.getAssignments().stream().map(assignment -> assignment.getName().getValue()).collect(toImmutableList());
// Create lists of columnnames and SET expressions, in table column order
ImmutableList.Builder<String> updatedColumnNamesBuilder = ImmutableList.builder();
ImmutableList.Builder<ColumnHandle> updatedColumnHandlesBuilder = ImmutableList.builder();
ImmutableList.Builder<Expression> orderedColumnValuesBuilder = ImmutableList.builder();
for (ColumnSchema columnSchema : columnsSchemas) {
String name = columnSchema.getName();
int index = targetColumnNames.indexOf(name);
if (index >= 0) {
updatedColumnNamesBuilder.add(name);
updatedColumnHandlesBuilder.add(requireNonNull(columnMap.get(name), "columnMap didn't contain name"));
orderedColumnValuesBuilder.add(node.getAssignments().get(index).getValue());
}
}
List<String> updatedColumnNames = updatedColumnNamesBuilder.build();
List<ColumnHandle> updatedColumnHandles = updatedColumnHandlesBuilder.build();
List<Expression> orderedColumnValues = orderedColumnValuesBuilder.build();
// create table scan
RelationPlan relationPlan = new RelationPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, plannerContext, outerContext, session, recursiveSubqueries).process(table, null);
PlanBuilder builder = newPlanBuilder(relationPlan, analysis, lambdaDeclarationToSymbolMap);
if (node.getWhere().isPresent()) {
builder = filter(builder, node.getWhere().get(), node);
}
builder = subqueryPlanner.handleSubqueries(builder, orderedColumnValues, analysis.getSubqueries(node));
builder = builder.appendProjections(orderedColumnValues, symbolAllocator, idAllocator);
PlanAndMappings planAndMappings = coerce(builder, orderedColumnValues, analysis, idAllocator, symbolAllocator, typeCoercion);
builder = planAndMappings.getSubPlan();
ImmutableList.Builder<Symbol> updatedColumnValuesBuilder = ImmutableList.builder();
orderedColumnValues.forEach(columnValue -> updatedColumnValuesBuilder.add(planAndMappings.get(columnValue)));
Symbol rowId = builder.translate(analysis.getRowIdField(table));
updatedColumnValuesBuilder.add(rowId);
List<Symbol> outputs = ImmutableList.of(symbolAllocator.newSymbol("partialrows", BIGINT), symbolAllocator.newSymbol("fragment", VARBINARY));
Optional<PlanNodeId> tableScanId = getIdForLeftTableScan(relationPlan.getRoot());
checkArgument(tableScanId.isPresent(), "tableScanId not present");
// create update node
return new UpdateNode(idAllocator.getNextId(), builder.getRoot(), new UpdateTarget(Optional.empty(), plannerContext.getMetadata().getTableMetadata(session, handle).getTable(), updatedColumnNames, updatedColumnHandles), rowId, updatedColumnValuesBuilder.build(), outputs);
}
use of io.trino.type.TypeCoercion in project trino by trinodb.
the class TestDomainTranslator method testNumericTypeTranslation.
private void testNumericTypeTranslation(NumericValues<?> columnValues, NumericValues<?> literalValues) {
Type columnType = columnValues.getType();
Type literalType = literalValues.getType();
Type superType = new TypeCoercion(functionResolution.getPlannerContext().getTypeManager()::getType).getCommonSuperType(columnType, literalType).orElseThrow(() -> new IllegalArgumentException("incompatible types in test (" + columnType + ", " + literalType + ")"));
Expression max = toExpression(literalValues.getMax(), literalType);
Expression min = toExpression(literalValues.getMin(), literalType);
Expression integerPositive = toExpression(literalValues.getIntegerPositive(), literalType);
Expression integerNegative = toExpression(literalValues.getIntegerNegative(), literalType);
Expression fractionalPositive = toExpression(literalValues.getFractionalPositive(), literalType);
Expression fractionalNegative = toExpression(literalValues.getFractionalNegative(), literalType);
if (!literalType.equals(superType)) {
max = cast(max, superType);
min = cast(min, superType);
integerPositive = cast(integerPositive, superType);
integerNegative = cast(integerNegative, superType);
fractionalPositive = cast(fractionalPositive, superType);
fractionalNegative = cast(fractionalNegative, superType);
}
Symbol columnSymbol = columnValues.getColumn();
Expression columnExpression = columnSymbol.toSymbolReference();
if (!columnType.equals(superType)) {
columnExpression = cast(columnExpression, superType);
}
// greater than or equal
testSimpleComparison(greaterThanOrEqual(columnExpression, integerPositive), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(greaterThanOrEqual(columnExpression, integerNegative), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(greaterThanOrEqual(columnExpression, max), columnSymbol, Range.greaterThan(columnType, columnValues.getMax()));
testSimpleComparison(greaterThanOrEqual(columnExpression, min), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(greaterThanOrEqual(columnExpression, fractionalPositive), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(greaterThanOrEqual(columnExpression, fractionalNegative), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalNegative()));
}
// greater than or equal negated
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, integerPositive)));
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, integerNegative)));
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, max)));
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, min)));
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(greaterThanOrEqual(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(greaterThanOrEqual(columnExpression, integerPositive)), columnSymbol, Range.lessThan(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(greaterThanOrEqual(columnExpression, integerNegative)), columnSymbol, Range.lessThan(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(greaterThanOrEqual(columnExpression, max)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getMax()));
testSimpleComparison(not(greaterThanOrEqual(columnExpression, min)), columnSymbol, Range.lessThan(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(not(greaterThanOrEqual(columnExpression, fractionalPositive)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(not(greaterThanOrEqual(columnExpression, fractionalNegative)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalNegative()));
}
}
// greater than
testSimpleComparison(greaterThan(columnExpression, integerPositive), columnSymbol, Range.greaterThan(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(greaterThan(columnExpression, integerNegative), columnSymbol, Range.greaterThan(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(greaterThan(columnExpression, max), columnSymbol, Range.greaterThan(columnType, columnValues.getMax()));
testSimpleComparison(greaterThan(columnExpression, min), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(greaterThan(columnExpression, fractionalPositive), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(greaterThan(columnExpression, fractionalNegative), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalNegative()));
}
// greater than negated
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(not(greaterThan(columnExpression, integerPositive)));
assertNoFullPushdown(not(greaterThan(columnExpression, integerNegative)));
assertNoFullPushdown(not(greaterThan(columnExpression, max)));
assertNoFullPushdown(not(greaterThan(columnExpression, min)));
assertNoFullPushdown(not(greaterThan(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(greaterThan(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(greaterThan(columnExpression, integerPositive)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(greaterThan(columnExpression, integerNegative)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(greaterThan(columnExpression, max)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getMax()));
testSimpleComparison(not(greaterThan(columnExpression, min)), columnSymbol, Range.lessThan(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(not(greaterThan(columnExpression, fractionalPositive)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(not(greaterThan(columnExpression, fractionalNegative)), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalNegative()));
}
}
// less than or equal
testSimpleComparison(lessThanOrEqual(columnExpression, integerPositive), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(lessThanOrEqual(columnExpression, integerNegative), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(lessThanOrEqual(columnExpression, max), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getMax()));
testSimpleComparison(lessThanOrEqual(columnExpression, min), columnSymbol, Range.lessThan(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(lessThanOrEqual(columnExpression, fractionalPositive), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(lessThanOrEqual(columnExpression, fractionalNegative), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalNegative()));
}
// less than or equal negated
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, integerPositive)));
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, integerNegative)));
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, max)));
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, min)));
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(lessThanOrEqual(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(lessThanOrEqual(columnExpression, integerPositive)), columnSymbol, Range.greaterThan(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(lessThanOrEqual(columnExpression, integerNegative)), columnSymbol, Range.greaterThan(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(lessThanOrEqual(columnExpression, max)), columnSymbol, Range.greaterThan(columnType, columnValues.getMax()));
testSimpleComparison(not(lessThanOrEqual(columnExpression, min)), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(not(lessThanOrEqual(columnExpression, fractionalPositive)), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(not(lessThanOrEqual(columnExpression, fractionalNegative)), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalNegative()));
}
}
// less than
testSimpleComparison(lessThan(columnExpression, integerPositive), columnSymbol, Range.lessThan(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(lessThan(columnExpression, integerNegative), columnSymbol, Range.lessThan(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(lessThan(columnExpression, max), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getMax()));
testSimpleComparison(lessThan(columnExpression, min), columnSymbol, Range.lessThan(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(lessThan(columnExpression, fractionalPositive), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(lessThan(columnExpression, fractionalNegative), columnSymbol, Range.lessThanOrEqual(columnType, columnValues.getFractionalNegative()));
}
// less than negated
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(not(lessThan(columnExpression, integerPositive)));
assertNoFullPushdown(not(lessThan(columnExpression, integerNegative)));
assertNoFullPushdown(not(lessThan(columnExpression, max)));
assertNoFullPushdown(not(lessThan(columnExpression, min)));
assertNoFullPushdown(not(lessThan(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(lessThan(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(lessThan(columnExpression, integerPositive)), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(lessThan(columnExpression, integerNegative)), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(lessThan(columnExpression, max)), columnSymbol, Range.greaterThan(columnType, columnValues.getMax()));
testSimpleComparison(not(lessThan(columnExpression, min)), columnSymbol, Range.greaterThanOrEqual(columnType, columnValues.getMin()));
if (literalValues.isFractional()) {
testSimpleComparison(not(lessThan(columnExpression, fractionalPositive)), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalPositive()));
testSimpleComparison(not(lessThan(columnExpression, fractionalNegative)), columnSymbol, Range.greaterThan(columnType, columnValues.getFractionalNegative()));
}
}
// equal
testSimpleComparison(equal(columnExpression, integerPositive), columnSymbol, Range.equal(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(equal(columnExpression, integerNegative), columnSymbol, Range.equal(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(equal(columnExpression, max), columnSymbol, Domain.none(columnType));
testSimpleComparison(equal(columnExpression, min), columnSymbol, Domain.none(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(equal(columnExpression, fractionalPositive), columnSymbol, Domain.none(columnType));
testSimpleComparison(equal(columnExpression, fractionalNegative), columnSymbol, Domain.none(columnType));
}
// equal negated
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(not(equal(columnExpression, integerPositive)));
assertNoFullPushdown(not(equal(columnExpression, integerNegative)));
assertNoFullPushdown(not(equal(columnExpression, max)));
assertNoFullPushdown(not(equal(columnExpression, min)));
assertNoFullPushdown(not(equal(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(equal(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(equal(columnExpression, integerPositive)), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerPositive()), Range.greaterThan(columnType, columnValues.getIntegerPositive())), false));
testSimpleComparison(not(equal(columnExpression, integerNegative)), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerNegative()), Range.greaterThan(columnType, columnValues.getIntegerNegative())), false));
testSimpleComparison(not(equal(columnExpression, max)), columnSymbol, Domain.notNull(columnType));
testSimpleComparison(not(equal(columnExpression, min)), columnSymbol, Domain.notNull(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(not(equal(columnExpression, fractionalPositive)), columnSymbol, Domain.notNull(columnType));
testSimpleComparison(not(equal(columnExpression, fractionalNegative)), columnSymbol, Domain.notNull(columnType));
}
}
// not equal
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(notEqual(columnExpression, integerPositive));
assertNoFullPushdown(notEqual(columnExpression, integerNegative));
assertNoFullPushdown(notEqual(columnExpression, max));
assertNoFullPushdown(notEqual(columnExpression, min));
assertNoFullPushdown(notEqual(columnExpression, fractionalPositive));
assertNoFullPushdown(notEqual(columnExpression, integerNegative));
} else {
testSimpleComparison(notEqual(columnExpression, integerPositive), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerPositive()), Range.greaterThan(columnType, columnValues.getIntegerPositive())), false));
testSimpleComparison(notEqual(columnExpression, integerNegative), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerNegative()), Range.greaterThan(columnType, columnValues.getIntegerNegative())), false));
testSimpleComparison(notEqual(columnExpression, max), columnSymbol, Domain.notNull(columnType));
testSimpleComparison(notEqual(columnExpression, min), columnSymbol, Domain.notNull(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(notEqual(columnExpression, fractionalPositive), columnSymbol, Domain.notNull(columnType));
testSimpleComparison(notEqual(columnExpression, fractionalNegative), columnSymbol, Domain.notNull(columnType));
}
}
// not equal negated
if (literalValues.isTypeWithNaN()) {
testSimpleComparison(not(notEqual(columnExpression, integerPositive)), columnSymbol, Range.equal(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(notEqual(columnExpression, integerNegative)), columnSymbol, Range.equal(columnType, columnValues.getIntegerNegative()));
assertNoFullPushdown(not(notEqual(columnExpression, max)));
assertNoFullPushdown(not(notEqual(columnExpression, min)));
assertNoFullPushdown(not(notEqual(columnExpression, fractionalPositive)));
assertNoFullPushdown(not(notEqual(columnExpression, fractionalNegative)));
} else {
testSimpleComparison(not(notEqual(columnExpression, integerPositive)), columnSymbol, Range.equal(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(notEqual(columnExpression, integerNegative)), columnSymbol, Range.equal(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(notEqual(columnExpression, max)), columnSymbol, Domain.none(columnType));
testSimpleComparison(not(notEqual(columnExpression, min)), columnSymbol, Domain.none(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(not(notEqual(columnExpression, fractionalPositive)), columnSymbol, Domain.none(columnType));
testSimpleComparison(not(notEqual(columnExpression, fractionalNegative)), columnSymbol, Domain.none(columnType));
}
}
// is distinct from
if (literalValues.isTypeWithNaN()) {
assertNoFullPushdown(isDistinctFrom(columnExpression, integerPositive));
assertNoFullPushdown(isDistinctFrom(columnExpression, integerNegative));
testSimpleComparison(isDistinctFrom(columnExpression, max), columnSymbol, Domain.all(columnType));
testSimpleComparison(isDistinctFrom(columnExpression, min), columnSymbol, Domain.all(columnType));
testSimpleComparison(isDistinctFrom(columnExpression, fractionalPositive), columnSymbol, Domain.all(columnType));
testSimpleComparison(isDistinctFrom(columnExpression, fractionalNegative), columnSymbol, Domain.all(columnType));
} else {
testSimpleComparison(isDistinctFrom(columnExpression, integerPositive), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerPositive()), Range.greaterThan(columnType, columnValues.getIntegerPositive())), true));
testSimpleComparison(isDistinctFrom(columnExpression, integerNegative), columnSymbol, Domain.create(ValueSet.ofRanges(Range.lessThan(columnType, columnValues.getIntegerNegative()), Range.greaterThan(columnType, columnValues.getIntegerNegative())), true));
testSimpleComparison(isDistinctFrom(columnExpression, max), columnSymbol, Domain.all(columnType));
testSimpleComparison(isDistinctFrom(columnExpression, min), columnSymbol, Domain.all(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(isDistinctFrom(columnExpression, fractionalPositive), columnSymbol, Domain.all(columnType));
testSimpleComparison(isDistinctFrom(columnExpression, fractionalNegative), columnSymbol, Domain.all(columnType));
}
}
// is distinct from negated
testSimpleComparison(not(isDistinctFrom(columnExpression, integerPositive)), columnSymbol, Range.equal(columnType, columnValues.getIntegerPositive()));
testSimpleComparison(not(isDistinctFrom(columnExpression, integerNegative)), columnSymbol, Range.equal(columnType, columnValues.getIntegerNegative()));
testSimpleComparison(not(isDistinctFrom(columnExpression, max)), columnSymbol, Domain.none(columnType));
testSimpleComparison(not(isDistinctFrom(columnExpression, min)), columnSymbol, Domain.none(columnType));
if (literalValues.isFractional()) {
testSimpleComparison(not(isDistinctFrom(columnExpression, fractionalPositive)), columnSymbol, Domain.none(columnType));
testSimpleComparison(not(isDistinctFrom(columnExpression, fractionalNegative)), columnSymbol, Domain.none(columnType));
}
}
use of io.trino.type.TypeCoercion in project trino by trinodb.
the class QueryPlanner method aggregate.
private PlanBuilder aggregate(PlanBuilder subPlan, QuerySpecification node) {
if (!analysis.isAggregation(node)) {
return subPlan;
}
ImmutableList.Builder<Expression> inputBuilder = ImmutableList.builder();
analysis.getAggregates(node).stream().map(FunctionCall::getArguments).flatMap(List::stream).filter(// lambda expression is generated at execution time
expression -> !(expression instanceof LambdaExpression)).forEach(inputBuilder::add);
analysis.getAggregates(node).stream().map(FunctionCall::getOrderBy).map(NodeUtils::getSortItemsFromOrderBy).flatMap(List::stream).map(SortItem::getSortKey).forEach(inputBuilder::add);
// filter expressions need to be projected first
analysis.getAggregates(node).stream().map(FunctionCall::getFilter).filter(Optional::isPresent).map(Optional::get).forEach(inputBuilder::add);
GroupingSetAnalysis groupingSetAnalysis = analysis.getGroupingSets(node);
inputBuilder.addAll(groupingSetAnalysis.getComplexExpressions());
List<Expression> inputs = inputBuilder.build();
subPlan = subqueryPlanner.handleSubqueries(subPlan, inputs, analysis.getSubqueries(node));
subPlan = subPlan.appendProjections(inputs, symbolAllocator, idAllocator);
// Add projection to coerce inputs to their site-specific types.
// This is important because the same lexical expression may need to be coerced
// in different ways if it's referenced by multiple arguments to the window function.
// For example, given v::integer,
// avg(v)
// Needs to be rewritten as
// avg(CAST(v AS double))
PlanAndMappings coercions = coerce(subPlan, inputs, analysis, idAllocator, symbolAllocator, typeCoercion);
subPlan = coercions.getSubPlan();
GroupingSetsPlan groupingSets = planGroupingSets(subPlan, node, groupingSetAnalysis);
subPlan = planAggregation(groupingSets.getSubPlan(), groupingSets.getGroupingSets(), groupingSets.getGroupIdSymbol(), analysis.getAggregates(node), coercions::get);
return planGroupingOperations(subPlan, node, groupingSets.getGroupIdSymbol(), groupingSets.getColumnOnlyGroupingSets());
}
Aggregations