private static boolean isSymbolToSymbolProjection(ProjectNode project) { return project.getAssignments().getExpressions().stream().allMatch(e -> e instanceof SymbolReference); }
private static boolean isSymbolToSymbolProjection(ProjectNode project) { return project.getAssignments().getExpressions().stream().allMatch(e -> e instanceof SymbolReference); }
@Override public Void visitProject(ProjectNode node, ImmutableList.Builder<Expression> context) { context.addAll(node.getAssignments().getExpressions()); return super.visitProject(node, context); }
@Override public Void visitApply(ApplyNode node, ImmutableList.Builder<Expression> context) { context.addAll(node.getSubqueryAssignments().getExpressions()); return super.visitApply(node, context); } }
@Override public Void visitProject(ProjectNode node, ImmutableList.Builder<Expression> context) { context.addAll(node.getAssignments().getExpressions()); return super.visitProject(node, context); }
@Override public Void visitApply(ApplyNode node, ImmutableList.Builder<Expression> context) { context.addAll(node.getSubqueryAssignments().getExpressions()); return super.visitApply(node, context); } }
@Override public Result apply(ProjectNode parent, Captures captures, Context context) { N targetNode = captures.get(targetCapture); return pruneInputs(targetNode.getOutputSymbols(), parent.getAssignments().getExpressions()) .flatMap(prunedOutputs -> this.pushDownProjectOff(context.getIdAllocator(), targetNode, prunedOutputs)) .map(newChild -> parent.replaceChildren(ImmutableList.of(newChild))) .map(Result::ofPlanNode) .orElse(Result.empty()); }
@Override public Result apply(ProjectNode parent, Captures captures, Context context) { N targetNode = captures.get(targetCapture); return pruneInputs(targetNode.getOutputSymbols(), parent.getAssignments().getExpressions()) .flatMap(prunedOutputs -> this.pushDownProjectOff(context.getIdAllocator(), targetNode, prunedOutputs)) .map(newChild -> parent.replaceChildren(ImmutableList.of(newChild))) .map(Result::ofPlanNode) .orElse(Result.empty()); }
@Override public Result apply(ApplyNode parent, Captures captures, Context context) { if (parent.getSubqueryAssignments().size() != 1) { return Result.empty(); } Expression expression = getOnlyElement(parent.getSubqueryAssignments().getExpressions()); if (!(expression instanceof ExistsPredicate)) { return Result.empty(); } Optional<PlanNode> nonDefaultAggregation = rewriteToNonDefaultAggregation(parent, context); return nonDefaultAggregation .map(Result::ofPlanNode) .orElseGet(() -> Result.ofPlanNode(rewriteToDefaultAggregation(parent, context))); }
@Override public Result apply(ApplyNode parent, Captures captures, Context context) { if (parent.getSubqueryAssignments().size() != 1) { return Result.empty(); } Expression expression = getOnlyElement(parent.getSubqueryAssignments().getExpressions()); if (!(expression instanceof ExistsPredicate)) { return Result.empty(); } Optional<PlanNode> nonDefaultAggregation = rewriteToNonDefaultAggregation(parent, context); return nonDefaultAggregation .map(Result::ofPlanNode) .orElseGet(() -> Result.ofPlanNode(rewriteToDefaultAggregation(parent, context))); }
@Override public PlanNode visitApply(ApplyNode node, RewriteContext<PlanNode> context) { if (node.getSubqueryAssignments().size() != 1) { return context.defaultRewrite(node); } Expression expression = getOnlyElement(node.getSubqueryAssignments().getExpressions()); if (!(expression instanceof QuantifiedComparisonExpression)) { return context.defaultRewrite(node); } QuantifiedComparisonExpression quantifiedComparison = (QuantifiedComparisonExpression) expression; return rewriteQuantifiedApplyNode(node, quantifiedComparison, context); }
@Override public PlanNode visitApply(ApplyNode node, RewriteContext<PlanNode> context) { if (node.getSubqueryAssignments().size() != 1) { return context.defaultRewrite(node); } Expression expression = getOnlyElement(node.getSubqueryAssignments().getExpressions()); if (!(expression instanceof QuantifiedComparisonExpression)) { return context.defaultRewrite(node); } QuantifiedComparisonExpression quantifiedComparison = (QuantifiedComparisonExpression) expression; return rewriteQuantifiedApplyNode(node, quantifiedComparison, context); }
@Override public Void visitProject(ProjectNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child Set<Symbol> inputs = createInputs(source, boundSymbols); for (Expression expression : node.getAssignments().getExpressions()) { Set<Symbol> dependencies = SymbolsExtractor.extractUnique(expression); checkDependencies(inputs, dependencies, "Invalid node. Expression dependencies (%s) not in source plan output (%s)", dependencies, inputs); } return null; }
@Override public Void visitProject(ProjectNode node, Set<Symbol> boundSymbols) { PlanNode source = node.getSource(); source.accept(this, boundSymbols); // visit child Set<Symbol> inputs = createInputs(source, boundSymbols); for (Expression expression : node.getAssignments().getExpressions()) { Set<Symbol> dependencies = SymbolsExtractor.extractUnique(expression); checkDependencies(inputs, dependencies, "Invalid node. Expression dependencies (%s) not in source plan output (%s)", dependencies, inputs); } return null; }
@Override public Void visitApply(ApplyNode node, Set<Symbol> boundSymbols) { Set<Symbol> subqueryCorrelation = ImmutableSet.<Symbol>builder() .addAll(boundSymbols) .addAll(node.getCorrelation()) .build(); node.getInput().accept(this, boundSymbols); // visit child node.getSubquery().accept(this, subqueryCorrelation); // visit child checkDependencies(node.getInput().getOutputSymbols(), node.getCorrelation(), "APPLY input must provide all the necessary correlation symbols for subquery"); checkDependencies(SymbolsExtractor.extractUnique(node.getSubquery()), node.getCorrelation(), "not all APPLY correlation symbols are used in subquery"); ImmutableSet<Symbol> inputs = ImmutableSet.<Symbol>builder() .addAll(createInputs(node.getSubquery(), boundSymbols)) .addAll(createInputs(node.getInput(), boundSymbols)) .build(); for (Expression expression : node.getSubqueryAssignments().getExpressions()) { Set<Symbol> dependencies = SymbolsExtractor.extractUnique(expression); checkDependencies(inputs, dependencies, "Invalid node. Expression dependencies (%s) not in source plan output (%s)", dependencies, inputs); } return null; }
@Override public Result apply(ApplyNode apply, Captures captures, Context context) { Assignments subqueryAssignments = apply.getSubqueryAssignments(); if (subqueryAssignments.size() != 1) { return Result.empty(); } Expression assignmentExpression = getOnlyElement(subqueryAssignments.getExpressions()); if (!(assignmentExpression instanceof InPredicate)) { return Result.empty(); } InPredicate inPredicate = (InPredicate) assignmentExpression; Symbol inPredicateOutputSymbol = getOnlyElement(subqueryAssignments.getSymbols()); return apply(apply, inPredicate, inPredicateOutputSymbol, context.getLookup(), context.getIdAllocator(), context.getSymbolAllocator()); }
@Override public Void visitApply(ApplyNode node, Set<Symbol> boundSymbols) { Set<Symbol> subqueryCorrelation = ImmutableSet.<Symbol>builder() .addAll(boundSymbols) .addAll(node.getCorrelation()) .build(); node.getInput().accept(this, boundSymbols); // visit child node.getSubquery().accept(this, subqueryCorrelation); // visit child checkDependencies(node.getInput().getOutputSymbols(), node.getCorrelation(), "APPLY input must provide all the necessary correlation symbols for subquery"); checkDependencies(SymbolsExtractor.extractUnique(node.getSubquery()), node.getCorrelation(), "not all APPLY correlation symbols are used in subquery"); ImmutableSet<Symbol> inputs = ImmutableSet.<Symbol>builder() .addAll(createInputs(node.getSubquery(), boundSymbols)) .addAll(createInputs(node.getInput(), boundSymbols)) .build(); for (Expression expression : node.getSubqueryAssignments().getExpressions()) { Set<Symbol> dependencies = SymbolsExtractor.extractUnique(expression); checkDependencies(inputs, dependencies, "Invalid node. Expression dependencies (%s) not in source plan output (%s)", dependencies, inputs); } return null; }
@Override public Result apply(ApplyNode apply, Captures captures, Context context) { Assignments subqueryAssignments = apply.getSubqueryAssignments(); if (subqueryAssignments.size() != 1) { return Result.empty(); } Expression assignmentExpression = getOnlyElement(subqueryAssignments.getExpressions()); if (!(assignmentExpression instanceof InPredicate)) { return Result.empty(); } InPredicate inPredicate = (InPredicate) assignmentExpression; Symbol inPredicateOutputSymbol = getOnlyElement(subqueryAssignments.getSymbols()); return apply(apply, inPredicate, inPredicateOutputSymbol, context.getLookup(), context.getIdAllocator(), context.getSymbolAllocator()); }
@Override public Result apply(ApplyNode applyNode, Captures captures, Context context) { if (applyNode.getSubqueryAssignments().size() != 1) { return Result.empty(); } Expression expression = getOnlyElement(applyNode.getSubqueryAssignments().getExpressions()); if (!(expression instanceof InPredicate)) { return Result.empty(); } InPredicate inPredicate = (InPredicate) expression; Symbol semiJoinSymbol = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); SemiJoinNode replacement = new SemiJoinNode(context.getIdAllocator().getNextId(), applyNode.getInput(), applyNode.getSubquery(), Symbol.from(inPredicate.getValue()), Symbol.from(inPredicate.getValueList()), semiJoinSymbol, Optional.empty(), Optional.empty(), Optional.empty()); return Result.ofPlanNode(replacement); } }
@Override public Result apply(ApplyNode applyNode, Captures captures, Context context) { if (applyNode.getSubqueryAssignments().size() != 1) { return Result.empty(); } Expression expression = getOnlyElement(applyNode.getSubqueryAssignments().getExpressions()); if (!(expression instanceof InPredicate)) { return Result.empty(); } InPredicate inPredicate = (InPredicate) expression; Symbol semiJoinSymbol = getOnlyElement(applyNode.getSubqueryAssignments().getSymbols()); SemiJoinNode replacement = new SemiJoinNode(context.getIdAllocator().getNextId(), applyNode.getInput(), applyNode.getSubquery(), Symbol.from(inPredicate.getValue()), Symbol.from(inPredicate.getValueList()), semiJoinSymbol, Optional.empty(), Optional.empty(), Optional.empty()); return Result.ofPlanNode(replacement); } }