use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class LogicalPlanner method createExplainAnalyzePlan.
private RelationPlan createExplainAnalyzePlan(Analysis analysis, Explain statement) {
RelationPlan underlyingPlan = planStatementWithoutOutput(analysis, statement.getStatement());
PlanNode root = underlyingPlan.getRoot();
Scope scope = analysis.getScope(statement);
VariableReferenceExpression outputVariable = variableAllocator.newVariable(scope.getRelationType().getFieldByIndex(0));
root = new ExplainAnalyzeNode(getSourceLocation(statement), idAllocator.getNextId(), root, outputVariable, statement.isVerbose());
return new RelationPlan(root, scope, ImmutableList.of(outputVariable));
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class RelationPlanner method visitAliasedRelation.
@Override
protected RelationPlan visitAliasedRelation(AliasedRelation node, Void context) {
RelationPlan subPlan = process(node.getRelation(), context);
PlanNode root = subPlan.getRoot();
List<VariableReferenceExpression> mappings = subPlan.getFieldMappings();
if (node.getColumnNames() != null) {
ImmutableList.Builder<VariableReferenceExpression> newMappings = ImmutableList.builder();
Assignments.Builder assignments = Assignments.builder();
// project only the visible columns from the underlying relation
for (int i = 0; i < subPlan.getDescriptor().getAllFieldCount(); i++) {
Field field = subPlan.getDescriptor().getFieldByIndex(i);
if (!field.isHidden()) {
VariableReferenceExpression aliasedColumn = variableAllocator.newVariable(mappings.get(i).getSourceLocation(), field);
assignments.put(aliasedColumn, castToRowExpression(asSymbolReference(subPlan.getFieldMappings().get(i))));
newMappings.add(aliasedColumn);
}
}
root = new ProjectNode(getSourceLocation(node.getLocation()), idAllocator.getNextId(), subPlan.getRoot(), assignments.build(), LOCAL);
mappings = newMappings.build();
}
return new RelationPlan(root, analysis.getScope(node), mappings);
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class CanonicalPlanGenerator method visitAggregation.
@Override
public Optional<PlanNode> visitAggregation(AggregationNode node, Map<VariableReferenceExpression, VariableReferenceExpression> context) {
Optional<PlanNode> source = node.getSource().accept(this, context);
if (!source.isPresent()) {
return Optional.empty();
}
// Steps to get canonical aggregations:
// 1. Transform aggregation into canonical form
// 2. Sort based on canonical aggregation expression
// 3. Get new variable reference for aggregation expression
// 4. Record mapping from original variable reference to the new one
List<AggregationReference> aggregationReferences = node.getAggregations().entrySet().stream().map(entry -> new AggregationReference(getCanonicalAggregation(entry.getValue(), context), entry.getKey())).sorted(comparing(aggregationReference -> aggregationReference.getAggregation().getCall().toString())).collect(toImmutableList());
ImmutableMap.Builder<VariableReferenceExpression, Aggregation> aggregations = ImmutableMap.builder();
for (AggregationReference aggregationReference : aggregationReferences) {
VariableReferenceExpression reference = variableAllocator.newVariable(aggregationReference.getAggregation().getCall());
context.put(aggregationReference.getVariableReferenceExpression(), reference);
aggregations.put(reference, aggregationReference.getAggregation());
}
return Optional.of(new AggregationNode(node.getSourceLocation(), planNodeidAllocator.getNextId(), source.get(), aggregations.build(), getCanonicalGroupingSetDescriptor(node.getGroupingSets(), context), node.getPreGroupedVariables().stream().map(context::get).collect(toImmutableList()), node.getStep(), node.getHashVariable().map(ignored -> variableAllocator.newHashVariable()), node.getGroupIdVariable().map(context::get)));
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class PlanFragmenter method reassignPartitioningHandleIfNecessaryHelper.
private SubPlan reassignPartitioningHandleIfNecessaryHelper(Session session, SubPlan subPlan, PartitioningHandle newOutputPartitioningHandle) {
PlanFragment fragment = subPlan.getFragment();
PlanNode newRoot = fragment.getRoot();
// If the fragment's partitioning is SINGLE or COORDINATOR_ONLY, leave the sources as is (this is for single-node execution)
if (!fragment.getPartitioning().isSingleNode()) {
PartitioningHandleReassigner partitioningHandleReassigner = new PartitioningHandleReassigner(fragment.getPartitioning(), metadata, session);
newRoot = SimplePlanRewriter.rewriteWith(partitioningHandleReassigner, newRoot);
}
PartitioningScheme outputPartitioningScheme = fragment.getPartitioningScheme();
Partitioning newOutputPartitioning = outputPartitioningScheme.getPartitioning();
if (outputPartitioningScheme.getPartitioning().getHandle().getConnectorId().isPresent()) {
// Do not replace the handle if the source's output handle is a system one, e.g. broadcast.
newOutputPartitioning = newOutputPartitioning.withAlternativePartitiongingHandle(newOutputPartitioningHandle);
}
PlanFragment newFragment = new PlanFragment(fragment.getId(), newRoot, fragment.getVariables(), fragment.getPartitioning(), fragment.getTableScanSchedulingOrder(), new PartitioningScheme(newOutputPartitioning, outputPartitioningScheme.getOutputLayout(), outputPartitioningScheme.getHashColumn(), outputPartitioningScheme.isReplicateNullsAndAny(), outputPartitioningScheme.getBucketToPartition()), fragment.getStageExecutionDescriptor(), fragment.isOutputTableWriterFragment(), fragment.getStatsAndCosts(), fragment.getJsonRepresentation());
ImmutableList.Builder<SubPlan> childrenBuilder = ImmutableList.builder();
for (SubPlan child : subPlan.getChildren()) {
childrenBuilder.add(reassignPartitioningHandleIfNecessaryHelper(session, child, fragment.getPartitioning()));
}
return new SubPlan(newFragment, childrenBuilder.build());
}
use of com.facebook.presto.spi.plan.PlanNode in project presto by prestodb.
the class TestDruidPlanOptimizer method testUnionAll.
@Test
public void testUnionAll() {
PlanBuilder planBuilder = createPlanBuilder(defaultSessionHolder);
PlanVariableAllocator variableAllocator = new PlanVariableAllocator();
AggregationNode aggregationOne = simpleAggregationSum(planBuilder, tableScan(planBuilder, druidTableOne, city, fare), variableAllocator, ImmutableList.of(city), fare);
AggregationNode aggregationTwo = simpleAggregationSum(planBuilder, tableScan(planBuilder, druidTableTwo, city, fare), variableAllocator, ImmutableList.of(city), fare);
VariableReferenceExpression groupByColumn = variableAllocator.newVariable(city.getColumnName(), city.getColumnType());
VariableReferenceExpression sumColumn = variableAllocator.newVariable(fare.getColumnName(), fare.getColumnType());
PlanNode originalPlan = new UnionNode(Optional.empty(), planBuilder.getIdAllocator().getNextId(), ImmutableList.of(aggregationOne, aggregationTwo), ImmutableList.of(groupByColumn, sumColumn), ImmutableMap.of(groupByColumn, Stream.concat(aggregationOne.getGroupingKeys().stream(), aggregationTwo.getGroupingKeys().stream()).collect(toImmutableList()), sumColumn, ImmutableList.of(Iterables.getOnlyElement(aggregationOne.getAggregations().keySet()), Iterables.getOnlyElement(aggregationTwo.getAggregations().keySet()))));
PlanNode optimizedPlan = getOptimizedPlan(planBuilder, originalPlan);
PlanMatchPattern tableScanMatcherOne = DruidTableScanMatcher.match(druidTableOne.getTableName(), "SELECT \"city\", sum(fare) FROM \"realtimeOnly\" GROUP BY \"city\"");
PlanMatchPattern tableScanMatcherTwo = DruidTableScanMatcher.match(druidTableTwo.getTableName(), "SELECT \"city\", sum(fare) FROM \"hybrid\" GROUP BY \"city\"");
assertPlanMatch(optimizedPlan, PlanMatchPattern.union(tableScanMatcherOne, tableScanMatcherTwo), typeProvider);
}
Aggregations