Search in sources :

Example 21 with ValuesNode

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

the class TestStageStateMachine method createValuesPlan.

private static PlanFragment createValuesPlan() {
    Symbol symbol = new Symbol("column");
    PlanNodeId valuesNodeId = new PlanNodeId("plan");
    PlanFragment planFragment = new PlanFragment(new PlanFragmentId("plan"), new ValuesNode(valuesNodeId, ImmutableList.of(symbol), ImmutableList.of(new Row(ImmutableList.of(new StringLiteral("foo"))))), ImmutableMap.of(symbol, VARCHAR), SOURCE_DISTRIBUTION, ImmutableList.of(valuesNodeId), new PartitioningScheme(Partitioning.create(SINGLE_DISTRIBUTION, ImmutableList.of()), ImmutableList.of(symbol)), ungroupedExecution(), StatsAndCosts.empty(), Optional.empty());
    return planFragment;
}
Also used : PlanNodeId(io.trino.sql.planner.plan.PlanNodeId) ValuesNode(io.trino.sql.planner.plan.ValuesNode) StringLiteral(io.trino.sql.tree.StringLiteral) Symbol(io.trino.sql.planner.Symbol) PartitioningScheme(io.trino.sql.planner.PartitioningScheme) PlanFragmentId(io.trino.sql.planner.plan.PlanFragmentId) Row(io.trino.sql.tree.Row) PlanFragment(io.trino.sql.planner.PlanFragment)

Example 22 with ValuesNode

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

the class PushAggregationThroughOuterJoin method createAggregationOverNull.

private MappedAggregationInfo createAggregationOverNull(AggregationNode referenceAggregation, SymbolAllocator symbolAllocator, PlanNodeIdAllocator idAllocator) {
    // Create a values node that consists of a single row of nulls.
    // Map the output symbols from the referenceAggregation's source
    // to symbol references for the new values node.
    ImmutableList.Builder<Symbol> nullSymbols = ImmutableList.builder();
    ImmutableList.Builder<Expression> nullLiterals = ImmutableList.builder();
    ImmutableMap.Builder<Symbol, Symbol> sourcesSymbolMappingBuilder = ImmutableMap.builder();
    for (Symbol sourceSymbol : referenceAggregation.getSource().getOutputSymbols()) {
        Type type = symbolAllocator.getTypes().get(sourceSymbol);
        nullLiterals.add(new Cast(new NullLiteral(), toSqlType(type)));
        Symbol nullSymbol = symbolAllocator.newSymbol("null", type);
        nullSymbols.add(nullSymbol);
        sourcesSymbolMappingBuilder.put(sourceSymbol, nullSymbol);
    }
    ValuesNode nullRow = new ValuesNode(idAllocator.getNextId(), nullSymbols.build(), ImmutableList.of(new Row(nullLiterals.build())));
    // For each aggregation function in the reference node, create a corresponding aggregation function
    // that points to the nullRow. Map the symbols from the aggregations in referenceAggregation to the
    // symbols in these new aggregations.
    ImmutableMap.Builder<Symbol, Symbol> aggregationsSymbolMappingBuilder = ImmutableMap.builder();
    ImmutableMap.Builder<Symbol, AggregationNode.Aggregation> aggregationsOverNullBuilder = ImmutableMap.builder();
    SymbolMapper mapper = symbolMapper(sourcesSymbolMappingBuilder.buildOrThrow());
    for (Map.Entry<Symbol, AggregationNode.Aggregation> entry : referenceAggregation.getAggregations().entrySet()) {
        Symbol aggregationSymbol = entry.getKey();
        Aggregation overNullAggregation = mapper.map(entry.getValue());
        Symbol overNullSymbol = symbolAllocator.newSymbol(overNullAggregation.getResolvedFunction().getSignature().getName(), symbolAllocator.getTypes().get(aggregationSymbol));
        aggregationsOverNullBuilder.put(overNullSymbol, overNullAggregation);
        aggregationsSymbolMappingBuilder.put(aggregationSymbol, overNullSymbol);
    }
    Map<Symbol, Symbol> aggregationsSymbolMapping = aggregationsSymbolMappingBuilder.buildOrThrow();
    // create an aggregation node whose source is the null row.
    AggregationNode aggregationOverNullRow = new AggregationNode(idAllocator.getNextId(), nullRow, aggregationsOverNullBuilder.buildOrThrow(), globalAggregation(), ImmutableList.of(), AggregationNode.Step.SINGLE, Optional.empty(), Optional.empty());
    return new MappedAggregationInfo(aggregationOverNullRow, aggregationsSymbolMapping);
}
Also used : Cast(io.trino.sql.tree.Cast) ValuesNode(io.trino.sql.planner.plan.ValuesNode) SymbolMapper(io.trino.sql.planner.optimizations.SymbolMapper) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) 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) AggregationNode.globalAggregation(io.trino.sql.planner.plan.AggregationNode.globalAggregation) Type(io.trino.spi.type.Type) TypeSignatureTranslator.toSqlType(io.trino.sql.analyzer.TypeSignatureTranslator.toSqlType) CoalesceExpression(io.trino.sql.tree.CoalesceExpression) Expression(io.trino.sql.tree.Expression) Row(io.trino.sql.tree.Row) NullLiteral(io.trino.sql.tree.NullLiteral) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap)

