use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.
the class RelationPlanner method planCrossJoinUnnest.
private RelationPlan planCrossJoinUnnest(RelationPlan leftPlan, Join joinNode, Unnest node) {
RelationType unnestOutputDescriptor = analysis.getOutputDescriptor(node);
// Create variables for the result of unnesting
ImmutableList.Builder<VariableReferenceExpression> unnestedVariablesBuilder = ImmutableList.builder();
for (Field field : unnestOutputDescriptor.getVisibleFields()) {
VariableReferenceExpression variable = variableAllocator.newVariable(field);
unnestedVariablesBuilder.add(variable);
}
ImmutableList<VariableReferenceExpression> unnestedVariables = unnestedVariablesBuilder.build();
// Add a projection for all the unnest arguments
PlanBuilder planBuilder = initializePlanBuilder(leftPlan);
planBuilder = planBuilder.appendProjections(node.getExpressions(), variableAllocator, idAllocator);
TranslationMap translations = planBuilder.getTranslations();
ProjectNode projectNode = (ProjectNode) planBuilder.getRoot();
ImmutableMap.Builder<VariableReferenceExpression, List<VariableReferenceExpression>> unnestVariables = ImmutableMap.builder();
UnmodifiableIterator<VariableReferenceExpression> unnestedVariablesIterator = unnestedVariables.iterator();
for (Expression expression : node.getExpressions()) {
Type type = analysis.getType(expression);
VariableReferenceExpression inputVariable = new VariableReferenceExpression(getSourceLocation(expression), translations.get(expression).getName(), type);
if (type instanceof ArrayType) {
Type elementType = ((ArrayType) type).getElementType();
if (!SystemSessionProperties.isLegacyUnnest(session) && elementType instanceof RowType) {
ImmutableList.Builder<VariableReferenceExpression> unnestVariableBuilder = ImmutableList.builder();
for (int i = 0; i < ((RowType) elementType).getFields().size(); i++) {
unnestVariableBuilder.add(unnestedVariablesIterator.next());
}
unnestVariables.put(inputVariable, unnestVariableBuilder.build());
} else {
unnestVariables.put(inputVariable, ImmutableList.of(unnestedVariablesIterator.next()));
}
} else if (type instanceof MapType) {
unnestVariables.put(inputVariable, ImmutableList.of(unnestedVariablesIterator.next(), unnestedVariablesIterator.next()));
} else {
throw new IllegalArgumentException("Unsupported type for UNNEST: " + type);
}
}
Optional<VariableReferenceExpression> ordinalityVariable = node.isWithOrdinality() ? Optional.of(unnestedVariablesIterator.next()) : Optional.empty();
checkState(!unnestedVariablesIterator.hasNext(), "Not all output variables were matched with input variables");
UnnestNode unnestNode = new UnnestNode(getSourceLocation(node), idAllocator.getNextId(), projectNode, leftPlan.getFieldMappings(), unnestVariables.build(), ordinalityVariable);
return new RelationPlan(unnestNode, analysis.getScope(joinNode), unnestNode.getOutputVariables());
}
use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.
the class PlanBuilder method appendProjections.
public PlanBuilder appendProjections(Iterable<Expression> expressions, PlanVariableAllocator variableAllocator, PlanNodeIdAllocator idAllocator) {
TranslationMap translations = copyTranslations();
Assignments.Builder projections = Assignments.builder();
// add an identity projection for underlying plan
for (VariableReferenceExpression variable : getRoot().getOutputVariables()) {
projections.put(variable, castToRowExpression(createSymbolReference(variable)));
}
ImmutableMap.Builder<VariableReferenceExpression, Expression> newTranslations = ImmutableMap.builder();
for (Expression expression : expressions) {
VariableReferenceExpression variable = variableAllocator.newVariable(expression, getAnalysis().getTypeWithCoercions(expression));
projections.put(variable, castToRowExpression(translations.rewrite(expression)));
newTranslations.put(variable, expression);
}
// Now append the new translations into the TranslationMap
for (Map.Entry<VariableReferenceExpression, Expression> entry : newTranslations.build().entrySet()) {
translations.put(entry.getValue(), entry.getKey());
}
return new PlanBuilder(translations, new ProjectNode(idAllocator.getNextId(), getRoot(), projections.build()));
}
use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.
the class SimpleFilterProjectSemiJoinStatsRule method doCalculate.
@Override
protected Optional<PlanNodeStatsEstimate> doCalculate(FilterNode node, StatsProvider sourceStats, Lookup lookup, Session session, TypeProvider types) {
PlanNode nodeSource = lookup.resolve(node.getSource());
SemiJoinNode semiJoinNode;
if (nodeSource instanceof ProjectNode) {
ProjectNode projectNode = (ProjectNode) nodeSource;
if (!isIdentity(projectNode)) {
return Optional.empty();
}
PlanNode projectNodeSource = lookup.resolve(projectNode.getSource());
if (!(projectNodeSource instanceof SemiJoinNode)) {
return Optional.empty();
}
semiJoinNode = (SemiJoinNode) projectNodeSource;
} else if (nodeSource instanceof SemiJoinNode) {
semiJoinNode = (SemiJoinNode) nodeSource;
} else {
return Optional.empty();
}
return calculate(node, semiJoinNode, sourceStats, session, types);
}
use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.
the class ScalarAggregationToJoinRewriter method rewriteScalarAggregation.
public PlanNode rewriteScalarAggregation(LateralJoinNode lateralJoinNode, AggregationNode aggregation) {
List<VariableReferenceExpression> correlation = lateralJoinNode.getCorrelation();
Optional<DecorrelatedNode> source = planNodeDecorrelator.decorrelateFilters(lookup.resolve(aggregation.getSource()), correlation);
if (!source.isPresent()) {
return lateralJoinNode;
}
VariableReferenceExpression nonNull = variableAllocator.newVariable("non_null", BooleanType.BOOLEAN);
Assignments scalarAggregationSourceAssignments = Assignments.builder().putAll(identitiesAsSymbolReferences(source.get().getNode().getOutputVariables())).put(nonNull, castToRowExpression(TRUE_LITERAL)).build();
ProjectNode scalarAggregationSourceWithNonNullableVariable = new ProjectNode(idAllocator.getNextId(), source.get().getNode(), scalarAggregationSourceAssignments);
return rewriteScalarAggregation(lateralJoinNode, aggregation, scalarAggregationSourceWithNonNullableVariable, source.get().getCorrelatedPredicates(), nonNull);
}
use of com.facebook.presto.spi.plan.ProjectNode in project presto by prestodb.
the class EliminateCrossJoins method buildJoinTree.
public static PlanNode buildJoinTree(List<VariableReferenceExpression> expectedOutputVariables, JoinGraph graph, List<Integer> joinOrder, PlanNodeIdAllocator idAllocator) {
requireNonNull(expectedOutputVariables, "expectedOutputVariables is null");
requireNonNull(idAllocator, "idAllocator is null");
requireNonNull(graph, "graph is null");
joinOrder = ImmutableList.copyOf(requireNonNull(joinOrder, "joinOrder is null"));
checkArgument(joinOrder.size() >= 2);
PlanNode result = graph.getNode(joinOrder.get(0));
Set<PlanNodeId> alreadyJoinedNodes = new HashSet<>();
alreadyJoinedNodes.add(result.getId());
for (int i = 1; i < joinOrder.size(); i++) {
PlanNode rightNode = graph.getNode(joinOrder.get(i));
alreadyJoinedNodes.add(rightNode.getId());
ImmutableList.Builder<JoinNode.EquiJoinClause> criteria = ImmutableList.builder();
for (JoinGraph.Edge edge : graph.getEdges(rightNode)) {
PlanNode targetNode = edge.getTargetNode();
if (alreadyJoinedNodes.contains(targetNode.getId())) {
criteria.add(new JoinNode.EquiJoinClause(edge.getTargetVariable(), edge.getSourceVariable()));
}
}
result = new JoinNode(result.getSourceLocation(), idAllocator.getNextId(), JoinNode.Type.INNER, result, rightNode, criteria.build(), ImmutableList.<VariableReferenceExpression>builder().addAll(result.getOutputVariables()).addAll(rightNode.getOutputVariables()).build(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of());
}
List<RowExpression> filters = graph.getFilters();
for (RowExpression filter : filters) {
result = new FilterNode(result.getSourceLocation(), idAllocator.getNextId(), result, filter);
}
if (graph.getAssignments().isPresent()) {
result = new ProjectNode(idAllocator.getNextId(), result, Assignments.copyOf(graph.getAssignments().get()));
}
// Some nodes are sensitive to what's produced (e.g., DistinctLimit node)
return restrictOutputs(idAllocator, result, ImmutableSet.copyOf(expectedOutputVariables), true).orElse(result);
}
Aggregations