Search in sources :

Example 26 with SemanticException

use of com.facebook.presto.sql.analyzer.SemanticException in project presto by prestodb.

the class CallTask method execute.

@Override
public ListenableFuture<?> execute(Call call, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters) {
    if (!stateMachine.isAutoCommit()) {
        throw new PrestoException(NOT_SUPPORTED, "Procedures cannot be called within a transaction (use autocommit mode)");
    }
    Session session = stateMachine.getSession();
    QualifiedObjectName procedureName = createQualifiedObjectName(session, call, call.getName());
    ConnectorId connectorId = metadata.getCatalogHandle(stateMachine.getSession(), procedureName.getCatalogName()).orElseThrow(() -> new SemanticException(MISSING_CATALOG, call, "Catalog %s does not exist", procedureName.getCatalogName()));
    Procedure procedure = metadata.getProcedureRegistry().resolve(connectorId, procedureName.asSchemaTableName());
    // map declared argument names to positions
    Map<String, Integer> positions = new HashMap<>();
    for (int i = 0; i < procedure.getArguments().size(); i++) {
        positions.put(procedure.getArguments().get(i).getName(), i);
    }
    // per specification, do not allow mixing argument types
    Predicate<CallArgument> hasName = argument -> argument.getName().isPresent();
    boolean anyNamed = call.getArguments().stream().anyMatch(hasName);
    boolean allNamed = call.getArguments().stream().allMatch(hasName);
    if (anyNamed && !allNamed) {
        throw new SemanticException(INVALID_PROCEDURE_ARGUMENTS, call, "Named and positional arguments cannot be mixed");
    }
    // get the argument names in call order
    Map<String, CallArgument> names = new LinkedHashMap<>();
    for (int i = 0; i < call.getArguments().size(); i++) {
        CallArgument argument = call.getArguments().get(i);
        if (argument.getName().isPresent()) {
            String name = argument.getName().get();
            if (names.put(name, argument) != null) {
                throw new SemanticException(INVALID_PROCEDURE_ARGUMENTS, argument, "Duplicate procedure argument: %s", name);
            }
            if (!positions.containsKey(name)) {
                throw new SemanticException(INVALID_PROCEDURE_ARGUMENTS, argument, "Unknown argument name: %s", name);
            }
        } else if (i < procedure.getArguments().size()) {
            names.put(procedure.getArguments().get(i).getName(), argument);
        } else {
            throw new SemanticException(INVALID_PROCEDURE_ARGUMENTS, call, "Too many arguments for procedure");
        }
    }
    // verify argument count
    if (names.size() < positions.size()) {
        throw new SemanticException(INVALID_PROCEDURE_ARGUMENTS, call, "Too few arguments for procedure");
    }
    // get argument values
    Object[] values = new Object[procedure.getArguments().size()];
    for (Entry<String, CallArgument> entry : names.entrySet()) {
        CallArgument callArgument = entry.getValue();
        int index = positions.get(entry.getKey());
        Argument argument = procedure.getArguments().get(index);
        Expression expression = ExpressionTreeRewriter.rewriteWith(new ParameterRewriter(parameters), callArgument.getValue());
        Type type = metadata.getType(argument.getType());
        checkCondition(type != null, INVALID_PROCEDURE_DEFINITION, "Unknown procedure argument type: %s", argument.getType());
        Object value = evaluateConstantExpression(expression, type, metadata, session, parameters);
        values[index] = toTypeObjectValue(session, type, value);
    }
    // validate arguments
    MethodType methodType = procedure.getMethodHandle().type();
    for (int i = 0; i < procedure.getArguments().size(); i++) {
        if ((values[i] == null) && methodType.parameterType(i).isPrimitive()) {
            String name = procedure.getArguments().get(i).getName();
            throw new PrestoException(INVALID_PROCEDURE_ARGUMENT, "Procedure argument cannot be null: " + name);
        }
    }
    // insert session argument
    List<Object> arguments = new ArrayList<>();
    Iterator<Object> valuesIterator = asList(values).iterator();
    for (Class<?> type : methodType.parameterList()) {
        if (ConnectorSession.class.isAssignableFrom(type)) {
            arguments.add(session.toConnectorSession(connectorId));
        } else {
            arguments.add(valuesIterator.next());
        }
    }
    try {
        procedure.getMethodHandle().invokeWithArguments(arguments);
    } catch (Throwable t) {
        if (t instanceof InterruptedException) {
            Thread.currentThread().interrupt();
        }
        propagateIfInstanceOf(t, PrestoException.class);
        throw new PrestoException(PROCEDURE_CALL_FAILED, t);
    }
    return immediateFuture(null);
}
Also used : ExpressionTreeRewriter(com.facebook.presto.sql.tree.ExpressionTreeRewriter) QualifiedObjectName(com.facebook.presto.metadata.QualifiedObjectName) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) HashMap(java.util.HashMap) TypeUtils.writeNativeValue(com.facebook.presto.spi.type.TypeUtils.writeNativeValue) PrestoException(com.facebook.presto.spi.PrestoException) SemanticException(com.facebook.presto.sql.analyzer.SemanticException) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) MISSING_CATALOG(com.facebook.presto.sql.analyzer.SemanticErrorCode.MISSING_CATALOG) Type(com.facebook.presto.spi.type.Type) Arrays.asList(java.util.Arrays.asList) Map(java.util.Map) BlockBuilderStatus(com.facebook.presto.spi.block.BlockBuilderStatus) ExpressionInterpreter.evaluateConstantExpression(com.facebook.presto.sql.planner.ExpressionInterpreter.evaluateConstantExpression) INVALID_PROCEDURE_DEFINITION(com.facebook.presto.spi.StandardErrorCode.INVALID_PROCEDURE_DEFINITION) TransactionManager(com.facebook.presto.transaction.TransactionManager) Argument(com.facebook.presto.spi.procedure.Procedure.Argument) Failures.checkCondition(com.facebook.presto.util.Failures.checkCondition) Futures.immediateFuture(com.google.common.util.concurrent.Futures.immediateFuture) Iterator(java.util.Iterator) ParameterRewriter(com.facebook.presto.sql.planner.ParameterRewriter) Predicate(java.util.function.Predicate) Session(com.facebook.presto.Session) Throwables.propagateIfInstanceOf(com.google.common.base.Throwables.propagateIfInstanceOf) BlockBuilder(com.facebook.presto.spi.block.BlockBuilder) CallArgument(com.facebook.presto.sql.tree.CallArgument) ConnectorSession(com.facebook.presto.spi.ConnectorSession) INVALID_PROCEDURE_ARGUMENT(com.facebook.presto.spi.StandardErrorCode.INVALID_PROCEDURE_ARGUMENT) Procedure(com.facebook.presto.spi.procedure.Procedure) List(java.util.List) MethodType(java.lang.invoke.MethodType) Expression(com.facebook.presto.sql.tree.Expression) NOT_SUPPORTED(com.facebook.presto.spi.StandardErrorCode.NOT_SUPPORTED) MetadataUtil.createQualifiedObjectName(com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName) Entry(java.util.Map.Entry) ConnectorId(com.facebook.presto.connector.ConnectorId) Call(com.facebook.presto.sql.tree.Call) PROCEDURE_CALL_FAILED(com.facebook.presto.spi.StandardErrorCode.PROCEDURE_CALL_FAILED) INVALID_PROCEDURE_ARGUMENTS(com.facebook.presto.sql.analyzer.SemanticErrorCode.INVALID_PROCEDURE_ARGUMENTS) Metadata(com.facebook.presto.metadata.Metadata) AccessControl(com.facebook.presto.security.AccessControl) CallArgument(com.facebook.presto.sql.tree.CallArgument) Argument(com.facebook.presto.spi.procedure.Procedure.Argument) CallArgument(com.facebook.presto.sql.tree.CallArgument) ParameterRewriter(com.facebook.presto.sql.planner.ParameterRewriter) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) PrestoException(com.facebook.presto.spi.PrestoException) LinkedHashMap(java.util.LinkedHashMap) Procedure(com.facebook.presto.spi.procedure.Procedure) ConnectorId(com.facebook.presto.connector.ConnectorId) SemanticException(com.facebook.presto.sql.analyzer.SemanticException) MethodType(java.lang.invoke.MethodType) QualifiedObjectName(com.facebook.presto.metadata.QualifiedObjectName) MetadataUtil.createQualifiedObjectName(com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName) Type(com.facebook.presto.spi.type.Type) MethodType(java.lang.invoke.MethodType) ExpressionInterpreter.evaluateConstantExpression(com.facebook.presto.sql.planner.ExpressionInterpreter.evaluateConstantExpression) Expression(com.facebook.presto.sql.tree.Expression) Session(com.facebook.presto.Session) ConnectorSession(com.facebook.presto.spi.ConnectorSession)

