private static ExpressionAnalysis analyzeExpressionsWithInputs( Session session, Metadata metadata, SqlParser sqlParser, Map<Integer, Type> types, Iterable<Expression> expressions, List<Expression> parameters, WarningCollector warningCollector) { Field[] fields = new Field[types.size()]; for (Entry<Integer, Type> entry : types.entrySet()) { fields[entry.getKey()] = com.facebook.presto.sql.analyzer.Field.newUnqualified(Optional.empty(), entry.getValue()); } RelationType tupleDescriptor = new RelationType(fields); return analyzeExpressions(session, metadata, sqlParser, tupleDescriptor, TypeProvider.empty(), expressions, parameters, warningCollector); }
if (!SystemSessionProperties.isLegacyUnnest(session) && elementType instanceof RowType) { ((RowType) elementType).getFields().stream() .map(field -> Field.newUnqualified(field.getName(), field.getType())) .forEach(outputFields::add); outputFields.add(Field.newUnqualified(Optional.empty(), elementType)); outputFields.add(Field.newUnqualified(Optional.empty(), ((MapType) expressionType).getKeyType())); outputFields.add(Field.newUnqualified(Optional.empty(), ((MapType) expressionType).getValueType())); outputFields.add(Field.newUnqualified(Optional.empty(), BIGINT));
@Override protected Scope visitExplain(Explain node, Optional<Scope> scope) throws SemanticException { checkState(node.isAnalyze(), "Non analyze explain should be rewritten to Query"); if (node.getOptions().stream().anyMatch(option -> !option.equals(new ExplainType(DISTRIBUTED)))) { throw new SemanticException(NOT_SUPPORTED, node, "EXPLAIN ANALYZE only supports TYPE DISTRIBUTED option"); } process(node.getStatement(), scope); analysis.setUpdateType(null); return createAndAssignScope(node, scope, Field.newUnqualified("Query Plan", VARCHAR)); }
.map(ResolvedField::getField); return sourceField .orElse(Field.newUnqualified(Optional.empty(), analysis.getType(expression))); }) .collect(toImmutableList());
.map(valueType -> Field.newUnqualified(Optional.empty(), valueType)) .collect(toImmutableList());
analysis.addTypes(ImmutableMap.of(NodeRef.of(column), type.get())); joinFields.add(Field.newUnqualified(column.getValue(), type.get()));
outputFields.add(Field.newUnqualified(field.getName(), field.getType(), field.getOriginTable(), field.getOriginColumnName(), false)); outputFields.add(Field.newUnqualified(field.map(Identifier::getValue), analysis.getType(expression), originTable, originColumn, column.getAlias().isPresent())); // TODO don't use analysis as a side-channel. Use outputExpressions to look up the type
return createAndAssignScope(insert, scope, Field.newUnqualified("rows", BIGINT));
LambdaArgumentDeclaration lambdaArgument = lambdaArguments.get(i); Type type = types.get(i); fields.add(com.facebook.presto.sql.analyzer.Field.newUnqualified(lambdaArgument.getName().getValue(), type)); setExpressionType(lambdaArgument, type);
Field rowIdField = Field.newUnqualified(Optional.empty(), rowIdType); Symbol rowIdSymbol = symbolAllocator.newSymbol("$rowId", rowIdField.getType()); outputSymbols.add(rowIdSymbol);
@Override protected Scope visitDelete(Delete node, Optional<Scope> scope) { Table table = node.getTable(); QualifiedObjectName tableName = createQualifiedObjectName(session, table, table.getName()); if (metadata.getView(session, tableName).isPresent()) { throw new SemanticException(NOT_SUPPORTED, node, "Deleting from views is not supported"); } // Analyzer checks for select permissions but DELETE has a separate permission, so disable access checks // TODO: we shouldn't need to create a new analyzer. The access control should be carried in the context object StatementAnalyzer analyzer = new StatementAnalyzer( analysis, metadata, sqlParser, new AllowAllAccessControl(), session, WarningCollector.NOOP); Scope tableScope = analyzer.analyze(table, scope); node.getWhere().ifPresent(where -> analyzeWhere(node, tableScope, where)); analysis.setUpdateType("DELETE"); accessControl.checkCanDeleteFromTable(session.getRequiredTransactionId(), session.getIdentity(), tableName); return createAndAssignScope(node, scope, Field.newUnqualified("rows", BIGINT)); }
if (node.isNotExists()) { analysis.setCreateTableAsSelectNoOp(true); return createAndAssignScope(node, scope, Field.newUnqualified("rows", BIGINT)); return createAndAssignScope(node, scope, Field.newUnqualified("rows", BIGINT));
.map(column -> Field.newUnqualified(column.getName(), column.getType())) .collect(toImmutableList()); Scope scope = Scope.builder().withRelationType(RelationId.anonymous(), new RelationType(fields)).build();
private static ExpressionAnalysis analyzeExpressionsWithInputs( Session session, Metadata metadata, SqlParser sqlParser, Map<Integer, Type> types, Iterable<? extends Expression> expressions) { Field[] fields = new Field[types.size()]; for (Entry<Integer, Type> entry : types.entrySet()) { fields[entry.getKey()] = Field.newUnqualified(Optional.empty(), entry.getValue()); } RelationType tupleDescriptor = new RelationType(fields); return analyzeExpressions(session, metadata, sqlParser, tupleDescriptor, expressions); }
@Override protected RelationType visitUnnest(Unnest node, AnalysisContext context) { ImmutableList.Builder<Field> outputFields = ImmutableList.builder(); for (Expression expression : node.getExpressions()) { ExpressionAnalysis expressionAnalysis = analyzeExpression(expression, context.getLateralTupleDescriptor(), context); Type expressionType = expressionAnalysis.getType(expression); if (expressionType instanceof ArrayType) { outputFields.add(Field.newUnqualified(Optional.empty(), ((ArrayType) expressionType).getElementType())); } else if (expressionType instanceof MapType) { outputFields.add(Field.newUnqualified(Optional.empty(), ((MapType) expressionType).getKeyType())); outputFields.add(Field.newUnqualified(Optional.empty(), ((MapType) expressionType).getValueType())); } else { throw new PrestoException(INVALID_FUNCTION_ARGUMENT, "Cannot unnest type: " + expressionType); } } if (node.isWithOrdinality()) { outputFields.add(Field.newUnqualified(Optional.empty(), BIGINT)); } RelationType descriptor = new RelationType(outputFields.build()); analysis.setOutputDescriptor(node, descriptor); return descriptor; }
public static ExpressionAnalysis analyzeExpressionsWithSymbols( Session session, Metadata metadata, SqlParser sqlParser, Map<Symbol, Type> types, Iterable<? extends Expression> expressions) { List<Field> fields = DependencyExtractor.extractUnique(expressions).stream() .map(symbol -> { Type type = types.get(symbol); checkArgument(type != null, "No type for symbol %s", symbol); return Field.newUnqualified(symbol.getName(), type); }) .collect(toImmutableList()); return analyzeExpressions(session, metadata, sqlParser, new RelationType(fields), expressions); }
outputFields.add(Field.newUnqualified(field.getName(), field.getType())); outputFields.add(Field.newUnqualified(alias, analysis.getType(expression))); // TODO don't use analysis as a side-channel. Use outputExpressions to look up the type
.map(column -> Field.newUnqualified(column.getName(), column.getType())) .collect(toImmutableList()));
@Override protected RelationType visitDelete(Delete node, AnalysisContext context) { Table table = node.getTable(); QualifiedObjectName tableName = createQualifiedObjectName(session, table, table.getName()); if (metadata.getView(session, tableName).isPresent()) { throw new SemanticException(NOT_SUPPORTED, node, "Deleting from views is not supported"); } // Analyzer checks for select permissions but DELETE has a separate permission, so disable access checks // TODO: we shouldn't need to create a new analyzer. The access control should be carried in the context object StatementAnalyzer analyzer = new StatementAnalyzer( analysis, metadata, sqlParser, new AllowAllAccessControl(), session, experimentalSyntaxEnabled, queryExplainer); RelationType descriptor = analyzer.process(table, context); node.getWhere().ifPresent(where -> analyzer.analyzeWhere(node, descriptor, context, where)); analysis.setUpdateType("DELETE"); analysis.setStatement(node); accessControl.checkCanDeleteFromTable(session.getRequiredTransactionId(), session.getIdentity(), tableName); return new RelationType(Field.newUnqualified("rows", BIGINT)); }
@Override protected RelationType visitCreateTableAsSelect(CreateTableAsSelect node, AnalysisContext context) { analysis.setUpdateType("CREATE TABLE"); // turn this into a query that has a new table writer node on top. QualifiedObjectName targetTable = createQualifiedObjectName(session, node, node.getName()); analysis.setCreateTableDestination(targetTable); Optional<TableHandle> targetTableHandle = metadata.getTableHandle(session, targetTable); if (targetTableHandle.isPresent()) { if (node.isNotExists()) { analysis.setCreateTableAsSelectNoOp(true); analysis.setStatement(node); return new RelationType(Field.newUnqualified("rows", BIGINT)); } throw new SemanticException(TABLE_ALREADY_EXISTS, node, "Destination table '%s' already exists", targetTable); } for (Expression expression : node.getProperties().values()) { // analyze table property value expressions which must be constant createConstantAnalyzer(metadata, session) .analyze(expression, new RelationType(), context); } analysis.setCreateTableProperties(node.getProperties()); accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), targetTable); analysis.setCreateTableAsSelectWithData(node.isWithData()); // analyze the query that creates the table RelationType descriptor = process(node.getQuery(), context); analysis.setStatement(node); validateColumns(node, descriptor); return new RelationType(Field.newUnqualified("rows", BIGINT)); }