Search in sources :

Example 36 with Symbol

use of io.trino.sql.planner.Symbol in project trino by trinodb.

the class RewriteSpatialPartitioningAggregation method apply.

@Override
public Result apply(AggregationNode node, Captures captures, Context context) {
    ResolvedFunction spatialPartitioningFunction = plannerContext.getMetadata().resolveFunction(context.getSession(), QualifiedName.of(NAME), fromTypeSignatures(GEOMETRY_TYPE_SIGNATURE, INTEGER.getTypeSignature()));
    ResolvedFunction stEnvelopeFunction = plannerContext.getMetadata().resolveFunction(context.getSession(), QualifiedName.of("ST_Envelope"), fromTypeSignatures(GEOMETRY_TYPE_SIGNATURE));
    ImmutableMap.Builder<Symbol, Aggregation> aggregations = ImmutableMap.builder();
    Symbol partitionCountSymbol = context.getSymbolAllocator().newSymbol("partition_count", INTEGER);
    ImmutableMap.Builder<Symbol, Expression> envelopeAssignments = ImmutableMap.builder();
    for (Map.Entry<Symbol, Aggregation> entry : node.getAggregations().entrySet()) {
        Aggregation aggregation = entry.getValue();
        String name = aggregation.getResolvedFunction().getSignature().getName();
        if (name.equals(NAME) && aggregation.getArguments().size() == 1) {
            Expression geometry = getOnlyElement(aggregation.getArguments());
            Symbol envelopeSymbol = context.getSymbolAllocator().newSymbol("envelope", plannerContext.getTypeManager().getType(GEOMETRY_TYPE_SIGNATURE));
            if (isStEnvelopeFunctionCall(geometry, stEnvelopeFunction)) {
                envelopeAssignments.put(envelopeSymbol, geometry);
            } else {
                envelopeAssignments.put(envelopeSymbol, FunctionCallBuilder.resolve(context.getSession(), plannerContext.getMetadata()).setName(QualifiedName.of("ST_Envelope")).addArgument(GEOMETRY_TYPE_SIGNATURE, geometry).build());
            }
            aggregations.put(entry.getKey(), new Aggregation(spatialPartitioningFunction, ImmutableList.of(envelopeSymbol.toSymbolReference(), partitionCountSymbol.toSymbolReference()), false, Optional.empty(), Optional.empty(), aggregation.getMask()));
        } else {
            aggregations.put(entry);
        }
    }
    return Result.ofPlanNode(new AggregationNode(node.getId(), new ProjectNode(context.getIdAllocator().getNextId(), node.getSource(), Assignments.builder().putIdentities(node.getSource().getOutputSymbols()).put(partitionCountSymbol, new LongLiteral(Integer.toString(getHashPartitionCount(context.getSession())))).putAll(envelopeAssignments.buildOrThrow()).build()), aggregations.buildOrThrow(), node.getGroupingSets(), node.getPreGroupedSymbols(), node.getStep(), node.getHashSymbol(), node.getGroupIdSymbol()));
}
Also used : LongLiteral(io.trino.sql.tree.LongLiteral) ResolvedFunction(io.trino.metadata.ResolvedFunction) Symbol(io.trino.sql.planner.Symbol) AggregationNode(io.trino.sql.planner.plan.AggregationNode) ImmutableMap(com.google.common.collect.ImmutableMap) Aggregation(io.trino.sql.planner.plan.AggregationNode.Aggregation) Expression(io.trino.sql.tree.Expression) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 37 with Symbol

use of io.trino.sql.planner.Symbol 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 38 with Symbol

use of io.trino.sql.planner.Symbol in project trino by trinodb.

the class SetOperationMerge method addMergedMappings.

private void addMergedMappings(SetOperationNode child, int childIndex, ImmutableListMultimap.Builder<Symbol, Symbol> newMappingsBuilder) {
    newSources.addAll(child.getSources());
    for (Map.Entry<Symbol, Collection<Symbol>> mapping : node.getSymbolMapping().asMap().entrySet()) {
        Symbol input = Iterables.get(mapping.getValue(), childIndex);
        newMappingsBuilder.putAll(mapping.getKey(), child.getSymbolMapping().get(input));
    }
}
Also used : Symbol(io.trino.sql.planner.Symbol) Collection(java.util.Collection) Map(java.util.Map)

Example 39 with Symbol