Example 27 with SemanticException

use of com.facebook.presto.sql.analyzer.SemanticException in project presto by prestodb.

the class CreateSchemaTask method execute.

@Override
public ListenableFuture<?> execute(CreateSchema statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters) {
    Session session = stateMachine.getSession();
    CatalogSchemaName schema = createCatalogSchemaName(session, statement, Optional.of(statement.getSchemaName()));
    // TODO: validate that catalog exists
    accessControl.checkCanCreateSchema(session.getRequiredTransactionId(), session.getIdentity(), schema);
    if (metadata.schemaExists(session, schema)) {
        if (!statement.isNotExists()) {
            throw new SemanticException(SCHEMA_ALREADY_EXISTS, statement, "Schema '%s' already exists", schema);
        }
        return immediateFuture(null);
    }
    ConnectorId connectorId = metadata.getCatalogHandle(session, schema.getCatalogName()).orElseThrow(() -> new PrestoException(NOT_FOUND, "Catalog does not exist: " + schema.getCatalogName()));
    Map<String, Object> properties = metadata.getSchemaPropertyManager().getProperties(connectorId, schema.getCatalogName(), statement.getProperties(), session, metadata, parameters);
    metadata.createSchema(session, schema, properties);
    return immediateFuture(null);
}
Also used : CatalogSchemaName(com.facebook.presto.spi.CatalogSchemaName) MetadataUtil.createCatalogSchemaName(com.facebook.presto.metadata.MetadataUtil.createCatalogSchemaName) PrestoException(com.facebook.presto.spi.PrestoException) Session(com.facebook.presto.Session) SemanticException(com.facebook.presto.sql.analyzer.SemanticException) ConnectorId(com.facebook.presto.connector.ConnectorId)

