Search in sources :

Example 11 with InsertInto

use of io.confluent.ksql.parser.tree.InsertInto in project ksql by confluentinc.

the class DistributingExecutor method execute.

/**
 * The transactional protocol for sending a command to the command topic is to
 * initTransaction(), beginTransaction(), wait for commandRunner to finish processing all previous
 * commands that were present at the start of the transaction, validate the current command,
 * enqueue the command in the command topic, and commit the transaction.
 * Only successfully committed commands can be read by the command topic consumer.
 * If any exceptions are thrown during this protocol, the transaction is aborted.
 * If a new transactional producer is initialized while the current transaction is incomplete,
 * the old producer will be fenced off and unable to continue with its transaction.
 */
// CHECKSTYLE_RULES.OFF: NPathComplexity
public StatementExecutorResponse execute(final ConfiguredStatement<? extends Statement> statement, final KsqlExecutionContext executionContext, final KsqlSecurityContext securityContext) {
    final String commandRunnerWarningString = commandRunnerWarning.get();
    if (!commandRunnerWarningString.equals("")) {
        throw new KsqlServerException("Failed to handle Ksql Statement." + System.lineSeparator() + commandRunnerWarningString);
    }
    final ConfiguredStatement<?> injected = injectorFactory.apply(executionContext, securityContext.getServiceContext()).inject(statement);
    if (injected.getStatement() instanceof InsertInto) {
        validateInsertIntoQueries(executionContext.getMetaStore(), (InsertInto) injected.getStatement());
    }
    final Optional<StatementExecutorResponse> response = checkIfNotExistsResponse(executionContext, statement);
    if (response.isPresent()) {
        return response.get();
    }
    checkAuthorization(injected, securityContext, executionContext);
    final Producer<CommandId, Command> transactionalProducer = commandQueue.createTransactionalProducer();
    try {
        transactionalProducer.initTransactions();
    } catch (final TimeoutException e) {
        throw new KsqlServerException(errorHandler.transactionInitTimeoutErrorMessage(e), e);
    } catch (final Exception e) {
        throw new KsqlServerException(String.format("Could not write the statement '%s' into the command topic: " + e.getMessage(), statement.getStatementText()), e);
    }
    if (!rateLimiter.tryAcquire(1, TimeUnit.SECONDS)) {
        throw new KsqlRestException(Errors.tooManyRequests("DDL/DML rate is crossing the configured rate limit of statements/second"));
    }
    CommandId commandId = null;
    try {
        transactionalProducer.beginTransaction();
        commandQueue.waitForCommandConsumer();
        commandId = commandIdAssigner.getCommandId(statement.getStatement());
        final Command command = validatedCommandFactory.create(injected, executionContext.createSandbox(executionContext.getServiceContext()));
        final QueuedCommandStatus queuedCommandStatus = commandQueue.enqueueCommand(commandId, command, transactionalProducer);
        transactionalProducer.commitTransaction();
        final CommandStatus commandStatus = queuedCommandStatus.tryWaitForFinalStatus(distributedCmdResponseTimeout);
        return StatementExecutorResponse.handled(Optional.of(new CommandStatusEntity(injected.getStatementText(), queuedCommandStatus.getCommandId(), commandStatus, queuedCommandStatus.getCommandSequenceNumber(), getDeprecatedWarnings(executionContext.getMetaStore(), injected))));
    } catch (final ProducerFencedException | OutOfOrderSequenceException | AuthorizationException e) {
        // This catch doesn't abortTransaction() since doing that would throw another exception.
        if (commandId != null) {
            commandQueue.abortCommand(commandId);
        }
        throw new KsqlServerException(String.format("Could not write the statement '%s' into the command topic.", statement.getStatementText()), e);
    } catch (final Exception e) {
        transactionalProducer.abortTransaction();
        if (commandId != null) {
            commandQueue.abortCommand(commandId);
        }
        throw new KsqlServerException(String.format("Could not write the statement '%s' into the command topic.", statement.getStatementText()), e);
    } finally {
        transactionalProducer.close();
    }
}
Also used : AuthorizationException(org.apache.kafka.common.errors.AuthorizationException) KsqlServerException(io.confluent.ksql.util.KsqlServerException) StatementExecutorResponse(io.confluent.ksql.rest.server.execution.StatementExecutorResponse) TimeoutException(org.apache.kafka.common.errors.TimeoutException) AuthorizationException(org.apache.kafka.common.errors.AuthorizationException) OutOfOrderSequenceException(org.apache.kafka.common.errors.OutOfOrderSequenceException) KsqlServerException(io.confluent.ksql.util.KsqlServerException) ProducerFencedException(org.apache.kafka.common.errors.ProducerFencedException) KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) KsqlException(io.confluent.ksql.util.KsqlException) CommandStatusEntity(io.confluent.ksql.rest.entity.CommandStatusEntity) ProducerFencedException(org.apache.kafka.common.errors.ProducerFencedException) OutOfOrderSequenceException(org.apache.kafka.common.errors.OutOfOrderSequenceException) KsqlRestException(io.confluent.ksql.rest.server.resources.KsqlRestException) InsertInto(io.confluent.ksql.parser.tree.InsertInto) CommandStatus(io.confluent.ksql.rest.entity.CommandStatus) CommandId(io.confluent.ksql.rest.entity.CommandId) TimeoutException(org.apache.kafka.common.errors.TimeoutException)

