@Override public PlanNode replaceChildren(List<PlanNode> newChildren) { checkArgument(newChildren.size() == 2, "expected newChildren to contain 2 nodes"); return new SemiJoinNode( getId(), newChildren.get(0), newChildren.get(1), sourceJoinSymbol, filteringSourceJoinSymbol, semiJoinOutput, sourceHashSymbol, filteringSourceHashSymbol, distributionType); } }
@Override public PlanNode replaceChildren(List<PlanNode> newChildren) { checkArgument(newChildren.size() == 2, "expected newChildren to contain 2 nodes"); return new SemiJoinNode( getId(), newChildren.get(0), newChildren.get(1), sourceJoinSymbol, filteringSourceJoinSymbol, semiJoinOutput, sourceHashSymbol, filteringSourceHashSymbol, distributionType); } }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Set<Symbol>> context) { ImmutableSet.Builder<Symbol> sourceInputsBuilder = ImmutableSet.builder(); sourceInputsBuilder.addAll(context.get()).add(node.getSourceJoinSymbol()); if (node.getSourceHashSymbol().isPresent()) { sourceInputsBuilder.add(node.getSourceHashSymbol().get()); } Set<Symbol> sourceInputs = sourceInputsBuilder.build(); ImmutableSet.Builder<Symbol> filteringSourceInputBuilder = ImmutableSet.builder(); filteringSourceInputBuilder.add(node.getFilteringSourceJoinSymbol()); if (node.getFilteringSourceHashSymbol().isPresent()) { filteringSourceInputBuilder.add(node.getFilteringSourceHashSymbol().get()); } Set<Symbol> filteringSourceInputs = filteringSourceInputBuilder.build(); PlanNode source = context.rewrite(node.getSource(), sourceInputs); PlanNode filteringSource = context.rewrite(node.getFilteringSource(), filteringSourceInputs); return new SemiJoinNode(node.getId(), source, filteringSource, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType()); }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Set<Symbol>> context) { ImmutableSet.Builder<Symbol> sourceInputsBuilder = ImmutableSet.builder(); sourceInputsBuilder.addAll(context.get()).add(node.getSourceJoinSymbol()); if (node.getSourceHashSymbol().isPresent()) { sourceInputsBuilder.add(node.getSourceHashSymbol().get()); } Set<Symbol> sourceInputs = sourceInputsBuilder.build(); ImmutableSet.Builder<Symbol> filteringSourceInputBuilder = ImmutableSet.builder(); filteringSourceInputBuilder.add(node.getFilteringSourceJoinSymbol()); if (node.getFilteringSourceHashSymbol().isPresent()) { filteringSourceInputBuilder.add(node.getFilteringSourceHashSymbol().get()); } Set<Symbol> filteringSourceInputs = filteringSourceInputBuilder.build(); PlanNode source = context.rewrite(node.getSource(), sourceInputs); PlanNode filteringSource = context.rewrite(node.getFilteringSource(), filteringSourceInputs); return new SemiJoinNode(node.getId(), source, filteringSource, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType()); }
@Override public PlanWithProperties visitSemiJoin(SemiJoinNode node, HashComputationSet parentPreference) { Optional<HashComputation> sourceHashComputation = computeHash(ImmutableList.of(node.getSourceJoinSymbol())); PlanWithProperties source = planAndEnforce( node.getSource(), new HashComputationSet(sourceHashComputation), true, new HashComputationSet(sourceHashComputation)); Symbol sourceHashSymbol = source.getRequiredHashSymbol(sourceHashComputation.get()); Optional<HashComputation> filterHashComputation = computeHash(ImmutableList.of(node.getFilteringSourceJoinSymbol())); HashComputationSet requiredHashes = new HashComputationSet(filterHashComputation); PlanWithProperties filteringSource = planAndEnforce(node.getFilteringSource(), requiredHashes, true, requiredHashes); Symbol filteringSourceHashSymbol = filteringSource.getRequiredHashSymbol(filterHashComputation.get()); return new PlanWithProperties( new SemiJoinNode( node.getId(), source.getNode(), filteringSource.getNode(), node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), Optional.of(sourceHashSymbol), Optional.of(filteringSourceHashSymbol), node.getDistributionType()), source.getHashSymbols()); }
@Override public PlanWithProperties visitSemiJoin(SemiJoinNode node, HashComputationSet parentPreference) { Optional<HashComputation> sourceHashComputation = computeHash(ImmutableList.of(node.getSourceJoinSymbol())); PlanWithProperties source = planAndEnforce( node.getSource(), new HashComputationSet(sourceHashComputation), true, new HashComputationSet(sourceHashComputation)); Symbol sourceHashSymbol = source.getRequiredHashSymbol(sourceHashComputation.get()); Optional<HashComputation> filterHashComputation = computeHash(ImmutableList.of(node.getFilteringSourceJoinSymbol())); HashComputationSet requiredHashes = new HashComputationSet(filterHashComputation); PlanWithProperties filteringSource = planAndEnforce(node.getFilteringSource(), requiredHashes, true, requiredHashes); Symbol filteringSourceHashSymbol = filteringSource.getRequiredHashSymbol(filterHashComputation.get()); return new PlanWithProperties( new SemiJoinNode( node.getId(), source.getNode(), filteringSource.getNode(), node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), Optional.of(sourceHashSymbol), Optional.of(filteringSourceHashSymbol), node.getDistributionType()), source.getHashSymbols()); }
@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); } }
public class AggregationBuilder { private PlanNode source; private Map<Symbol, Aggregation> assignments = new HashMap<>(); private AggregationNode.GroupingSetDescriptor groupingSets; private List<Symbol> preGroupedSymbols = new ArrayList<>(); private Step step = Step.SINGLE; private Optional<Symbol> hashSymbol = Optional.empty(); private Optional<Symbol> groupIdSymbol = Optional.empty(); public AggregationBuilder source(PlanNode source) { this.source = source; return this; } public AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes) { return addAggregation(output, expression, inputTypes, Optional.empty()); } public AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes, Symbol mask) { return addAggregation(output, expression, inputTypes, Optional.of(mask)); } private AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes, Optional<Symbol> mask) { checkArgument(expression instanceof FunctionCall); FunctionCall aggregation = (FunctionCall) expression;
public class AggregationBuilder { private PlanNode source; private Map<Symbol, Aggregation> assignments = new HashMap<>(); private AggregationNode.GroupingSetDescriptor groupingSets; private List<Symbol> preGroupedSymbols = new ArrayList<>(); private Step step = Step.SINGLE; private Optional<Symbol> hashSymbol = Optional.empty(); private Optional<Symbol> groupIdSymbol = Optional.empty(); public AggregationBuilder source(PlanNode source) { this.source = source; return this; } public AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes) { return addAggregation(output, expression, inputTypes, Optional.empty()); } public AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes, Symbol mask) { return addAggregation(output, expression, inputTypes, Optional.of(mask)); } private AggregationBuilder addAggregation(Symbol output, Expression expression, List<Type> inputTypes, Optional<Symbol> mask) { checkArgument(expression instanceof FunctionCall); FunctionCall aggregation = (FunctionCall) expression;
@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); } }
output = new SemiJoinNode(node.getId(), rewrittenSource, rewrittenFilteringSource, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType());
output = new SemiJoinNode(node.getId(), rewrittenSource, rewrittenFilteringSource, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType());
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Void> context) { PlanNode sourceRewritten = context.rewrite(node.getSource(), context.get()); PlanNode filteringSourceRewritten = context.rewrite(node.getFilteringSource(), context.get()); SemiJoinNode.DistributionType targetJoinDistributionType = getTargetSemiJoinDistributionType(isDeleteQuery); return new SemiJoinNode( node.getId(), sourceRewritten, filteringSourceRewritten, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), Optional.of(targetJoinDistributionType)); }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Void> context) { PlanNode sourceRewritten = context.rewrite(node.getSource(), context.get()); PlanNode filteringSourceRewritten = context.rewrite(node.getFilteringSource(), context.get()); SemiJoinNode.DistributionType targetJoinDistributionType = getTargetSemiJoinDistributionType(isDeleteQuery); return new SemiJoinNode( node.getId(), sourceRewritten, filteringSourceRewritten, node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), Optional.of(targetJoinDistributionType)); }
@Test public void testSemiJoin() { PlanNode node = new SemiJoinNode(newId(), filter(baseTableScan, and(greaterThan(AE, bigintLiteral(10)), lessThan(AE, bigintLiteral(100)))), filter(baseTableScan, greaterThan(AE, bigintLiteral(5))), A, B, C, Optional.empty(), Optional.empty(), Optional.empty()); Expression effectivePredicate = effectivePredicateExtractor.extract(node); // Currently, only pull predicates through the source plan assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(and(greaterThan(AE, bigintLiteral(10)), lessThan(AE, bigintLiteral(100))))); }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<LimitContext> context) { PlanNode source = context.rewrite(node.getSource(), context.get()); if (source != node.getSource()) { return new SemiJoinNode( node.getId(), source, node.getFilteringSource(), node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType()); } return node; } }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<LimitContext> context) { PlanNode source = context.rewrite(node.getSource(), context.get()); if (source != node.getSource()) { return new SemiJoinNode( node.getId(), source, node.getFilteringSource(), node.getSourceJoinSymbol(), node.getFilteringSourceJoinSymbol(), node.getSemiJoinOutput(), node.getSourceHashSymbol(), node.getFilteringSourceHashSymbol(), node.getDistributionType()); } return node; } }
@Test public void testSemiJoin() { PlanNode node = new SemiJoinNode(newId(), filter(baseTableScan, and(greaterThan(AE, bigintLiteral(10)), lessThan(AE, bigintLiteral(100)))), filter(baseTableScan, greaterThan(AE, bigintLiteral(5))), A, B, C, Optional.empty(), Optional.empty(), Optional.empty()); Expression effectivePredicate = effectivePredicateExtractor.extract(node); // Currently, only pull predicates through the source plan assertEquals(normalizeConjuncts(effectivePredicate), normalizeConjuncts(and(greaterThan(AE, bigintLiteral(10)), lessThan(AE, bigintLiteral(100))))); }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getSource()); PlanNode filteringSource = context.rewrite(node.getFilteringSource()); return new SemiJoinNode( node.getId(), source, filteringSource, canonicalize(node.getSourceJoinSymbol()), canonicalize(node.getFilteringSourceJoinSymbol()), canonicalize(node.getSemiJoinOutput()), canonicalize(node.getSourceHashSymbol()), canonicalize(node.getFilteringSourceHashSymbol()), node.getDistributionType()); }
@Override public PlanNode visitSemiJoin(SemiJoinNode node, RewriteContext<Void> context) { PlanNode source = context.rewrite(node.getSource()); PlanNode filteringSource = context.rewrite(node.getFilteringSource()); return new SemiJoinNode( node.getId(), source, filteringSource, canonicalize(node.getSourceJoinSymbol()), canonicalize(node.getFilteringSourceJoinSymbol()), canonicalize(node.getSemiJoinOutput()), canonicalize(node.getSourceHashSymbol()), canonicalize(node.getFilteringSourceHashSymbol()), node.getDistributionType()); }