Example 28 with SemanticException

use of com.facebook.presto.sql.analyzer.SemanticException in project presto by prestodb.

the class DropTableTask method execute.

@Override
public ListenableFuture<?> execute(DropTable statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters) {
    Session session = stateMachine.getSession();
    QualifiedObjectName tableName = createQualifiedObjectName(session, statement, statement.getTableName());
    Optional<TableHandle> tableHandle = metadata.getTableHandle(session, tableName);
    if (!tableHandle.isPresent()) {
        if (!statement.isExists()) {
            throw new SemanticException(MISSING_TABLE, statement, "Table '%s' does not exist", tableName);
        }
        return immediateFuture(null);
    }
    accessControl.checkCanDropTable(session.getRequiredTransactionId(), session.getIdentity(), tableName);
    metadata.dropTable(session, tableHandle.get());
    return immediateFuture(null);
}
Also used : TableHandle(com.facebook.presto.metadata.TableHandle) QualifiedObjectName(com.facebook.presto.metadata.QualifiedObjectName) MetadataUtil.createQualifiedObjectName(com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName) Session(com.facebook.presto.Session) SemanticException(com.facebook.presto.sql.analyzer.SemanticException)

Example 29 with SemanticException

use of com.facebook.presto.sql.analyzer.SemanticException in project presto by prestodb.

