use of io.trino.sql.analyzer.Field in project trino by trinodb.
the class RelationPlanner method visitTable.
@Override
protected RelationPlan visitTable(Table node, Void context) {
// is this a recursive reference in expandable named query? If so, there's base relation already planned.
RelationPlan expansion = recursiveSubqueries.get(NodeRef.of(node));
if (expansion != null) {
// put the pre-planned recursive subquery in the actual outer context to enable resolving correlation
return new RelationPlan(expansion.getRoot(), expansion.getScope(), expansion.getFieldMappings(), outerContext);
}
Query namedQuery = analysis.getNamedQuery(node);
Scope scope = analysis.getScope(node);
RelationPlan plan;
if (namedQuery != null) {
RelationPlan subPlan;
if (analysis.isExpandableQuery(namedQuery)) {
subPlan = new QueryPlanner(analysis, symbolAllocator, idAllocator, lambdaDeclarationToSymbolMap, plannerContext, outerContext, session, recursiveSubqueries).planExpand(namedQuery);
} else {
subPlan = process(namedQuery, null);
}
// Add implicit coercions if view query produces types that don't match the declared output types
// of the view (e.g., if the underlying tables referenced by the view changed)
List<Type> types = analysis.getOutputDescriptor(node).getAllFields().stream().map(Field::getType).collect(toImmutableList());
NodeAndMappings coerced = coerce(subPlan, types, symbolAllocator, idAllocator);
plan = new RelationPlan(coerced.getNode(), scope, coerced.getFields(), outerContext);
} else {
TableHandle handle = analysis.getTableHandle(node);
ImmutableList.Builder<Symbol> outputSymbolsBuilder = ImmutableList.builder();
ImmutableMap.Builder<Symbol, ColumnHandle> columns = ImmutableMap.builder();
for (Field field : scope.getRelationType().getAllFields()) {
Symbol symbol = symbolAllocator.newSymbol(field);
outputSymbolsBuilder.add(symbol);
columns.put(symbol, analysis.getColumn(field));
}
List<Symbol> outputSymbols = outputSymbolsBuilder.build();
boolean updateTarget = analysis.isUpdateTarget(node);
PlanNode root = TableScanNode.newInstance(idAllocator.getNextId(), handle, outputSymbols, columns.buildOrThrow(), updateTarget, Optional.empty());
plan = new RelationPlan(root, scope, outputSymbols, outerContext);
List<Type> types = analysis.getRelationCoercion(node);
if (types != null) {
// apply required coercion and prune invisible fields from child outputs
NodeAndMappings coerced = coerce(plan, types, symbolAllocator, idAllocator);
plan = new RelationPlan(coerced.getNode(), scope, coerced.getFields(), outerContext);
}
}
plan = addRowFilters(node, plan);
plan = addColumnMasks(node, plan);
return plan;
}
use of io.trino.sql.analyzer.Field in project trino by trinodb.
the class RelationPlanner method addColumnMasks.
private RelationPlan addColumnMasks(Table table, RelationPlan plan) {
Map<String, List<Expression>> columnMasks = analysis.getColumnMasks(table);
// if the masks are missing
if (columnMasks.isEmpty()) {
return plan;
}
PlanBuilder planBuilder = newPlanBuilder(plan, analysis, lambdaDeclarationToSymbolMap).withScope(analysis.getAccessControlScope(table), // The fields in the access control scope has the same layout as those for the table scope
plan.getFieldMappings());
for (int i = 0; i < plan.getDescriptor().getAllFieldCount(); i++) {
Field field = plan.getDescriptor().getFieldByIndex(i);
for (Expression mask : columnMasks.getOrDefault(field.getName().orElseThrow(), ImmutableList.of())) {
planBuilder = subqueryPlanner.handleSubqueries(planBuilder, mask, analysis.getSubqueries(mask));
Map<Symbol, Expression> assignments = new LinkedHashMap<>();
for (Symbol symbol : planBuilder.getRoot().getOutputSymbols()) {
assignments.put(symbol, symbol.toSymbolReference());
}
assignments.put(plan.getFieldMappings().get(i), coerceIfNecessary(analysis, mask, planBuilder.rewrite(mask)));
planBuilder = planBuilder.withNewRoot(new ProjectNode(idAllocator.getNextId(), planBuilder.getRoot(), Assignments.copyOf(assignments)));
}
}
return new RelationPlan(planBuilder.getRoot(), plan.getScope(), plan.getFieldMappings(), outerContext);
}
use of io.trino.sql.analyzer.Field in project trino by trinodb.
the class LogicalPlanner method createOutputPlan.
private PlanNode createOutputPlan(RelationPlan plan, Analysis analysis) {
ImmutableList.Builder<Symbol> outputs = ImmutableList.builder();
ImmutableList.Builder<String> names = ImmutableList.builder();
int columnNumber = 0;
RelationType outputDescriptor = analysis.getOutputDescriptor();
for (Field field : outputDescriptor.getVisibleFields()) {
String name = field.getName().orElse("_col" + columnNumber);
names.add(name);
int fieldIndex = outputDescriptor.indexOf(field);
Symbol symbol = plan.getSymbol(fieldIndex);
outputs.add(symbol);
columnNumber++;
}
return new OutputNode(idAllocator.getNextId(), plan.getRoot(), names.build(), outputs.build());
}
use of io.trino.sql.analyzer.Field in project trino by trinodb.
the class LogicalPlanner method createExplainAnalyzePlan.
private RelationPlan createExplainAnalyzePlan(Analysis analysis, ExplainAnalyze statement) {
RelationPlan underlyingPlan = planStatementWithoutOutput(analysis, statement.getStatement());
PlanNode root = underlyingPlan.getRoot();
Scope scope = analysis.getScope(statement);
Symbol outputSymbol = symbolAllocator.newSymbol(scope.getRelationType().getFieldByIndex(0));
ImmutableList.Builder<Symbol> actualOutputs = ImmutableList.builder();
RelationType outputDescriptor = analysis.getOutputDescriptor(statement.getStatement());
for (Field field : outputDescriptor.getVisibleFields()) {
int fieldIndex = outputDescriptor.indexOf(field);
Symbol symbol = underlyingPlan.getSymbol(fieldIndex);
actualOutputs.add(symbol);
}
root = new ExplainAnalyzeNode(idAllocator.getNextId(), root, outputSymbol, actualOutputs.build(), statement.isVerbose());
return new RelationPlan(root, scope, ImmutableList.of(outputSymbol), Optional.empty());
}
Aggregations