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;
}
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);
}
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()));
}
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()));
}
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());
}
Aggregations