Search in sources :

Example 96 with ProjectNode

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

the class RelationPlanner method planJoinUsing.

private RelationPlan planJoinUsing(Join node, RelationPlan left, RelationPlan right) {
    /* Given: l JOIN r USING (k1, ..., kn)

           produces:

            - project
                    coalesce(l.k1, r.k1)
                    ...,
                    coalesce(l.kn, r.kn)
                    l.v1,
                    ...,
                    l.vn,
                    r.v1,
                    ...,
                    r.vn
              - join (l.k1 = r.k1 and ... l.kn = r.kn)
                    - project
                        cast(l.k1 as commonType(l.k1, r.k1))
                        ...
                    - project
                        cast(rl.k1 as commonType(l.k1, r.k1))

            If casts are redundant (due to column type and common type being equal),
            they will be removed by optimization passes.
        */
    List<Identifier> joinColumns = ((JoinUsing) node.getCriteria().orElseThrow()).getColumns();
    Analysis.JoinUsingAnalysis joinAnalysis = analysis.getJoinUsing(node);
    ImmutableList.Builder<JoinNode.EquiJoinClause> clauses = ImmutableList.builder();
    Map<Identifier, Symbol> leftJoinColumns = new HashMap<>();
    Map<Identifier, Symbol> rightJoinColumns = new HashMap<>();
    Assignments.Builder leftCoercions = Assignments.builder();
    Assignments.Builder rightCoercions = Assignments.builder();
    leftCoercions.putIdentities(left.getRoot().getOutputSymbols());
    rightCoercions.putIdentities(right.getRoot().getOutputSymbols());
    for (int i = 0; i < joinColumns.size(); i++) {
        Identifier identifier = joinColumns.get(i);
        Type type = analysis.getType(identifier);
        // compute the coercion for the field on the left to the common supertype of left & right
        Symbol leftOutput = symbolAllocator.newSymbol(identifier, type);
        int leftField = joinAnalysis.getLeftJoinFields().get(i);
        leftCoercions.put(leftOutput, new Cast(left.getSymbol(leftField).toSymbolReference(), toSqlType(type), false, typeCoercion.isTypeOnlyCoercion(left.getDescriptor().getFieldByIndex(leftField).getType(), type)));
        leftJoinColumns.put(identifier, leftOutput);
        // compute the coercion for the field on the right to the common supertype of left & right
        Symbol rightOutput = symbolAllocator.newSymbol(identifier, type);
        int rightField = joinAnalysis.getRightJoinFields().get(i);
        rightCoercions.put(rightOutput, new Cast(right.getSymbol(rightField).toSymbolReference(), toSqlType(type), false, typeCoercion.isTypeOnlyCoercion(right.getDescriptor().getFieldByIndex(rightField).getType(), type)));
        rightJoinColumns.put(identifier, rightOutput);
        clauses.add(new JoinNode.EquiJoinClause(leftOutput, rightOutput));
    }
    ProjectNode leftCoercion = new ProjectNode(idAllocator.getNextId(), left.getRoot(), leftCoercions.build());
    ProjectNode rightCoercion = new ProjectNode(idAllocator.getNextId(), right.getRoot(), rightCoercions.build());
    JoinNode join = new JoinNode(idAllocator.getNextId(), JoinNode.Type.typeConvert(node.getType()), leftCoercion, rightCoercion, clauses.build(), leftCoercion.getOutputSymbols(), rightCoercion.getOutputSymbols(), false, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableMap.of(), Optional.empty());
    // Add a projection to produce the outputs of the columns in the USING clause,
    // which are defined as coalesce(l.k, r.k)
    Assignments.Builder assignments = Assignments.builder();
    ImmutableList.Builder<Symbol> outputs = ImmutableList.builder();
    for (Identifier column : joinColumns) {
        Symbol output = symbolAllocator.newSymbol(column, analysis.getType(column));
        outputs.add(output);
        assignments.put(output, new CoalesceExpression(leftJoinColumns.get(column).toSymbolReference(), rightJoinColumns.get(column).toSymbolReference()));
    }
    for (int field : joinAnalysis.getOtherLeftFields()) {
        Symbol symbol = left.getFieldMappings().get(field);
        outputs.add(symbol);
        assignments.put(symbol, symbol.toSymbolReference());
    }
    for (int field : joinAnalysis.getOtherRightFields()) {
        Symbol symbol = right.getFieldMappings().get(field);
        outputs.add(symbol);
        assignments.put(symbol, symbol.toSymbolReference());
    }
    return new RelationPlan(new ProjectNode(idAllocator.getNextId(), join, assignments.build()), analysis.getScope(node), outputs.build(), outerContext);
}
Also used : Cast(io.trino.sql.tree.Cast) LinkedHashMap(java.util.LinkedHashMap) HashMap(java.util.HashMap) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) CorrelatedJoinNode(io.trino.sql.planner.plan.CorrelatedJoinNode) JoinNode(io.trino.sql.planner.plan.JoinNode) Assignments(io.trino.sql.planner.plan.Assignments) JoinUsing(io.trino.sql.tree.JoinUsing) RelationType(io.trino.sql.analyzer.RelationType) RowType(io.trino.spi.type.RowType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) Type(io.trino.spi.type.Type) Identifier(io.trino.sql.tree.Identifier) UnnestAnalysis(io.trino.sql.analyzer.Analysis.UnnestAnalysis) Analysis(io.trino.sql.analyzer.Analysis) ProjectNode(io.trino.sql.planner.plan.ProjectNode) CoalesceExpression(io.trino.sql.tree.CoalesceExpression)

