use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.
the class TestEffectivePredicateExtractor method testAggregation.
@Test
public void testAggregation() {
PlanNode node = new AggregationNode(newId(), filter(baseTableScan, and(equals(AE, DE), equals(BE, EE), equals(CE, FE), lessThan(DE, bigintLiteral(10)), lessThan(CE, DE), greaterThan(AE, bigintLiteral(2)), equals(EE, FE))), ImmutableMap.of(C, new Aggregation(fakeFunction("test"), ImmutableList.of(), false, Optional.empty(), Optional.empty(), Optional.empty()), D, new Aggregation(fakeFunction("test"), ImmutableList.of(), false, Optional.empty(), Optional.empty(), Optional.empty())), singleGroupingSet(ImmutableList.of(A, B, C)), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
Expression effectivePredicate = effectivePredicateExtractor.extract(SESSION, node, TypeProvider.empty(), typeAnalyzer);
// Rewrite in terms of group by symbols
assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(lessThan(AE, bigintLiteral(10)), lessThan(BE, AE), greaterThan(AE, bigintLiteral(2)), equals(BE, CE)));
}
use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.
the class PlanPrinter method formatAggregation.
public static String formatAggregation(Aggregation aggregation) {
StringBuilder builder = new StringBuilder();
String arguments = Joiner.on(", ").join(aggregation.getArguments());
if (aggregation.getArguments().isEmpty() && "count".equalsIgnoreCase(aggregation.getResolvedFunction().getSignature().getName())) {
arguments = "*";
}
if (aggregation.isDistinct()) {
arguments = "DISTINCT " + arguments;
}
builder.append(aggregation.getResolvedFunction().getSignature().getName()).append('(').append(arguments);
aggregation.getOrderingScheme().ifPresent(orderingScheme -> builder.append(' ').append(orderingScheme.getOrderBy().stream().map(input -> input + " " + orderingScheme.getOrdering(input)).collect(joining(", "))));
builder.append(')');
aggregation.getFilter().ifPresent(expression -> builder.append(" FILTER (WHERE ").append(expression).append(")"));
aggregation.getMask().ifPresent(symbol -> builder.append(" (mask = ").append(symbol).append(")"));
return builder.toString();
}
use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.
the class StatisticAggregations method createPartialAggregations.
public Parts createPartialAggregations(SymbolAllocator symbolAllocator, PlannerContext plannerContext) {
ImmutableMap.Builder<Symbol, Aggregation> partialAggregation = ImmutableMap.builder();
ImmutableMap.Builder<Symbol, Aggregation> finalAggregation = ImmutableMap.builder();
ImmutableMap.Builder<Symbol, Symbol> mappings = ImmutableMap.builder();
for (Map.Entry<Symbol, Aggregation> entry : aggregations.entrySet()) {
Aggregation originalAggregation = entry.getValue();
ResolvedFunction resolvedFunction = originalAggregation.getResolvedFunction();
AggregationFunctionMetadata functionMetadata = plannerContext.getMetadata().getAggregationFunctionMetadata(resolvedFunction);
List<Type> intermediateTypes = functionMetadata.getIntermediateTypes().stream().map(plannerContext.getTypeManager()::getType).collect(toImmutableList());
Type intermediateType = intermediateTypes.size() == 1 ? intermediateTypes.get(0) : RowType.anonymous(intermediateTypes);
Symbol partialSymbol = symbolAllocator.newSymbol(resolvedFunction.getSignature().getName(), intermediateType);
mappings.put(entry.getKey(), partialSymbol);
partialAggregation.put(partialSymbol, new Aggregation(resolvedFunction, originalAggregation.getArguments(), originalAggregation.isDistinct(), originalAggregation.getFilter(), originalAggregation.getOrderingScheme(), originalAggregation.getMask()));
finalAggregation.put(entry.getKey(), new Aggregation(resolvedFunction, ImmutableList.of(partialSymbol.toSymbolReference()), false, Optional.empty(), Optional.empty(), Optional.empty()));
}
groupingSymbols.forEach(symbol -> mappings.put(symbol, symbol));
return new Parts(new StatisticAggregations(partialAggregation.buildOrThrow(), groupingSymbols), new StatisticAggregations(finalAggregation.buildOrThrow(), groupingSymbols), mappings.buildOrThrow());
}
use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.
the class PlanBuilder method aggregation.
public Aggregation aggregation(Expression expression, List<Type> inputTypes) {
checkArgument(expression instanceof FunctionCall);
FunctionCall aggregation = (FunctionCall) expression;
ResolvedFunction resolvedFunction = metadata.resolveFunction(session, aggregation.getName(), TypeSignatureProvider.fromTypes(inputTypes));
return new Aggregation(resolvedFunction, aggregation.getArguments(), aggregation.isDistinct(), aggregation.getFilter().map(Symbol::from), aggregation.getOrderBy().map(OrderingScheme::fromOrderBy), Optional.empty());
}
use of io.trino.sql.planner.plan.AggregationNode.Aggregation in project trino by trinodb.
the class PushAggregationThroughOuterJoin method createAggregationOverNull.
private MappedAggregationInfo createAggregationOverNull(AggregationNode referenceAggregation, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator) {
// Create a values node that consists of a single row of nulls.
// Map the output symbols from the referenceAggregation's source
// to symbol references for the new values node.
ImmutableList.Builder<Symbol> nullSymbols = ImmutableList.builder();
ImmutableList.Builder<Expression> nullLiterals = ImmutableList.builder();
ImmutableMap.Builder<Symbol, Symbol> sourcesSymbolMappingBuilder = ImmutableMap.builder();
for (Symbol sourceSymbol : referenceAggregation.getSource().getOutputSymbols()) {
Type type = symbolAllocator.getTypes().get(sourceSymbol);
nullLiterals.add(new Cast(new NullLiteral(), toSqlType(type)));
Symbol nullSymbol = symbolAllocator.newSymbol("null", type);
nullSymbols.add(nullSymbol);
sourcesSymbolMappingBuilder.put(sourceSymbol, nullSymbol);
}
ValuesNode nullRow = new ValuesNode(idAllocator.getNextId(), nullSymbols.build(), ImmutableList.of(new Row(nullLiterals.build())));
// For each aggregation function in the reference node, create a corresponding aggregation function
// that points to the nullRow. Map the symbols from the aggregations in referenceAggregation to the
// symbols in these new aggregations.
ImmutableMap.Builder<Symbol, Symbol> aggregationsSymbolMappingBuilder = ImmutableMap.builder();
ImmutableMap.Builder<Symbol, AggregationNode.Aggregation> aggregationsOverNullBuilder = ImmutableMap.builder();
SymbolMapper mapper = symbolMapper(sourcesSymbolMappingBuilder.buildOrThrow());
for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : referenceAggregation.getAggregations().entrySet()) {
Symbol aggregationSymbol = entry.getKey();
Aggregation overNullAggregation = mapper.map(entry.getValue());
Symbol overNullSymbol = symbolAllocator.newSymbol(overNullAggregation.getResolvedFunction().getSignature().getName(), symbolAllocator.getTypes().get(aggregationSymbol));
aggregationsOverNullBuilder.put(overNullSymbol, overNullAggregation);
aggregationsSymbolMappingBuilder.put(aggregationSymbol, overNullSymbol);
}
Map<Symbol, Symbol> aggregationsSymbolMapping = aggregationsSymbolMappingBuilder.buildOrThrow();
// create an aggregation node whose source is the null row.
AggregationNode aggregationOverNullRow = new AggregationNode(idAllocator.getNextId(), nullRow, aggregationsOverNullBuilder.buildOrThrow(), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
return new MappedAggregationInfo(aggregationOverNullRow, aggregationsSymbolMapping);
}
Aggregations