Example 23 with ValuesNode

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

the class MergeProjectWithValues method apply.

@Override
public Result apply(ProjectNode node, Captures captures, Context context) {
    ValuesNode valuesNode = captures.get(VALUES);
    // handle projection which prunes all symbols
    if (node.getOutputSymbols().isEmpty()) {
        return Result.ofPlanNode(new ValuesNode(valuesNode.getId(), valuesNode.getRowCount()));
    }
    // fix iteration order over ProjectNode's assignments
    List<Map.Entry<Symbol, Expression>> assignments = ImmutableList.copyOf(node.getAssignments().entrySet());
    List<Symbol> outputs = assignments.stream().map(Map.Entry::getKey).collect(toImmutableList());
    List<Expression> expressions = assignments.stream().map(Map.Entry::getValue).collect(toImmutableList());
    // handle values with no output symbols
    if (valuesNode.getOutputSymbols().isEmpty()) {
        return Result.ofPlanNode(new ValuesNode(valuesNode.getId(), outputs, nCopies(valuesNode.getRowCount(), new Row(ImmutableList.copyOf(expressions)))));
    }
    // do not proceed if ValuesNode contains a non-deterministic expression and it is referenced more than once by the projection
    Set<Symbol> nonDeterministicValuesOutputs = new HashSet<>();
    for (Expression rowExpression : valuesNode.getRows().get()) {
        Row row = (Row) rowExpression;
        for (int i = 0; i < valuesNode.getOutputSymbols().size(); i++) {
            if (!isDeterministic(row.getItems().get(i), metadata)) {
                nonDeterministicValuesOutputs.add(valuesNode.getOutputSymbols().get(i));
            }
        }
    }
    Set<Symbol> multipleReferencedSymbols = expressions.stream().flatMap(expression -> SymbolsExtractor.extractAll(expression).stream()).collect(Collectors.groupingBy(Function.identity(), Collectors.counting())).entrySet().stream().filter(entry -> entry.getValue() > 1).map(Map.Entry::getKey).collect(toImmutableSet());
    if (!Sets.intersection(nonDeterministicValuesOutputs, multipleReferencedSymbols).isEmpty()) {
        return Result.empty();
    }
    // inline values expressions into projection's assignments
    ImmutableList.Builder<Expression> projectedRows = ImmutableList.builder();
    for (Expression rowExpression : valuesNode.getRows().get()) {
        Map<SymbolReference, Expression> mapping = buildMappings(valuesNode.getOutputSymbols(), (Row) rowExpression);
        Row projectedRow = new Row(expressions.stream().map(expression -> replaceExpression(expression, mapping)).collect(toImmutableList()));
        projectedRows.add(projectedRow);
    }
    return Result.ofPlanNode(new ValuesNode(valuesNode.getId(), outputs, projectedRows.build()));
}
Also used : ValuesNode(io.trino.sql.planner.plan.ValuesNode) Symbol(io.trino.sql.planner.Symbol) ImmutableList(com.google.common.collect.ImmutableList) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) SymbolReference(io.trino.sql.tree.SymbolReference) ExpressionNodeInliner.replaceExpression(io.trino.sql.planner.ExpressionNodeInliner.replaceExpression) Expression(io.trino.sql.tree.Expression) Row(io.trino.sql.tree.Row) Map(java.util.Map) ImmutableMap(com.google.common.collect.ImmutableMap) HashSet(java.util.HashSet)

