Search in sources :

Example 1 with IntersectNode

use of io.trino.sql.planner.plan.IntersectNode in project trino by trinodb.

the class SetOperationMerge method mergeFirstSource.

/**
 * Only merge first source node. This method is assumed to be used for EXCEPT, which is a non-associative set operation.
 * Provides a correct plan transformation also for associative set operations: UNION and INTERSECT.
 *
 * @return Merged plan node if applied.
 */
public Optional<SetOperationNode> mergeFirstSource() {
    Lookup lookup = context.getLookup();
    List<PlanNode> sources = node.getSources().stream().flatMap(lookup::resolveGroup).collect(Collectors.toList());
    PlanNode child = sources.get(0);
    // Determine if set operations can be merged and whether the resulting set operation is quantified DISTINCT or ALL
    Optional<Boolean> mergedQuantifier = mergedQuantifierIsDistinct(node, child);
    if (mergedQuantifier.isEmpty()) {
        return Optional.empty();
    }
    ImmutableListMultimap.Builder<Symbol, Symbol> newMappingsBuilder = ImmutableListMultimap.builder();
    // Merge all sources of the first source.
    addMergedMappings((SetOperationNode) child, 0, newMappingsBuilder);
    // Keep remaining as it is
    for (int i = 1; i < sources.size(); i++) {
        PlanNode source = sources.get(i);
        addOriginalMappings(source, i, newMappingsBuilder);
    }
    if (node instanceof UnionNode) {
        return Optional.of(new UnionNode(node.getId(), newSources, newMappingsBuilder.build(), node.getOutputSymbols()));
    }
    if (node instanceof IntersectNode) {
        return Optional.of(new IntersectNode(node.getId(), newSources, newMappingsBuilder.build(), node.getOutputSymbols(), mergedQuantifier.get()));
    }
    if (node instanceof ExceptNode) {
        return Optional.of(new ExceptNode(node.getId(), newSources, newMappingsBuilder.build(), node.getOutputSymbols(), mergedQuantifier.get()));
    }
    throw new IllegalArgumentException("unexpected node type: " + node.getClass().getSimpleName());
}
Also used : Symbol(io.trino.sql.planner.Symbol) PlanNode(io.trino.sql.planner.plan.PlanNode) UnionNode(io.trino.sql.planner.plan.UnionNode) ExceptNode(io.trino.sql.planner.plan.ExceptNode) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) Lookup(io.trino.sql.planner.iterative.Lookup) IntersectNode(io.trino.sql.planner.plan.IntersectNode)

Example 2 with IntersectNode

use of io.trino.sql.planner.plan.IntersectNode in project trino by trinodb.

the class TestMergeIntersect method buildNestedIntersect.

private PlanNode buildNestedIntersect(PlanBuilder builder, boolean lefSourceDistinct, boolean rightSourceDistinct, boolean parentDistinct) {
    Symbol v1 = builder.symbol("v_1");
    Symbol v2 = builder.symbol("v_2");
    Symbol v3 = builder.symbol("v_3");
    Symbol v4 = builder.symbol("v_4");
    Symbol a = builder.symbol("a");
    Symbol b = builder.symbol("b");
    Symbol c = builder.symbol("c");
    IntersectNode child1 = builder.intersect(ImmutableListMultimap.of(a, v1, a, v2), ImmutableList.of(builder.values(v1), builder.values(v2)), lefSourceDistinct);
    IntersectNode child2 = builder.intersect(ImmutableListMultimap.of(b, v3, b, v4), ImmutableList.of(builder.values(v3), builder.values(v4)), rightSourceDistinct);
    return builder.intersect(ImmutableListMultimap.of(c, a, c, b), ImmutableList.of(child1, child2), parentDistinct);
}
Also used : Symbol(io.trino.sql.planner.Symbol) IntersectNode(io.trino.sql.planner.plan.IntersectNode)

Example 3 with IntersectNode

use of io.trino.sql.planner.plan.IntersectNode in project trino by trinodb.

the class RelationPlanner method visitIntersect.

@Override
protected RelationPlan visitIntersect(Intersect node, Void context) {
    checkArgument(!node.getRelations().isEmpty(), "No relations specified for INTERSECT");
    SetOperationPlan setOperationPlan = process(node);
    PlanNode planNode = new IntersectNode(idAllocator.getNextId(), setOperationPlan.getSources(), setOperationPlan.getSymbolMapping(), ImmutableList.copyOf(setOperationPlan.getSymbolMapping().keySet()), node.isDistinct());
    return new RelationPlan(planNode, analysis.getScope(node), planNode.getOutputSymbols(), outerContext);
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) IntersectNode(io.trino.sql.planner.plan.IntersectNode)

Example 4 with IntersectNode

use of io.trino.sql.planner.plan.IntersectNode in project trino by trinodb.

the class SetOperationMerge method merge.

/**
 * Merge all matching source nodes. This method is assumed to be used only for associative set operations: UNION and INTERSECT.
 *
 * @return Merged plan node if applied.
 */
public Optional<SetOperationNode> merge() {
    checkState(node instanceof UnionNode || node instanceof IntersectNode, "unexpected node type: %s", node.getClass().getSimpleName());
    Lookup lookup = context.getLookup();
    List<PlanNode> sources = node.getSources().stream().flatMap(lookup::resolveGroup).collect(Collectors.toList());
    ImmutableListMultimap.Builder<Symbol, Symbol> newMappingsBuilder = ImmutableListMultimap.builder();
    boolean resultIsDistinct = false;
    boolean rewritten = false;
    for (int i = 0; i < sources.size(); i++) {
        PlanNode source = sources.get(i);
        // Determine if set operations can be merged and whether the resulting set operation is quantified DISTINCT or ALL
        Optional<Boolean> mergedQuantifier = mergedQuantifierIsDistinct(node, source);
        if (mergedQuantifier.isPresent()) {
            addMergedMappings((SetOperationNode) source, i, newMappingsBuilder);
            resultIsDistinct |= mergedQuantifier.get();
            rewritten = true;
        } else {
            // Keep mapping as it is
            addOriginalMappings(source, i, newMappingsBuilder);
        }
    }
    if (!rewritten) {
        return Optional.empty();
    }
    if (node instanceof UnionNode) {
        return Optional.of(new UnionNode(node.getId(), newSources, newMappingsBuilder.build(), node.getOutputSymbols()));
    }
    return Optional.of(new IntersectNode(node.getId(), newSources, newMappingsBuilder.build(), node.getOutputSymbols(), resultIsDistinct));
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) UnionNode(io.trino.sql.planner.plan.UnionNode) Symbol(io.trino.sql.planner.Symbol) ImmutableListMultimap(com.google.common.collect.ImmutableListMultimap) Lookup(io.trino.sql.planner.iterative.Lookup) IntersectNode(io.trino.sql.planner.plan.IntersectNode)

Aggregations

IntersectNode (io.trino.sql.planner.plan.IntersectNode)4 Symbol (io.trino.sql.planner.Symbol)3 PlanNode (io.trino.sql.planner.plan.PlanNode)3 ImmutableListMultimap (com.google.common.collect.ImmutableListMultimap)2 Lookup (io.trino.sql.planner.iterative.Lookup)2 UnionNode (io.trino.sql.planner.plan.UnionNode)2 ExceptNode (io.trino.sql.planner.plan.ExceptNode)1