use of io.trino.sql.planner.Symbol in project trino by trinodb.

the class SetOperationNodeTranslator method appendCounts.

private WindowNode appendCounts(UnionNode sourceNode, List<Symbol> originalColumns, List<Symbol> markers, List<Symbol> countOutputs, Symbol rowNumberSymbol) {
    ImmutableMap.Builder<Symbol, WindowNode.Function> functions = ImmutableMap.builder();
    WindowNode.Frame defaultFrame = new WindowNode.Frame(ROWS, UNBOUNDED_PRECEDING, Optional.empty(), Optional.empty(), UNBOUNDED_FOLLOWING, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty());
    for (int i = 0; i < markers.size(); i++) {
        Symbol output = countOutputs.get(i);
        functions.put(output, new WindowNode.Function(countFunction, ImmutableList.of(markers.get(i).toSymbolReference()), defaultFrame, false));
    }
    functions.put(rowNumberSymbol, new WindowNode.Function(rowNumberFunction, ImmutableList.of(), defaultFrame, false));
    return new WindowNode(idAllocator.getNextId(), sourceNode, new Specification(originalColumns, Optional.empty()), functions.buildOrThrow(), Optional.empty(), ImmutableSet.of(), 0);
}
Also used : ResolvedFunction(io.trino.metadata.ResolvedFunction) WindowNode(io.trino.sql.planner.plan.WindowNode) Symbol(io.trino.sql.planner.Symbol) Specification(io.trino.sql.planner.plan.WindowNode.Specification) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 40 with Symbol

use of io.trino.sql.planner.Symbol in project trino by trinodb.

the class SetOperationNodeTranslator method appendMarkers.

private static PlanNode appendMarkers(PlanNodeIdAllocator idAllocator, SymbolAllocator symbolAllocator, PlanNode source, int markerIndex, List<Symbol> markers, Map<Symbol, SymbolReference> projections) {
    Assignments.Builder assignments = Assignments.builder();
    // add existing intersect symbols to projection
    for (Map.Entry<Symbol, SymbolReference> entry : projections.entrySet()) {
        Symbol symbol = symbolAllocator.newSymbol(entry.getKey().getName(), symbolAllocator.getTypes().get(entry.getKey()));
        assignments.put(symbol, entry.getValue());
    }
    // add extra marker fields to the projection
    for (int i = 0; i < markers.size(); ++i) {
        Expression expression = (i == markerIndex) ? TRUE_LITERAL : new Cast(new NullLiteral(), toSqlType(BOOLEAN));
        assignments.put(symbolAllocator.newSymbol(markers.get(i).getName(), BOOLEAN), expression);
    }
    return new ProjectNode(idAllocator.getNextId(), source, assignments.build());
}
Also used : Cast(io.trino.sql.tree.Cast) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) SymbolReference(io.trino.sql.tree.SymbolReference) Assignments(io.trino.sql.planner.plan.Assignments) ProjectNode(io.trino.sql.planner.plan.ProjectNode) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) NullLiteral(io.trino.sql.tree.NullLiteral)

Aggregations

Symbol (io.trino.sql.planner.Symbol)366 Test (org.testng.annotations.Test)171 ImmutableList (com.google.common.collect.ImmutableList)124 ImmutableMap (com.google.common.collect.ImmutableMap)106 Optional (java.util.Optional)96 PlanNode (io.trino.sql.planner.plan.PlanNode)85 Expression (io.trino.sql.tree.Expression)85 Map (java.util.Map)66 Assignments (io.trino.sql.planner.plan.Assignments)65 JoinNode (io.trino.sql.planner.plan.JoinNode)64 ProjectNode (io.trino.sql.planner.plan.ProjectNode)61 PlanMatchPattern.values (io.trino.sql.planner.assertions.PlanMatchPattern.values)56 SymbolReference (io.trino.sql.tree.SymbolReference)55 BIGINT (io.trino.spi.type.BigintType.BIGINT)52 Type (io.trino.spi.type.Type)51 Session (io.trino.Session)46 List (java.util.List)46 RuleTester (io.trino.sql.planner.iterative.rule.test.RuleTester)43 RuleTester.defaultRuleTester (io.trino.sql.planner.iterative.rule.test.RuleTester.defaultRuleTester)43 PlanNodeId (io.trino.sql.planner.plan.PlanNodeId)43