Example 24 with ValuesNode

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

the class PruneValuesColumns method pushDownProjectOff.

@Override
protected Optional<PlanNode> pushDownProjectOff(Context context, ValuesNode valuesNode, Set<Symbol> referencedOutputs) {
    // no symbols to prune
    if (valuesNode.getOutputSymbols().isEmpty()) {
        return Optional.empty();
    }
    List<Symbol> newOutputs = filteredCopy(valuesNode.getOutputSymbols(), referencedOutputs::contains);
    // no output symbols left
    if (newOutputs.isEmpty()) {
        return Optional.of(new ValuesNode(valuesNode.getId(), valuesNode.getRowCount()));
    }
    checkState(valuesNode.getRows().isPresent(), "rows is empty");
    // if any of ValuesNode's rows is specified by expression other than Row, the redundant piece cannot be extracted and pruned
    if (!valuesNode.getRows().get().stream().allMatch(Row.class::isInstance)) {
        return Optional.empty();
    }
    // for each output of project, the corresponding column in the values node
    int[] mapping = new int[newOutputs.size()];
    for (int i = 0; i < mapping.length; i++) {
        mapping[i] = valuesNode.getOutputSymbols().indexOf(newOutputs.get(i));
    }
    ImmutableList.Builder<Expression> rowsBuilder = ImmutableList.builder();
    for (Expression row : valuesNode.getRows().get()) {
        rowsBuilder.add(new Row(Arrays.stream(mapping).mapToObj(i -> ((Row) row).getItems().get(i)).collect(Collectors.toList())));
    }
    return Optional.of(new ValuesNode(valuesNode.getId(), newOutputs, rowsBuilder.build()));
}
Also used : Symbol(io.trino.sql.planner.Symbol) Arrays(java.util.Arrays) MoreLists.filteredCopy(io.trino.util.MoreLists.filteredCopy) Patterns.values(io.trino.sql.planner.plan.Patterns.values) Set(java.util.Set) Collectors(java.util.stream.Collectors) PlanNode(io.trino.sql.planner.plan.PlanNode) Preconditions.checkState(com.google.common.base.Preconditions.checkState) List(java.util.List) ImmutableList(com.google.common.collect.ImmutableList) Row(io.trino.sql.tree.Row) Optional(java.util.Optional) Expression(io.trino.sql.tree.Expression) ValuesNode(io.trino.sql.planner.plan.ValuesNode) ValuesNode(io.trino.sql.planner.plan.ValuesNode) Expression(io.trino.sql.tree.Expression) Symbol(io.trino.sql.planner.Symbol) ImmutableList(com.google.common.collect.ImmutableList) Row(io.trino.sql.tree.Row)

Example 25 with ValuesNode

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

the class ValuesStatsRule method getSymbolValues.