Example 97 with ProjectNode

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

the class QueryPlanner method pruneInvisibleFields.

public static NodeAndMappings pruneInvisibleFields(RelationPlan plan, PlanNodeIdAllocator idAllocator) {
    List<Symbol> visibleFields = visibleFields(plan);
    ProjectNode pruned = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), Assignments.identity(visibleFields));
    return new NodeAndMappings(pruned, visibleFields);
}
Also used : ProjectNode(io.trino.sql.planner.plan.ProjectNode)

Example 98 with ProjectNode

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

the class QueryPlanner method coerce.

public static NodeAndMappings coerce(RelationPlan plan, List<Type> types, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator) {
    List<Symbol> visibleFields = visibleFields(plan);
    checkArgument(visibleFields.size() == types.size());
    Assignments.Builder assignments = Assignments.builder();
    ImmutableList.Builder<Symbol> mappings = ImmutableList.builder();
    for (int i = 0; i < types.size(); i++) {
        Symbol input = visibleFields.get(i);
        Type type = types.get(i);
        if (!symbolAllocator.getTypes().get(input).equals(type)) {
            Symbol coerced = symbolAllocator.newSymbol(input.getName(), type);
            assignments.put(coerced, new Cast(input.toSymbolReference(), toSqlType(type)));
            mappings.add(coerced);
        } else {
            assignments.putIdentity(input);
            mappings.add(input);
        }
    }
    ProjectNode coerced = new ProjectNode(idAllocator.getNextId(), plan.getRoot(), assignments.build());
    return new NodeAndMappings(coerced, mappings.build());
}
Also used : Cast(io.trino.sql.tree.Cast) RelationType(io.trino.sql.analyzer.RelationType) ExpressionAnalyzer.isNumericType(io.trino.sql.analyzer.ExpressionAnalyzer.isNumericType) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) DecimalType(io.trino.spi.type.DecimalType) Type(io.trino.spi.type.Type) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) ImmutableList(com.google.common.collect.ImmutableList) Assignments(io.trino.sql.planner.plan.Assignments) ProjectNode(io.trino.sql.planner.plan.ProjectNode)

Example 99 with ProjectNode

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

the class TestPushProjectionThroughJoin method testDoesNotPushStraddlingProjection.