the class SqlQueryManager method createQuery.

@Override
public QueryInfo createQuery(SessionSupplier sessionSupplier, String query) {
    requireNonNull(sessionSupplier, "sessionFactory is null");
    requireNonNull(query, "query is null");
    checkArgument(!query.isEmpty(), "query must not be empty string");
    QueryId queryId = queryIdGenerator.createNextQueryId();
    Session session = null;
    QueryExecution queryExecution;
    Statement statement;
    try {
        session = sessionSupplier.createSession(queryId, transactionManager, accessControl, sessionPropertyManager);
        if (query.length() > maxQueryLength) {
            int queryLength = query.length();
            query = query.substring(0, maxQueryLength);
            throw new PrestoException(QUERY_TEXT_TOO_LARGE, format("Query text length (%s) exceeds the maximum length (%s)", queryLength, maxQueryLength));
        }
        Statement wrappedStatement = sqlParser.createStatement(query);
        statement = unwrapExecuteStatement(wrappedStatement, sqlParser, session);
        List<Expression> parameters = wrappedStatement instanceof Execute ? ((Execute) wrappedStatement).getParameters() : emptyList();
        validateParameters(statement, parameters);
        QueryExecutionFactory<?> queryExecutionFactory = executionFactories.get(statement.getClass());
        if (queryExecutionFactory == null) {
            throw new PrestoException(NOT_SUPPORTED, "Unsupported statement type: " + statement.getClass().getSimpleName());
        }
        if (statement instanceof Explain && ((Explain) statement).isAnalyze()) {
            Statement innerStatement = ((Explain) statement).getStatement();
            if (!(executionFactories.get(innerStatement.getClass()) instanceof SqlQueryExecutionFactory)) {
                throw new PrestoException(NOT_SUPPORTED, "EXPLAIN ANALYZE only supported for statements that are queries");
            }
        }
        queryExecution = queryExecutionFactory.createQueryExecution(queryId, query, session, statement, parameters);
    } catch (ParsingException | PrestoException | SemanticException e) {
        // This is intentionally not a method, since after the state change listener is registered
        // it's not safe to do any of this, and we had bugs before where people reused this code in a method
        URI self = locationFactory.createQueryLocation(queryId);
        // if session creation failed, create a minimal session object
        if (session == null) {
            session = Session.builder(new SessionPropertyManager()).setQueryId(queryId).setIdentity(sessionSupplier.getIdentity()).build();
        }
        Optional<ResourceGroupId> resourceGroup = Optional.empty();
        if (e instanceof QueryQueueFullException) {
            resourceGroup = Optional.of(((QueryQueueFullException) e).getResourceGroup());
        }
        QueryExecution execution = new FailedQueryExecution(queryId, query, resourceGroup, session, self, transactionManager, queryExecutor, metadata, e);
        QueryInfo queryInfo = null;
        try {
            queries.put(queryId, execution);
            queryInfo = execution.getQueryInfo();
            queryMonitor.queryCreatedEvent(queryInfo);
            queryMonitor.queryCompletedEvent(queryInfo);
            stats.queryFinished(queryInfo);
        } finally {
            // execution MUST be added to the expiration queue or there will be a leak
            expirationQueue.add(execution);
        }
        return queryInfo;
    }
    QueryInfo queryInfo = queryExecution.getQueryInfo();
    queryMonitor.queryCreatedEvent(queryInfo);
    queryExecution.addFinalQueryInfoListener(finalQueryInfo -> {
        try {
            QueryInfo info = queryExecution.getQueryInfo();
            stats.queryFinished(info);
            queryMonitor.queryCompletedEvent(info);
        } finally {
            expirationQueue.add(queryExecution);
        }
    });
    addStatsListener(queryExecution);
    queries.put(queryId, queryExecution);
    // start the query in the background
    queueManager.submit(statement, queryExecution, queryExecutor);
    return queryInfo;
}
Also used : Execute(com.facebook.presto.sql.tree.Execute) Optional(java.util.Optional) Statement(com.facebook.presto.sql.tree.Statement) QueryId(com.facebook.presto.spi.QueryId) Explain(com.facebook.presto.sql.tree.Explain) QueryQueueFullException(com.facebook.presto.execution.resourceGroups.QueryQueueFullException) PrestoException(com.facebook.presto.spi.PrestoException) URI(java.net.URI) SqlQueryExecutionFactory(com.facebook.presto.execution.SqlQueryExecution.SqlQueryExecutionFactory) Expression(com.facebook.presto.sql.tree.Expression) ParsingException(com.facebook.presto.sql.parser.ParsingException) SessionPropertyManager(com.facebook.presto.metadata.SessionPropertyManager) Session(com.facebook.presto.Session) SemanticException(com.facebook.presto.sql.analyzer.SemanticException)

