public static Assignments identity(Symbol... symbols) { return identity(asList(symbols)); }
private ProjectNode project(PlanNode node, List<Symbol> columns) { return new ProjectNode( idAllocator.getNextId(), node, Assignments.identity(columns)); } }
/** * @return If the node has outputs not in permittedOutputs, returns an identity projection containing only those node outputs also in permittedOutputs. */ public static Optional<PlanNode> restrictOutputs(PlanNodeIdAllocator idAllocator, PlanNode node, Set<Symbol> permittedOutputs) { List<Symbol> restrictedOutputs = node.getOutputSymbols().stream() .filter(permittedOutputs::contains) .collect(toImmutableList()); if (restrictedOutputs.size() == node.getOutputSymbols().size()) { return Optional.empty(); } return Optional.of( new ProjectNode( idAllocator.getNextId(), node, Assignments.identity(restrictedOutputs))); }
private static PlanNode createIndexJoinWithExpectedOutputs(List<Symbol> expectedOutputs, IndexJoinNode.Type type, PlanNode probe, PlanNode index, List<IndexJoinNode.EquiJoinClause> equiJoinClause, PlanNodeIdAllocator idAllocator) { PlanNode result = new IndexJoinNode(idAllocator.getNextId(), type, probe, index, equiJoinClause, Optional.empty(), Optional.empty()); if (!result.getOutputSymbols().equals(expectedOutputs)) { result = new ProjectNode( idAllocator.getNextId(), result, Assignments.identity(expectedOutputs)); } return result; }
@Override public PhysicalOperation visitFilter(FilterNode node, LocalExecutionPlanContext context) { PlanNode sourceNode = node.getSource(); Expression filterExpression = node.getPredicate(); List<Symbol> outputSymbols = node.getOutputSymbols(); return visitScanFilterAndProject(context, node.getId(), sourceNode, Optional.of(filterExpression), Assignments.identity(outputSymbols), outputSymbols); }
private ProjectNode buildProjectedTopN(PlanBuilder planBuilder, Predicate<Symbol> projectionTopN) { Symbol a = planBuilder.symbol("a"); Symbol b = planBuilder.symbol("b"); return planBuilder.project( Assignments.identity(ImmutableList.of(a, b).stream().filter(projectionTopN).collect(toImmutableSet())), planBuilder.topN( COUNT, ImmutableList.of(b), planBuilder.values(a, b))); } }
private ProjectNode buildProjectedLimit(PlanBuilder planBuilder, Predicate<Symbol> projectionFilter) { Symbol a = planBuilder.symbol("a"); Symbol b = planBuilder.symbol("b"); return planBuilder.project( Assignments.identity(Stream.of(a, b).filter(projectionFilter).collect(toImmutableSet())), planBuilder.limit(1, planBuilder.values(a, b))); } }
private static PlanNode buildProjectedCrossJoin(PlanBuilder p, Predicate<Symbol> projectionFilter) { Symbol leftValue = p.symbol("leftValue"); Symbol rightValue = p.symbol("rightValue"); List<Symbol> outputs = ImmutableList.of(leftValue, rightValue); return p.project( Assignments.identity( outputs.stream() .filter(projectionFilter) .collect(toImmutableList())), p.join( JoinNode.Type.INNER, p.values(leftValue), p.values(rightValue), ImmutableList.of(), outputs, Optional.empty(), Optional.empty(), Optional.empty())); } }
private ProjectNode buildProjectedFilter(PlanBuilder planBuilder, Predicate<Symbol> projectionFilter) { Symbol a = planBuilder.symbol("a"); Symbol b = planBuilder.symbol("b"); return planBuilder.project( Assignments.identity(Stream.of(a, b).filter(projectionFilter).collect(toImmutableSet())), planBuilder.filter( planBuilder.expression("b > 5"), planBuilder.values(a, b))); } }
private static PlanNode buildProjectedJoin(PlanBuilder p, Predicate<Symbol> projectionFilter) { Symbol leftKey = p.symbol("leftKey"); Symbol leftValue = p.symbol("leftValue"); Symbol rightKey = p.symbol("rightKey"); Symbol rightValue = p.symbol("rightValue"); List<Symbol> outputs = ImmutableList.of(leftKey, leftValue, rightKey, rightValue); return p.project( Assignments.identity( outputs.stream() .filter(projectionFilter) .collect(toImmutableList())), p.join( JoinNode.Type.INNER, p.values(leftKey, leftValue), p.values(rightKey, rightValue), ImmutableList.of(new JoinNode.EquiJoinClause(leftKey, rightKey)), outputs, Optional.empty(), Optional.empty(), Optional.empty())); } }
private ProjectNode buildProjectedAggregation(PlanBuilder planBuilder, Predicate<Symbol> projectionFilter) { Symbol a = planBuilder.symbol("a"); Symbol b = planBuilder.symbol("b"); Symbol key = planBuilder.symbol("key"); return planBuilder.project( Assignments.identity(ImmutableList.of(a, b).stream().filter(projectionFilter).collect(toImmutableSet())), planBuilder.aggregation(aggregationBuilder -> aggregationBuilder .source(planBuilder.values(key)) .singleGroupingSet(key) .addAggregation(a, planBuilder.expression("count()"), ImmutableList.of()) .addAggregation(b, planBuilder.expression("count()"), ImmutableList.of()))); } }
private static PlanNode buildProjectedSemiJoin(PlanBuilder p, Predicate<Symbol> projectionFilter) { Symbol match = p.symbol("match"); Symbol leftKey = p.symbol("leftKey"); Symbol leftKeyHash = p.symbol("leftKeyHash"); Symbol leftValue = p.symbol("leftValue"); Symbol rightKey = p.symbol("rightKey"); List<Symbol> outputs = ImmutableList.of(match, leftKey, leftKeyHash, leftValue); return p.project( Assignments.identity( outputs.stream() .filter(projectionFilter) .collect(toImmutableList())), p.semiJoin( leftKey, rightKey, match, Optional.of(leftKeyHash), Optional.empty(), p.values(leftKey, leftKeyHash, leftValue), p.values(rightKey))); } }
@Test public void testKeySymbolNotReferenced() { tester().assertThat(new PruneMarkDistinctColumns()) .on(p -> { Symbol key = p.symbol("key"); Symbol mark = p.symbol("mark"); return p.project( Assignments.identity(mark), p.markDistinct(mark, ImmutableList.of(key), p.values(key))); }) .doesNotFire(); }
@Test public void testNotAllOutputsReferenced() { tester().assertThat(new PruneProjectColumns()) .on(p -> { Symbol a = p.symbol("a"); Symbol b = p.symbol("b"); return p.project( Assignments.identity(b), p.project( Assignments.identity(a, b), p.values(a, b))); }) .matches( strictProject( ImmutableMap.of("b", expression("b")), strictProject( ImmutableMap.of("b", expression("b")), values("a", "b")))); }
@Test public void testAllOutputsReferenced() { tester().assertThat(new PruneMarkDistinctColumns()) .on(p -> { Symbol key = p.symbol("key"); Symbol mark = p.symbol("mark"); return p.project( Assignments.identity(key, mark), p.markDistinct(mark, ImmutableList.of(key), p.values(key))); }) .doesNotFire(); } }
private static PlanNode buildProjectedIndexSource(PlanBuilder p, Predicate<Symbol> projectionFilter) { Symbol orderkey = p.symbol("orderkey", INTEGER); Symbol custkey = p.symbol("custkey", INTEGER); Symbol totalprice = p.symbol("totalprice", DOUBLE); ColumnHandle orderkeyHandle = new TpchColumnHandle(orderkey.getName(), INTEGER); ColumnHandle custkeyHandle = new TpchColumnHandle(custkey.getName(), INTEGER); ColumnHandle totalpriceHandle = new TpchColumnHandle(totalprice.getName(), DOUBLE); return p.project( Assignments.identity( ImmutableList.of(orderkey, custkey, totalprice).stream() .filter(projectionFilter) .collect(toImmutableList())), p.indexSource( new TableHandle( new ConnectorId("local"), new TpchTableHandle("orders", TINY_SCALE_FACTOR)), ImmutableSet.of(orderkey, custkey), ImmutableList.of(orderkey, custkey, totalprice), ImmutableMap.of( orderkey, orderkeyHandle, custkey, custkeyHandle, totalprice, totalpriceHandle), TupleDomain.fromFixedValues(ImmutableMap.of(totalpriceHandle, asNull(DOUBLE))))); } }
@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); }
@Test public void testIdentityProjections() { tester().assertThat(new InlineProjections()) .on(p -> p.project( Assignments.of(p.symbol("output"), expression("value")), p.project( Assignments.identity(p.symbol("value")), p.values(p.symbol("value"))))) .doesNotFire(); }