use of io.prestosql.spi.plan.Assignments in project hetu-core by openlookeng.
the class CubeOptimizer method rewriteAggregationNode.
private PlanNode rewriteAggregationNode(CubeRewriteResult cubeRewriteResult, PlanNode inputPlanNode) {
TypeProvider typeProvider = context.getSymbolAllocator().getTypes();
// Add group by
List<Symbol> groupings = aggregationNode.getGroupingKeys().stream().map(Symbol::getName).map(columnRewritesMap::get).map(optimizedPlanMappings::get).collect(Collectors.toList());
Map<Symbol, Symbol> cubeScanToAggOutputMap = new HashMap<>();
// Rewrite AggregationNode using Cube table
ImmutableMap.Builder<Symbol, AggregationNode.Aggregation> aggregationsBuilder = ImmutableMap.builder();
for (CubeRewriteResult.AggregatorSource aggregatorSource : cubeRewriteResult.getAggregationColumns()) {
Type type = cubeRewriteResult.getSymbolMetadataMap().get(aggregatorSource.getOriginalAggSymbol()).getType();
TypeSignature typeSignature = type.getTypeSignature();
ColumnHandle cubeColHandle = cubeRewriteResult.getTableScanNode().getAssignments().get(aggregatorSource.getScanSymbol());
ColumnMetadata cubeColumnMetadata = metadata.getColumnMetadata(context.getSession(), cubeTableHandle, cubeColHandle);
AggregationSignature aggregationSignature = cubeMetadata.getAggregationSignature(cubeColumnMetadata.getName()).orElseThrow(() -> new ColumnNotFoundException(new SchemaTableName("", ""), cubeColHandle.getColumnName()));
String aggFunction = COUNT.getName().equals(aggregationSignature.getFunction()) ? SUM.getName() : aggregationSignature.getFunction();
SymbolReference argument = toSymbolReference(aggregatorSource.getScanSymbol());
FunctionHandle functionHandle = metadata.getFunctionAndTypeManager().lookupFunction(aggFunction, TypeSignatureProvider.fromTypeSignatures(typeSignature));
cubeScanToAggOutputMap.put(aggregatorSource.getScanSymbol(), aggregatorSource.getOriginalAggSymbol());
aggregationsBuilder.put(aggregatorSource.getOriginalAggSymbol(), new AggregationNode.Aggregation(new CallExpression(aggFunction, functionHandle, type, ImmutableList.of(castToRowExpression(argument))), ImmutableList.of(castToRowExpression(argument)), false, Optional.empty(), Optional.empty(), Optional.empty()));
}
PlanNode planNode = inputPlanNode;
AggregationNode aggNode = new AggregationNode(context.getIdAllocator().getNextId(), planNode, aggregationsBuilder.build(), singleGroupingSet(groupings), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty(), AggregationNode.AggregationType.HASH, Optional.empty());
if (cubeRewriteResult.getAvgAggregationColumns().isEmpty()) {
return aggNode;
}
if (!cubeRewriteResult.getComputeAvgDividingSumByCount()) {
Map<Symbol, Expression> aggregateAssignments = new HashMap<>();
for (CubeRewriteResult.AggregatorSource aggregatorSource : cubeRewriteResult.getAggregationColumns()) {
aggregateAssignments.put(aggregatorSource.getOriginalAggSymbol(), toSymbolReference(aggregatorSource.getScanSymbol()));
}
planNode = new ProjectNode(context.getIdAllocator().getNextId(), aggNode, new Assignments(aggregateAssignments.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> castToRowExpression(entry.getValue())))));
} else {
// If there was an AVG aggregation, map it to AVG = SUM/COUNT
Map<Symbol, Expression> projections = new HashMap<>();
aggNode.getGroupingKeys().forEach(symbol -> projections.put(symbol, toSymbolReference(symbol)));
aggNode.getAggregations().keySet().stream().filter(originalAggregationsMap::containsValue).forEach(aggSymbol -> projections.put(aggSymbol, toSymbolReference(aggSymbol)));
// Add AVG = SUM / COUNT
for (CubeRewriteResult.AverageAggregatorSource avgAggSource : cubeRewriteResult.getAvgAggregationColumns()) {
Symbol sumSymbol = cubeScanToAggOutputMap.get(avgAggSource.getSum());
Symbol countSymbol = cubeScanToAggOutputMap.get(avgAggSource.getCount());
Type avgResultType = typeProvider.get(avgAggSource.getOriginalAggSymbol());
ArithmeticBinaryExpression division = new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.DIVIDE, new Cast(toSymbolReference(sumSymbol), avgResultType.getTypeSignature().toString()), new Cast(toSymbolReference(countSymbol), avgResultType.getTypeSignature().toString()));
projections.put(avgAggSource.getOriginalAggSymbol(), division);
}
return new ProjectNode(context.getIdAllocator().getNextId(), aggNode, new Assignments(projections.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, entry -> castToRowExpression(entry.getValue())))));
}
return planNode;
}
use of io.prestosql.spi.plan.Assignments in project hetu-core by openlookeng.
the class ScalarAggregationToJoinRewriter method rewriteScalarAggregation.
private PlanNode rewriteScalarAggregation(LateralJoinNode lateralJoinNode, AggregationNode scalarAggregation, PlanNode scalarAggregationSource, Optional<Expression> joinExpression, Symbol nonNull) {
AssignUniqueId inputWithUniqueColumns = new AssignUniqueId(idAllocator.getNextId(), lateralJoinNode.getInput(), planSymbolAllocator.newSymbol("unique", BIGINT));
JoinNode leftOuterJoin = new JoinNode(idAllocator.getNextId(), JoinNode.Type.LEFT, inputWithUniqueColumns, scalarAggregationSource, ImmutableList.of(), ImmutableList.<Symbol>builder().addAll(inputWithUniqueColumns.getOutputSymbols()).addAll(scalarAggregationSource.getOutputSymbols()).build(), joinExpression.map(OriginalExpressionUtils::castToRowExpression), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
Optional<AggregationNode> aggregationNode = createAggregationNode(scalarAggregation, leftOuterJoin, nonNull);
if (!aggregationNode.isPresent()) {
return lateralJoinNode;
}
Optional<ProjectNode> subqueryProjection = searchFrom(lateralJoinNode.getSubquery(), lookup).where(ProjectNode.class::isInstance).recurseOnlyWhen(EnforceSingleRowNode.class::isInstance).findFirst();
List<Symbol> aggregationOutputSymbols = getTruncatedAggregationSymbols(lateralJoinNode, aggregationNode.get());
if (subqueryProjection.isPresent()) {
Assignments assignments = Assignments.builder().putAll(AssignmentUtils.identityAsSymbolReferences(aggregationOutputSymbols)).putAll(subqueryProjection.get().getAssignments()).build();
return new ProjectNode(idAllocator.getNextId(), aggregationNode.get(), assignments);
} else {
return new ProjectNode(idAllocator.getNextId(), aggregationNode.get(), AssignmentUtils.identityAsSymbolReferences(aggregationOutputSymbols));
}
}
use of io.prestosql.spi.plan.Assignments in project hetu-core by openlookeng.
the class TestTypeValidator method testValidTypeOnlyCoercion.
@Test
public void testValidTypeOnlyCoercion() {
Expression expression = new Cast(toSymbolReference(columnB), StandardTypes.BIGINT);
Assignments assignments = Assignments.builder().put(planSymbolAllocator.newSymbol(expression, BIGINT), castToRowExpression(expression)).put(planSymbolAllocator.newSymbol(toSymbolReference(columnE), VARCHAR), // implicit coercion from varchar(3) to varchar
castToRowExpression(toSymbolReference(columnE))).build();
PlanNode node = new ProjectNode(newId(), baseTableScan, assignments);
assertTypesValid(node);
}
use of io.prestosql.spi.plan.Assignments in project hetu-core by openlookeng.
the class TestTypeValidator method testValidProject.
@Test
public void testValidProject() {
Expression expression1 = new Cast(toSymbolReference(columnB), StandardTypes.BIGINT);
Expression expression2 = new Cast(toSymbolReference(columnC), StandardTypes.BIGINT);
Assignments assignments = Assignments.builder().put(planSymbolAllocator.newSymbol(expression1, BIGINT), castToRowExpression(expression1)).put(planSymbolAllocator.newSymbol(expression2, BIGINT), castToRowExpression(expression2)).build();
PlanNode node = new ProjectNode(newId(), baseTableScan, assignments);
assertTypesValid(node);
}
Aggregations