private List<Object> getSymbolValues(ValuesNode valuesNode, int symbolId, Session session, Type rowType) {
    Type symbolType = rowType.getTypeParameters().get(symbolId);
    if (UNKNOWN.equals(symbolType)) {
        // special casing for UNKNOWN as evaluateConstantExpression does not handle that
        return IntStream.range(0, valuesNode.getRowCount()).mapToObj(rowId -> null).collect(toList());
    }
    checkState(valuesNode.getRows().isPresent(), "rows is empty");
    return valuesNode.getRows().get().stream().map(row -> {
        Object rowValue = evaluateConstantExpression(row, rowType, plannerContext, session, new AllowAllAccessControl(), ImmutableMap.of());
        return readNativeValue(symbolType, (SingleRowBlock) rowValue, symbolId);
    }).collect(toList());
}
Also used : IntStream(java.util.stream.IntStream) AllowAllAccessControl(io.trino.security.AllowAllAccessControl) ExpressionInterpreter.evaluateConstantExpression(io.trino.sql.planner.ExpressionInterpreter.evaluateConstantExpression) Patterns.values(io.trino.sql.planner.plan.Patterns.values) Type(io.trino.spi.type.Type) OptionalDouble(java.util.OptionalDouble) UNKNOWN(io.trino.type.UnknownType.UNKNOWN) StatsUtil.toStatsRepresentation(io.trino.spi.statistics.StatsUtil.toStatsRepresentation) Objects.requireNonNull(java.util.Objects.requireNonNull) Symbol(io.trino.sql.planner.Symbol) RowType(io.trino.spi.type.RowType) ImmutableMap(com.google.common.collect.ImmutableMap) Lookup(io.trino.sql.planner.iterative.Lookup) ImmutableList.toImmutableList(com.google.common.collect.ImmutableList.toImmutableList) SingleRowBlock(io.trino.spi.block.SingleRowBlock) DoubleStream(java.util.stream.DoubleStream) Preconditions.checkState(com.google.common.base.Preconditions.checkState) Objects(java.util.Objects) List(java.util.List) Collectors.toList(java.util.stream.Collectors.toList) Rule(io.trino.cost.ComposableStatsCalculator.Rule) Pattern(io.trino.matching.Pattern) TypeProvider(io.trino.sql.planner.TypeProvider) Optional(java.util.Optional) ValuesNode(io.trino.sql.planner.plan.ValuesNode) TypeUtils.readNativeValue(io.trino.spi.type.TypeUtils.readNativeValue) Session(io.trino.Session) PlannerContext(io.trino.sql.PlannerContext) Type(io.trino.spi.type.Type) RowType(io.trino.spi.type.RowType) AllowAllAccessControl(io.trino.security.AllowAllAccessControl) SingleRowBlock(io.trino.spi.block.SingleRowBlock)

Aggregations

ValuesNode (io.trino.sql.planner.plan.ValuesNode)36 Symbol (io.trino.sql.planner.Symbol)25 Expression (io.trino.sql.tree.Expression)15 PlanNode (io.trino.sql.planner.plan.PlanNode)14 Test (org.testng.annotations.Test)12 Row (io.trino.sql.tree.Row)11 JoinNode (io.trino.sql.planner.plan.JoinNode)10 ProjectNode (io.trino.sql.planner.plan.ProjectNode)10 ImmutableList (com.google.common.collect.ImmutableList)9 PlanNodeIdAllocator (io.trino.sql.planner.PlanNodeIdAllocator)8 PlanBuilder (io.trino.sql.planner.iterative.rule.test.PlanBuilder)8 FilterNode (io.trino.sql.planner.plan.FilterNode)8 ImmutableMap (com.google.common.collect.ImmutableMap)7 Session (io.trino.Session)7 MultiJoinNode (io.trino.sql.planner.iterative.rule.ReorderJoins.MultiJoinNode)7 MultiJoinNode.toMultiJoinNode (io.trino.sql.planner.iterative.rule.ReorderJoins.MultiJoinNode.toMultiJoinNode)7 List (java.util.List)7 Type (io.trino.spi.type.Type)6 DomainTranslator (io.trino.sql.planner.DomainTranslator)6 Map (java.util.Map)6