@Test
public void testDoesNotPushStraddlingProjection() {
    PlanBuilder p = new PlanBuilder(new PlanNodeIdAllocator(), dummyMetadata(), TEST_SESSION);
    Symbol a = p.symbol("a");
    Symbol b = p.symbol("b");
    Symbol c = p.symbol("c");
    ProjectNode planNode = p.project(Assignments.of(c, new ArithmeticBinaryExpression(ADD, a.toSymbolReference(), b.toSymbolReference())), p.join(INNER, p.values(a), p.values(b)));
    Optional<PlanNode> rewritten = pushProjectionThroughJoin(PLANNER_CONTEXT, planNode, noLookup(), new PlanNodeIdAllocator(), testSessionBuilder().build(), createTestingTypeAnalyzer(PLANNER_CONTEXT), p.getTypes());
    assertThat(rewritten).isEmpty();
}
Also used : ArithmeticBinaryExpression(io.trino.sql.tree.ArithmeticBinaryExpression) PlanNode(io.trino.sql.planner.plan.PlanNode) PlanNodeIdAllocator(io.trino.sql.planner.PlanNodeIdAllocator) Symbol(io.trino.sql.planner.Symbol) ProjectNode(io.trino.sql.planner.plan.ProjectNode) PlanBuilder(io.trino.sql.planner.iterative.rule.test.PlanBuilder) Test(org.testng.annotations.Test)

Example 100 with ProjectNode

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

the class TestPushProjectionThroughJoin method testDoesNotPushProjectionThroughOuterJoin.

@Test
public void testDoesNotPushProjectionThroughOuterJoin() {
    PlanBuilder p = new PlanBuilder(new PlanNodeIdAllocator(), dummyMetadata(), TEST_SESSION);
    Symbol a = p.symbol("a");
    Symbol b = p.symbol("b");
    Symbol c = p.symbol("c");
    ProjectNode planNode = p.project(Assignments.of(c, new ArithmeticUnaryExpression(MINUS, a.toSymbolReference())), p.join(LEFT, p.values(a), p.values(b)));
    Optional<PlanNode> rewritten = pushProjectionThroughJoin(PLANNER_CONTEXT, planNode, noLookup(), new PlanNodeIdAllocator(), testSessionBuilder().build(), createTestingTypeAnalyzer(PLANNER_CONTEXT), p.getTypes());
    assertThat(rewritten).isEmpty();
}
Also used : PlanNode(io.trino.sql.planner.plan.PlanNode) PlanNodeIdAllocator(io.trino.sql.planner.PlanNodeIdAllocator) Symbol(io.trino.sql.planner.Symbol) ProjectNode(io.trino.sql.planner.plan.ProjectNode) ArithmeticUnaryExpression(io.trino.sql.tree.ArithmeticUnaryExpression) PlanBuilder(io.trino.sql.planner.iterative.rule.test.PlanBuilder) Test(org.testng.annotations.Test)

Aggregations

ProjectNode (io.trino.sql.planner.plan.ProjectNode)101 Assignments (io.trino.sql.planner.plan.Assignments)64 Expression (io.trino.sql.tree.Expression)58 Symbol (io.trino.sql.planner.Symbol)57 PlanNode (io.trino.sql.planner.plan.PlanNode)50 ImmutableList (com.google.common.collect.ImmutableList)41 Map (java.util.Map)35 Captures (io.trino.matching.Captures)29 Pattern (io.trino.matching.Pattern)29 Rule (io.trino.sql.planner.iterative.Rule)29 Set (java.util.Set)25 Capture (io.trino.matching.Capture)23 Capture.newCapture (io.trino.matching.Capture.newCapture)23 SymbolReference (io.trino.sql.tree.SymbolReference)23 Objects.requireNonNull (java.util.Objects.requireNonNull)23 Patterns.source (io.trino.sql.planner.plan.Patterns.source)22 TypeAnalyzer (io.trino.sql.planner.TypeAnalyzer)20 AggregationNode (io.trino.sql.planner.plan.AggregationNode)20 FilterNode (io.trino.sql.planner.plan.FilterNode)20 ImmutableMap.toImmutableMap (com.google.common.collect.ImmutableMap.toImmutableMap)19