use of io.prestosql.spi.plan.ProjectNode in project hetu-core by openlookeng.
the class RelationPlanner method planCrossJoinUnnest.
private RelationPlan planCrossJoinUnnest(RelationPlan leftPlan, Join joinNode, Unnest node) {
RelationType unnestOutputDescriptor = analysis.getOutputDescriptor(node);
// Create symbols for the result of unnesting
ImmutableList.Builder<Symbol> unnestedSymbolsBuilder = ImmutableList.builder();
for (Field field : unnestOutputDescriptor.getVisibleFields()) {
Symbol symbol = planSymbolAllocator.newSymbol(field);
unnestedSymbolsBuilder.add(symbol);
}
ImmutableList<Symbol> unnestedSymbols = unnestedSymbolsBuilder.build();
// Add a projection for all the unnest arguments
PlanBuilder planBuilder = initializePlanBuilder(leftPlan);
planBuilder = planBuilder.appendProjections(node.getExpressions(), planSymbolAllocator, idAllocator);
TranslationMap translations = planBuilder.getTranslations();
ProjectNode projectNode = (ProjectNode) planBuilder.getRoot();
ImmutableMap.Builder<Symbol, List<Symbol>> unnestSymbols = ImmutableMap.builder();
UnmodifiableIterator<Symbol> unnestedSymbolsIterator = unnestedSymbols.iterator();
for (Expression expression : node.getExpressions()) {
Type type = analysis.getType(expression);
Symbol inputSymbol = translations.get(expression);
if (type instanceof ArrayType) {
Type elementType = ((ArrayType) type).getElementType();
if (elementType instanceof RowType) {
ImmutableList.Builder<Symbol> unnestSymbolBuilder = ImmutableList.builder();
for (int i = 0; i < ((RowType) elementType).getFields().size(); i++) {
unnestSymbolBuilder.add(unnestedSymbolsIterator.next());
}
unnestSymbols.put(inputSymbol, unnestSymbolBuilder.build());
} else {
unnestSymbols.put(inputSymbol, ImmutableList.of(unnestedSymbolsIterator.next()));
}
} else if (type instanceof MapType) {
unnestSymbols.put(inputSymbol, ImmutableList.of(unnestedSymbolsIterator.next(), unnestedSymbolsIterator.next()));
} else {
throw new IllegalArgumentException("Unsupported type for UNNEST: " + type);
}
}
Optional<Symbol> ordinalitySymbol = node.isWithOrdinality() ? Optional.of(unnestedSymbolsIterator.next()) : Optional.empty();
checkState(!unnestedSymbolsIterator.hasNext(), "Not all output symbols were matched with input symbols");
UnnestNode unnestNode = new UnnestNode(idAllocator.getNextId(), projectNode, leftPlan.getFieldMappings(), unnestSymbols.build(), ordinalitySymbol);
return new RelationPlan(unnestNode, analysis.getScope(joinNode), unnestNode.getOutputSymbols());
}
use of io.prestosql.spi.plan.ProjectNode in project hetu-core by openlookeng.
the class RelationPlanner method addCoercions.
private RelationPlan addCoercions(RelationPlan plan, Type[] targetColumnTypes) {
List<Symbol> oldSymbols = plan.getFieldMappings();
RelationType oldDescriptor = plan.getDescriptor().withOnlyVisibleFields();
verify(targetColumnTypes.length == oldSymbols.size());
ImmutableList.Builder<Symbol> newSymbols = new ImmutableList.Builder<>();
Field[] newFields = new Field[targetColumnTypes.length];
Assignments.Builder assignments = Assignments.builder();
for (int i = 0; i < targetColumnTypes.length; i++) {
Symbol inputSymbol = oldSymbols.get(i);
Type inputType = planSymbolAllocator.getTypes().get(inputSymbol);
Type outputType = targetColumnTypes[i];
if (!outputType.equals(inputType)) {
Expression cast = new Cast(toSymbolReference(inputSymbol), outputType.getTypeSignature().toString());
Symbol outputSymbol = planSymbolAllocator.newSymbol(cast, outputType);
assignments.put(outputSymbol, castToRowExpression(cast));
newSymbols.add(outputSymbol);
} else {
SymbolReference symbolReference = toSymbolReference(inputSymbol);
Symbol outputSymbol = planSymbolAllocator.newSymbol(symbolReference, outputType);
assignments.put(outputSymbol, castToRowExpression(symbolReference));
newSymbols.add(outputSymbol);
}
Field oldField = oldDescriptor.getFieldByIndex(i);
newFields[i] = new Field(oldField.getRelationAlias(), oldField.getName(), targetColumnTypes[i], oldField.isHidden(), oldField.getOriginTable(), oldField.getOriginColumnName(), oldField.isAliased());
}
ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build());
return new RelationPlan(projectNode, Scope.builder().withRelationType(RelationId.anonymous(), new RelationType(newFields)).build(), newSymbols.build());
}
use of io.prestosql.spi.plan.ProjectNode in project hetu-core by openlookeng.
the class RelationPlanner method visitAliasedRelation.
@Override
protected RelationPlan visitAliasedRelation(AliasedRelation node, Void context) {
RelationPlan subPlan = process(node.getRelation(), context);
PlanNode root = subPlan.getRoot();
List<Symbol> mappings = subPlan.getFieldMappings();
if (node.getColumnNames() != null) {
ImmutableList.Builder<Symbol> 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()) {
Symbol aliasedColumn = planSymbolAllocator.newSymbol(field);
assignments.put(aliasedColumn, castToRowExpression(toSymbolReference(subPlan.getFieldMappings().get(i))));
newMappings.add(aliasedColumn);
}
}
root = new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), assignments.build());
mappings = newMappings.build();
}
return new RelationPlan(root, analysis.getScope(node), mappings);
}
use of io.prestosql.spi.plan.ProjectNode in project hetu-core by openlookeng.
the class SubqueryPlanner method appendExistSubqueryApplyNode.
/**
* Exists is modeled as:
* <pre>
* - Project($0 > 0)
* - Aggregation(COUNT(*))
* - Limit(1)
* -- subquery
* </pre>
*/
private PlanBuilder appendExistSubqueryApplyNode(PlanBuilder subPlan, ExistsPredicate existsPredicate, boolean correlationAllowed) {
if (subPlan.canTranslate(existsPredicate)) {
// given subquery is already appended
return subPlan;
}
PlanBuilder subqueryPlan = createPlanBuilder(existsPredicate.getSubquery());
PlanNode subqueryPlanRoot = subqueryPlan.getRoot();
if (isAggregationWithEmptyGroupBy(subqueryPlanRoot)) {
subPlan.getTranslations().put(existsPredicate, TRUE_LITERAL);
return subPlan;
}
// add an explicit projection that removes all columns
PlanNode subqueryNode = new ProjectNode(idAllocator.getNextId(), subqueryPlan.getRoot(), Assignments.of());
Symbol exists = planSymbolAllocator.newSymbol("exists", BOOLEAN);
subPlan.getTranslations().put(existsPredicate, exists);
ExistsPredicate rewrittenExistsPredicate = new ExistsPredicate(TRUE_LITERAL);
return appendApplyNode(subPlan, existsPredicate.getSubquery(), subqueryNode, Assignments.of(exists, castToRowExpression(rewrittenExistsPredicate)), correlationAllowed);
}
use of io.prestosql.spi.plan.ProjectNode in project hetu-core by openlookeng.
the class ImplementFilteredAggregations method apply.
@Override
public Result apply(AggregationNode aggregationNode, Captures captures, Context context) {
Assignments.Builder newAssignments = Assignments.builder();
ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder();
ImmutableList.Builder<Expression> maskSymbols = ImmutableList.builder();
boolean aggregateWithoutFilterPresent = false;
for (Map.Entry<Symbol, Aggregation> entry : aggregationNode.getAggregations().entrySet()) {
Symbol output = entry.getKey();
// strip the filters
Aggregation aggregation = entry.getValue();
Optional<Symbol> mask = aggregation.getMask();
if (aggregation.getFilter().isPresent()) {
Symbol filter = aggregation.getFilter().get();
Symbol symbol = context.getSymbolAllocator().newSymbol(filter.getName(), BOOLEAN);
verify(!mask.isPresent(), "Expected aggregation without mask symbols, see Rule pattern");
newAssignments.put(symbol, castToRowExpression(toSymbolReference(filter)));
mask = Optional.of(symbol);
maskSymbols.add(toSymbolReference(symbol));
} else {
aggregateWithoutFilterPresent = true;
}
aggregations.put(output, new Aggregation(aggregation.getFunctionCall(), aggregation.getArguments(), aggregation.isDistinct(), Optional.empty(), aggregation.getOrderingScheme(), mask));
}
Expression predicate = TRUE_LITERAL;
if (!aggregationNode.hasNonEmptyGroupingSet() && !aggregateWithoutFilterPresent) {
predicate = combineDisjunctsWithDefault(maskSymbols.build(), TRUE_LITERAL);
}
// identity projection for all existing inputs
newAssignments.putAll(AssignmentUtils.identityAsSymbolReferences(aggregationNode.getSource().getOutputSymbols()));
return Result.ofPlanNode(new AggregationNode(context.getIdAllocator().getNextId(), new FilterNode(context.getIdAllocator().getNextId(), new ProjectNode(context.getIdAllocator().getNextId(), aggregationNode.getSource(), newAssignments.build()), castToRowExpression(predicate)), aggregations.build(), aggregationNode.getGroupingSets(), ImmutableList.of(), aggregationNode.getStep(), aggregationNode.getHashSymbol(), aggregationNode.getGroupIdSymbol(), aggregationNode.getAggregationType(), aggregationNode.getFinalizeSymbol()));
}
Aggregations