Example 30 with SemanticException

use of com.facebook.presto.sql.analyzer.SemanticException in project presto by prestodb.

the class DropViewTask method execute.

@Override
public ListenableFuture<?> execute(DropView statement, TransactionManager transactionManager, Metadata metadata, AccessControl accessControl, QueryStateMachine stateMachine, List<Expression> parameters) {
    Session session = stateMachine.getSession();
    QualifiedObjectName name = createQualifiedObjectName(session, statement, statement.getName());
    Optional<ViewDefinition> view = metadata.getView(session, name);
    if (!view.isPresent()) {
        if (!statement.isExists()) {
            throw new SemanticException(MISSING_TABLE, statement, "View '%s' does not exist", name);
        }
        return immediateFuture(null);
    }
    accessControl.checkCanDropView(session.getRequiredTransactionId(), session.getIdentity(), name);
    metadata.dropView(session, name);
    return immediateFuture(null);
}
Also used : ViewDefinition(com.facebook.presto.metadata.ViewDefinition) QualifiedObjectName(com.facebook.presto.metadata.QualifiedObjectName) MetadataUtil.createQualifiedObjectName(com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName) Session(com.facebook.presto.Session) SemanticException(com.facebook.presto.sql.analyzer.SemanticException)

Aggregations

SemanticException (com.facebook.presto.sql.analyzer.SemanticException)45 Session (com.facebook.presto.Session)29 MetadataUtil.createQualifiedObjectName (com.facebook.presto.metadata.MetadataUtil.createQualifiedObjectName)21 PrestoException (com.facebook.presto.spi.PrestoException)14 QualifiedObjectName (com.facebook.presto.common.QualifiedObjectName)12 QualifiedObjectName (com.facebook.presto.metadata.QualifiedObjectName)9 TableHandle (com.facebook.presto.spi.TableHandle)9 Test (org.testng.annotations.Test)9 Expression (com.facebook.presto.sql.tree.Expression)8 TableHandle (com.facebook.presto.metadata.TableHandle)7 ConnectorId (com.facebook.presto.spi.ConnectorId)7 ConnectorMaterializedViewDefinition (com.facebook.presto.spi.ConnectorMaterializedViewDefinition)7 MetadataUtil.createCatalogSchemaName (com.facebook.presto.metadata.MetadataUtil.createCatalogSchemaName)6 TransactionManager (com.facebook.presto.transaction.TransactionManager)6 ColumnHandle (com.facebook.presto.spi.ColumnHandle)5 Type (com.facebook.presto.common.type.Type)4 Metadata (com.facebook.presto.metadata.Metadata)4 AccessControl (com.facebook.presto.security.AccessControl)4 ColumnMetadata (com.facebook.presto.spi.ColumnMetadata)4 Privilege (com.facebook.presto.spi.security.Privilege)4