@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)); }
@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)); }
node.getSource(), Assignments.builder() .putIdentities(node.getSource().getOutputSymbols()) .put(partitionCountSymbol, new LongLiteral(Integer.toString(getHashPartitionCount(context.getSession())))) .putAll(envelopeAssignments.build())
node.getSource(), Assignments.builder() .putIdentities(node.getSource().getOutputSymbols()) .put(partitionCountSymbol, new LongLiteral(Integer.toString(getHashPartitionCount(context.getSession())))) .putAll(envelopeAssignments.build())
Assignments.builder() .put(p.symbol("one"), expression("CAST(1 AS bigint)")) .putIdentities(ImmutableList.of(p.symbol("a"), p.symbol("avgOutput"))) .build(), p.project(
Assignments.builder() .put(p.symbol("one"), expression("CAST(1 AS bigint)")) .putIdentities(ImmutableList.of(p.symbol("a"), p.symbol("avgOutput"))) .build(), p.project(
private PlanBuilder handleGroupingOperations(PlanBuilder subPlan, QuerySpecification node, Optional<Symbol> groupIdSymbol, List<Set<FieldId>> groupingSets) { if (analysis.getGroupingOperations(node).isEmpty()) { return subPlan; } TranslationMap newTranslations = subPlan.copyTranslations(); Assignments.Builder projections = Assignments.builder(); projections.putIdentities(subPlan.getRoot().getOutputSymbols()); List<Set<Integer>> descriptor = groupingSets.stream() .map(set -> set.stream() .map(FieldId::getFieldIndex) .collect(toImmutableSet())) .collect(toImmutableList()); for (GroupingOperation groupingOperation : analysis.getGroupingOperations(node)) { Expression rewritten = GroupingOperationRewriter.rewriteGroupingOperation(groupingOperation, descriptor, analysis.getColumnReferenceFields(), groupIdSymbol); Type coercion = analysis.getCoercion(groupingOperation); Symbol symbol = symbolAllocator.newSymbol(rewritten, analysis.getTypeWithCoercions(groupingOperation)); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, metadata.getTypeManager().isTypeOnlyCoercion(analysis.getType(groupingOperation), coercion)); } projections.put(symbol, rewritten); newTranslations.put(groupingOperation, symbol); } return new PlanBuilder(newTranslations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), analysis.getParameters()); }
private Optional<PlanNode> rewriteToNonDefaultAggregation(ApplyNode applyNode, Context context) { checkState(applyNode.getSubquery().getOutputSymbols().isEmpty(), "Expected subquery output symbols to be pruned"); Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); Symbol subqueryTrue = context.getSymbolAllocator().newSymbol("subqueryTrue", BOOLEAN); Assignments.Builder assignments = Assignments.builder(); assignments.putIdentities(applyNode.getInput().getOutputSymbols()); assignments.put(exists, new CoalesceExpression(ImmutableList.of(subqueryTrue.toSymbolReference(), BooleanLiteral.FALSE_LITERAL))); PlanNode subquery = new ProjectNode( context.getIdAllocator().getNextId(), new LimitNode( context.getIdAllocator().getNextId(), applyNode.getSubquery(), 1L, false), Assignments.of(subqueryTrue, TRUE_LITERAL)); PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup()); if (!decorrelator.decorrelateFilters(subquery, applyNode.getCorrelation()).isPresent()) { return Optional.empty(); } return Optional.of(new ProjectNode(context.getIdAllocator().getNextId(), new LateralJoinNode( applyNode.getId(), applyNode.getInput(), subquery, applyNode.getCorrelation(), LEFT, applyNode.getOriginSubquery()), assignments.build())); }
private Optional<PlanNode> rewriteToNonDefaultAggregation(ApplyNode applyNode, Context context) { checkState(applyNode.getSubquery().getOutputSymbols().isEmpty(), "Expected subquery output symbols to be pruned"); Symbol exists = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); Symbol subqueryTrue = context.getSymbolAllocator().newSymbol("subqueryTrue", BOOLEAN); Assignments.Builder assignments = Assignments.builder(); assignments.putIdentities(applyNode.getInput().getOutputSymbols()); assignments.put(exists, new CoalesceExpression(ImmutableList.of(subqueryTrue.toSymbolReference(), BooleanLiteral.FALSE_LITERAL))); PlanNode subquery = new ProjectNode( context.getIdAllocator().getNextId(), new LimitNode( context.getIdAllocator().getNextId(), applyNode.getSubquery(), 1L, false), Assignments.of(subqueryTrue, TRUE_LITERAL)); PlanNodeDecorrelator decorrelator = new PlanNodeDecorrelator(context.getIdAllocator(), context.getLookup()); if (!decorrelator.decorrelateFilters(subquery, applyNode.getCorrelation()).isPresent()) { return Optional.empty(); } return Optional.of(new ProjectNode(context.getIdAllocator().getNextId(), new LateralJoinNode( applyNode.getId(), applyNode.getInput(), subquery, applyNode.getCorrelation(), LEFT, applyNode.getOriginSubquery()), assignments.build())); }
private PlanBuilder handleGroupingOperations(PlanBuilder subPlan, QuerySpecification node, Optional<Symbol> groupIdSymbol, List<Set<FieldId>> groupingSets) { if (analysis.getGroupingOperations(node).isEmpty()) { return subPlan; } TranslationMap newTranslations = subPlan.copyTranslations(); Assignments.Builder projections = Assignments.builder(); projections.putIdentities(subPlan.getRoot().getOutputSymbols()); List<Set<Integer>> descriptor = groupingSets.stream() .map(set -> set.stream() .map(FieldId::getFieldIndex) .collect(toImmutableSet())) .collect(toImmutableList()); for (GroupingOperation groupingOperation : analysis.getGroupingOperations(node)) { Expression rewritten = GroupingOperationRewriter.rewriteGroupingOperation(groupingOperation, descriptor, analysis.getColumnReferenceFields(), groupIdSymbol); Type coercion = analysis.getCoercion(groupingOperation); Symbol symbol = symbolAllocator.newSymbol(rewritten, analysis.getTypeWithCoercions(groupingOperation)); if (coercion != null) { rewritten = new Cast( rewritten, coercion.getTypeSignature().toString(), false, metadata.getTypeManager().isTypeOnlyCoercion(analysis.getType(groupingOperation), coercion)); } projections.put(symbol, rewritten); newTranslations.put(groupingOperation, symbol); } return new PlanBuilder(newTranslations, new ProjectNode(idAllocator.getNextId(), subPlan.getRoot(), projections.build()), analysis.getParameters()); }
@Override public Result apply(LateralJoinNode parent, Captures captures, Context context) { List<ValuesNode> values = searchFrom(parent.getSubquery(), context.getLookup()) .recurseOnlyWhen(ProjectNode.class::isInstance) .where(ValuesNode.class::isInstance) .findAll(); if (values.size() != 1 || !isSingleRowValuesWithNoColumns(values.get(0))) { return Result.empty(); } List<ProjectNode> subqueryProjections = searchFrom(parent.getSubquery(), context.getLookup()) .where(node -> node instanceof ProjectNode && !node.getOutputSymbols().equals(parent.getCorrelation())) .findAll(); if (subqueryProjections.size() == 0) { return Result.ofPlanNode(parent.getInput()); } else if (subqueryProjections.size() == 1) { Assignments assignments = Assignments.builder() .putIdentities(parent.getInput().getOutputSymbols()) .putAll(subqueryProjections.get(0).getAssignments()) .build(); return Result.ofPlanNode(projectNode(parent.getInput(), assignments, context)); } return Result.empty(); }
@Override public Result apply(LateralJoinNode parent, Captures captures, Context context) { List<ValuesNode> values = searchFrom(parent.getSubquery(), context.getLookup()) .recurseOnlyWhen(ProjectNode.class::isInstance) .where(ValuesNode.class::isInstance) .findAll(); if (values.size() != 1 || !isSingleRowValuesWithNoColumns(values.get(0))) { return Result.empty(); } List<ProjectNode> subqueryProjections = searchFrom(parent.getSubquery(), context.getLookup()) .where(node -> node instanceof ProjectNode && !node.getOutputSymbols().equals(parent.getCorrelation())) .findAll(); if (subqueryProjections.size() == 0) { return Result.ofPlanNode(parent.getInput()); } else if (subqueryProjections.size() == 1) { Assignments assignments = Assignments.builder() .putIdentities(parent.getInput().getOutputSymbols()) .putAll(subqueryProjections.get(0).getAssignments()) .build(); return Result.ofPlanNode(projectNode(parent.getInput(), assignments, context)); } return Result.empty(); }
public PlanNode rewriteScalarAggregation(LateralJoinNode lateralJoinNode, AggregationNode aggregation) { List<Symbol> correlation = lateralJoinNode.getCorrelation(); Optional<DecorrelatedNode> source = planNodeDecorrelator.decorrelateFilters(lookup.resolve(aggregation.getSource()), correlation); if (!source.isPresent()) { return lateralJoinNode; } Symbol nonNull = symbolAllocator.newSymbol("non_null", BooleanType.BOOLEAN); Assignments scalarAggregationSourceAssignments = Assignments.builder() .putIdentities(source.get().getNode().getOutputSymbols()) .put(nonNull, TRUE_LITERAL) .build(); ProjectNode scalarAggregationSourceWithNonNullableSymbol = new ProjectNode( idAllocator.getNextId(), source.get().getNode(), scalarAggregationSourceAssignments); return rewriteScalarAggregation( lateralJoinNode, aggregation, scalarAggregationSourceWithNonNullableSymbol, source.get().getCorrelatedPredicates(), nonNull); }
public PlanNode rewriteScalarAggregation(LateralJoinNode lateralJoinNode, AggregationNode aggregation) { List<Symbol> correlation = lateralJoinNode.getCorrelation(); Optional<DecorrelatedNode> source = planNodeDecorrelator.decorrelateFilters(lookup.resolve(aggregation.getSource()), correlation); if (!source.isPresent()) { return lateralJoinNode; } Symbol nonNull = symbolAllocator.newSymbol("non_null", BooleanType.BOOLEAN); Assignments scalarAggregationSourceAssignments = Assignments.builder() .putIdentities(source.get().getNode().getOutputSymbols()) .put(nonNull, TRUE_LITERAL) .build(); ProjectNode scalarAggregationSourceWithNonNullableSymbol = new ProjectNode( idAllocator.getNextId(), source.get().getNode(), scalarAggregationSourceAssignments); return rewriteScalarAggregation( lateralJoinNode, aggregation, scalarAggregationSourceWithNonNullableSymbol, source.get().getCorrelatedPredicates(), nonNull); }
private PlanBuilder explicitCoercionSymbols(PlanBuilder subPlan, Iterable<Symbol> alreadyCoerced, Iterable<? extends Expression> uncoerced) { TranslationMap translations = subPlan.copyTranslations(); Assignments assignments = Assignments.builder() .putAll(coerce(uncoerced, subPlan, translations)) .putIdentities(alreadyCoerced) .build(); return new PlanBuilder(translations, new ProjectNode( idAllocator.getNextId(), subPlan.getRoot(), assignments), analysis.getParameters()); }
public static Assignments identity(Iterable<Symbol> symbols) { return builder().putIdentities(symbols).build(); }
private PlanBuilder explicitCoercionSymbols(PlanBuilder subPlan, Iterable<Symbol> alreadyCoerced, Iterable<? extends Expression> uncoerced) { TranslationMap translations = subPlan.copyTranslations(); Assignments assignments = Assignments.builder() .putAll(coerce(uncoerced, subPlan, translations)) .putIdentities(alreadyCoerced) .build(); return new PlanBuilder(translations, new ProjectNode( idAllocator.getNextId(), subPlan.getRoot(), assignments), analysis.getParameters()); }
private ProjectNode projectExpressions(PlanNode input, Assignments subqueryAssignments) { Assignments assignments = Assignments.builder() .putIdentities(input.getOutputSymbols()) .putAll(subqueryAssignments) .build(); return new ProjectNode( idAllocator.getNextId(), input, assignments); } }
public static Assignments identity(Iterable<Symbol> symbols) { return builder().putIdentities(symbols).build(); }
private ProjectNode projectExpressions(PlanNode input, Assignments subqueryAssignments) { Assignments assignments = Assignments.builder() .putIdentities(input.getOutputSymbols()) .putAll(subqueryAssignments) .build(); return new ProjectNode( idAllocator.getNextId(), input, assignments); } }