Example 12 with InsertInto

use of io.confluent.ksql.parser.tree.InsertInto in project ksql by confluentinc.

the class InteractiveStatementExecutor method executeStatement.

@SuppressWarnings("unchecked")
private void executeStatement(final PreparedStatement<?> statement, final CommandId commandId, final Optional<CommandStatusFuture> commandStatusFuture) {
    if (statement.getStatement() instanceof TerminateQuery) {
        terminateQuery((PreparedStatement<TerminateQuery>) statement);
        final String successMessage = "Query terminated.";
        final CommandStatus successStatus = new CommandStatus(CommandStatus.Status.SUCCESS, successMessage, Optional.empty());
        putFinalStatus(commandId, commandStatusFuture, successStatus);
    } else if (statement.getStatement() instanceof ExecutableDdlStatement) {
        throwUnsupportedStatementError();
    } else if (statement.getStatement() instanceof CreateAsSelect) {
        throwUnsupportedStatementError();
    } else if (statement.getStatement() instanceof InsertInto) {
        throwUnsupportedStatementError();
    } else if (statement.getStatement() instanceof AlterSystemProperty) {
        final PreparedStatement<AlterSystemProperty> alterSystemQuery = (PreparedStatement<AlterSystemProperty>) statement;
        final String propertyName = alterSystemQuery.getStatement().getPropertyName();
        final String propertyValue = alterSystemQuery.getStatement().getPropertyValue();
        ksqlEngine.alterSystemProperty(propertyName, propertyValue);
        ksqlEngine.updateStreamsPropertiesAndRestartRuntime();
        final String successMessage = String.format("System property %s was set to %s.", propertyName, propertyValue);
        final CommandStatus successStatus = new CommandStatus(CommandStatus.Status.SUCCESS, successMessage, Optional.empty());
        putFinalStatus(commandId, commandStatusFuture, successStatus);
    } else {
        throw new KsqlException(String.format("Unexpected statement type: %s", statement.getClass().getName()));
    }
}
Also used : TerminateQuery(io.confluent.ksql.parser.tree.TerminateQuery) AlterSystemProperty(io.confluent.ksql.parser.tree.AlterSystemProperty) CommandStatus(io.confluent.ksql.rest.entity.CommandStatus) InsertInto(io.confluent.ksql.parser.tree.InsertInto) PreparedStatement(io.confluent.ksql.parser.KsqlParser.PreparedStatement) ExecutableDdlStatement(io.confluent.ksql.parser.tree.ExecutableDdlStatement) CreateAsSelect(io.confluent.ksql.parser.tree.CreateAsSelect) KsqlException(io.confluent.ksql.util.KsqlException)

Aggregations

InsertInto (io.confluent.ksql.parser.tree.InsertInto)12 Test (org.junit.Test)9 PreparedStatement (io.confluent.ksql.parser.KsqlParser.PreparedStatement)7 Statement (io.confluent.ksql.parser.tree.Statement)6 KsqlException (io.confluent.ksql.util.KsqlException)6 KsqlRestException (io.confluent.ksql.rest.server.resources.KsqlRestException)5 ConfiguredStatement (io.confluent.ksql.statement.ConfiguredStatement)5 KsqlServerException (io.confluent.ksql.util.KsqlServerException)5 ProducerFencedException (org.apache.kafka.common.errors.ProducerFencedException)5 TimeoutException (org.apache.kafka.common.errors.TimeoutException)5 KsqlTopicAuthorizationException (io.confluent.ksql.exception.KsqlTopicAuthorizationException)4 DataSource (io.confluent.ksql.metastore.model.DataSource)3 TerminateQuery (io.confluent.ksql.parser.tree.TerminateQuery)3 AstNode (io.confluent.ksql.parser.tree.AstNode)2 CreateAsSelect (io.confluent.ksql.parser.tree.CreateAsSelect)2 CommandStatus (io.confluent.ksql.rest.entity.CommandStatus)2 ComparisonExpression (io.confluent.ksql.execution.expression.tree.ComparisonExpression)1 ParsedStatement (io.confluent.ksql.parser.KsqlParser.ParsedStatement)1 AlterSystemProperty (io.confluent.ksql.parser.tree.AlterSystemProperty)1 ExecutableDdlStatement (io.confluent.ksql.parser.tree.ExecutableDdlStatement)1