private boolean isInliningCandidate(Expression expression, ProjectNode node) { // TryExpressions should not be pushed down. However they are now being handled as lambda // passed to a FunctionCall now and should not affect predicate push down. So we want to make // sure the conjuncts are not TryExpressions. verify(AstUtils.preOrder(expression).noneMatch(TryExpression.class::isInstance)); // candidate symbols for inlining are // 1. references to simple constants // 2. references to complex expressions that appear only once // which come from the node, as opposed to an enclosing scope. Set<Symbol> childOutputSet = ImmutableSet.copyOf(node.getOutputSymbols()); Map<Symbol, Long> dependencies = SymbolsExtractor.extractAll(expression).stream() .filter(childOutputSet::contains) .collect(Collectors.groupingBy(Function.identity(), Collectors.counting())); return dependencies.entrySet().stream() .allMatch(entry -> entry.getValue() == 1 || node.getAssignments().get(entry.getKey()) instanceof Literal); }
private static JoinNode leftOuterJoin(PlanNodeIdAllocator idAllocator, AssignUniqueId probeSide, ProjectNode buildSide, Expression joinExpression) { return new JoinNode( idAllocator.getNextId(), JoinNode.Type.LEFT, probeSide, buildSide, ImmutableList.of(), ImmutableList.<Symbol>builder() .addAll(probeSide.getOutputSymbols()) .addAll(buildSide.getOutputSymbols()) .build(), Optional.of(joinExpression), Optional.empty(), Optional.empty(), Optional.empty()); }
private static boolean outputsSameAsSource(ProjectNode node) { return ImmutableSet.copyOf(node.getOutputSymbols()).equals(ImmutableSet.copyOf(node.getSource().getOutputSymbols())); }
Set<Symbol> childOutputSet = ImmutableSet.copyOf(child.getOutputSymbols());
@Override public Expression visitProject(ProjectNode node, Void context) { // TODO: add simple algebraic solver for projection translation (right now only considers identity projections) Expression underlyingPredicate = node.getSource().accept(this, context); List<Expression> projectionEqualities = node.getAssignments().entrySet().stream() .filter(SYMBOL_MATCHES_EXPRESSION.negate()) .map(ENTRY_TO_EQUALITY) .collect(toImmutableList()); return pullExpressionThroughSymbols(combineConjuncts( ImmutableList.<Expression>builder() .addAll(projectionEqualities) .add(underlyingPredicate) .build()), node.getOutputSymbols()); }
@Override public PlanNodeCostEstimate visitProject(ProjectNode node, Void context) { return cpuCost(getStats(node).getOutputSizeInBytes(node.getOutputSymbols(), types)); }
arguments.add(formatOutputs(projectNode.get().getOutputSymbols()));
@Override public Optional<DecorrelationResult> visitProject(ProjectNode node, Void context) { Optional<DecorrelationResult> childDecorrelationResultOptional = lookup.resolve(node.getSource()).accept(this, null); if (!childDecorrelationResultOptional.isPresent()) { return Optional.empty(); } DecorrelationResult childDecorrelationResult = childDecorrelationResultOptional.get(); Set<Symbol> nodeOutputSymbols = ImmutableSet.copyOf(node.getOutputSymbols()); List<Symbol> symbolsToAdd = childDecorrelationResult.symbolsToPropagate.stream() .filter(symbol -> !nodeOutputSymbols.contains(symbol)) .collect(toImmutableList()); Assignments assignments = Assignments.builder() .putAll(node.getAssignments()) .putIdentities(symbolsToAdd) .build(); return Optional.of(new DecorrelationResult( new ProjectNode(idAllocator.getNextId(), childDecorrelationResult.node, assignments), childDecorrelationResult.symbolsToPropagate, childDecorrelationResult.correlatedPredicates, childDecorrelationResult.correlatedSymbolsMapping, childDecorrelationResult.atMostSingleRow)); }
if (!newTargetOutputs.containsAll(projects.get(projects.size() - 1).getOutputSymbols())) {
private static boolean isIdentityProjection(ProjectNode project) { return ImmutableSet.copyOf(project.getOutputSymbols()).equals(ImmutableSet.copyOf(project.getSource().getOutputSymbols())); } }
@Override public PhysicalOperation visitProject(ProjectNode node, LocalExecutionPlanContext context) { PlanNode sourceNode; Optional<Expression> filterExpression = Optional.empty(); if (node.getSource() instanceof FilterNode) { FilterNode filterNode = (FilterNode) node.getSource(); sourceNode = filterNode.getSource(); filterExpression = Optional.of(filterNode.getPredicate()); } else { sourceNode = node.getSource(); } List<Symbol> outputSymbols = node.getOutputSymbols(); return visitScanFilterAndProject(context, node.getId(), sourceNode, filterExpression, node.getAssignments(), outputSymbols); }
List<Symbol> outputLayout = parent.getOutputSymbols();
return Result.ofPlanNode(restrictOutputs(context.getIdAllocator(), result, ImmutableSet.copyOf(project.getOutputSymbols())).orElse(result));
clauses.build(), ImmutableList.<Symbol>builder() .addAll(leftCoercion.getOutputSymbols()) .addAll(rightCoercion.getOutputSymbols()) .build(), Optional.empty(),
@Override public Result apply(ProjectNode project, Captures captures, Context context) { if (isIdentityProjection(project)) { return Result.ofPlanNode(project.getSource()); } PlanNode projectNode = new ProjectNode(context.getIdAllocator().getNextId(), project, Assignments.identity(project.getOutputSymbols())); return Result.ofPlanNode(projectNode); }
Scope scope = Scope.builder().withRelationType(RelationId.anonymous(), new RelationType(fields)).build(); plan = new RelationPlan(projectNode, scope, projectNode.getOutputSymbols());
@Override public Void visitProject(ProjectNode node, Void context) { // visit child node.getSource().accept(this, context); builder.addAll(node.getOutputSymbols()); return null; }
@Override public Expression visitProject(ProjectNode node, Void context) { // TODO: add simple algebraic solver for projection translation (right now only considers identity projections) Expression underlyingPredicate = node.getSource().accept(this, context); List<Expression> projectionEqualities = node.getAssignments().entrySet().stream() .filter(SYMBOL_MATCHES_EXPRESSION.negate()) .map(ENTRY_TO_EQUALITY) .collect(toImmutableList()); return pullExpressionThroughSymbols(combineConjuncts( ImmutableList.<Expression>builder() .addAll(projectionEqualities) .add(underlyingPredicate) .build()), node.getOutputSymbols()); }
@Override public Void visitProject(ProjectNode node, Integer indent) { print(indent, "- Project => [%s]", formatOutputs(node.getOutputSymbols())); for (Map.Entry<Symbol, Expression> entry : node.getAssignments().entrySet()) { if (entry.getValue() instanceof QualifiedNameReference && ((QualifiedNameReference) entry.getValue()).getName().equals(entry.getKey().toQualifiedName())) { // skip identity assignments continue; } print(indent + 2, "%s := %s", entry.getKey(), entry.getValue()); } return processChildren(node, indent + 1); }
private RelationPlan addConstantSampleWeight(RelationPlan subPlan) { ImmutableMap.Builder<Symbol, Expression> projections = ImmutableMap.builder(); for (Symbol symbol : subPlan.getOutputSymbols()) { Expression expression = new QualifiedNameReference(symbol.toQualifiedName()); projections.put(symbol, expression); } Expression one = new LongLiteral("1"); Symbol sampleWeightSymbol = symbolAllocator.newSymbol("$sampleWeight", BIGINT); projections.put(sampleWeightSymbol, one); ProjectNode projectNode = new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()); return new RelationPlan(projectNode, subPlan.getDescriptor(), projectNode.getOutputSymbols(), Optional.of(sampleWeightSymbol)); }