use of io.confluent.ksql.util.KsqlStatementException in project ksql by confluentinc.
the class KsqlResourceTest method shouldFailWhenAvroInferenceFailsDuringValidate.
@Test
public void shouldFailWhenAvroInferenceFailsDuringValidate() {
// Given:
when(sandboxSchemaInjector.inject(any())).thenThrow(new KsqlStatementException("boom", "sql"));
// When:
final KsqlErrorMessage result = makeFailingRequest("CREATE STREAM S WITH(KEY_FORMAT='KAFKA', VALUE_FORMAT='AVRO', KAFKA_TOPIC='orders-topic');", BAD_REQUEST.code());
// Then:
assertThat(result.getErrorCode(), is(Errors.ERROR_CODE_BAD_STATEMENT));
assertThat(result.getMessage(), is("boom"));
}
use of io.confluent.ksql.util.KsqlStatementException in project ksql by confluentinc.
the class EngineExecutor method plan.
// Known to be non-empty
@SuppressWarnings("OptionalGetWithoutIsPresent")
KsqlPlan plan(final ConfiguredStatement<?> statement) {
try {
throwOnNonExecutableStatement(statement);
if (statement.getStatement() instanceof ExecutableDdlStatement) {
final boolean isSourceStream = statement.getStatement() instanceof CreateStream && ((CreateStream) statement.getStatement()).isSource();
final boolean isSourceTable = statement.getStatement() instanceof CreateTable && ((CreateTable) statement.getStatement()).isSource();
if ((isSourceStream || isSourceTable) && !isSourceTableMaterializationEnabled()) {
throw new KsqlStatementException("Cannot execute command because source table " + "materialization is disabled.", statement.getStatementText());
}
if (isSourceTable) {
return sourceTablePlan(statement);
} else {
final DdlCommand ddlCommand = engineContext.createDdlCommand(statement.getStatementText(), (ExecutableDdlStatement) statement.getStatement(), config);
return KsqlPlan.ddlPlanCurrent(statement.getStatementText(), ddlCommand);
}
}
final QueryContainer queryContainer = (QueryContainer) statement.getStatement();
final ExecutorPlans plans = planQuery(statement, queryContainer.getQuery(), Optional.of(queryContainer.getSink()), queryContainer.getQueryId(), engineContext.getMetaStore());
final KsqlStructuredDataOutputNode outputNode = (KsqlStructuredDataOutputNode) plans.logicalPlan.getNode().get();
final Optional<DdlCommand> ddlCommand = maybeCreateSinkDdl(statement, outputNode);
validateResultType(outputNode.getNodeOutputType(), statement);
final QueryPlan queryPlan = new QueryPlan(getSourceNames(outputNode), outputNode.getSinkName(), plans.physicalPlan.getPhysicalPlan(), plans.physicalPlan.getQueryId(), getApplicationId(plans.physicalPlan.getQueryId(), getSourceNames(outputNode)));
engineContext.createQueryValidator().validateQuery(config, plans.physicalPlan, engineContext.getQueryRegistry().getAllLiveQueries());
return KsqlPlan.queryPlanCurrent(statement.getStatementText(), ddlCommand, queryPlan);
} catch (final KsqlStatementException e) {
throw e;
} catch (final Exception e) {
throw new KsqlStatementException(e.getMessage(), statement.getStatementText(), e);
}
}
use of io.confluent.ksql.util.KsqlStatementException in project ksql by confluentinc.
the class EngineExecutor method executeScalablePushQuery.
ScalablePushQueryMetadata executeScalablePushQuery(final ImmutableAnalysis analysis, final ConfiguredStatement<Query> statement, final PushRouting pushRouting, final PushRoutingOptions pushRoutingOptions, final QueryPlannerOptions queryPlannerOptions, final Context context, final Optional<ScalablePushQueryMetrics> scalablePushQueryMetrics) {
final SessionConfig sessionConfig = statement.getSessionConfig();
// If we ever change how many hops a request can do, we'll need to update this for correct
// metrics.
final RoutingNodeType routingNodeType = pushRoutingOptions.getHasBeenForwarded() ? RoutingNodeType.REMOTE_NODE : RoutingNodeType.SOURCE_NODE;
PushPhysicalPlan plan = null;
try {
final KsqlConfig ksqlConfig = sessionConfig.getConfig(false);
final LogicalPlanNode logicalPlan = buildAndValidateLogicalPlan(statement, analysis, ksqlConfig, queryPlannerOptions, true);
final PushPhysicalPlanCreator pushPhysicalPlanCreator = (offsetRange, catchupConsumerGroup) -> buildScalablePushPhysicalPlan(logicalPlan, analysis, context, offsetRange, catchupConsumerGroup);
final Optional<PushOffsetRange> offsetRange = pushRoutingOptions.getContinuationToken().map(PushOffsetRange::deserialize);
final Optional<String> catchupConsumerGroup = pushRoutingOptions.getCatchupConsumerGroup();
final PushPhysicalPlanManager physicalPlanManager = new PushPhysicalPlanManager(pushPhysicalPlanCreator, catchupConsumerGroup, offsetRange);
final PushPhysicalPlan physicalPlan = physicalPlanManager.getPhysicalPlan();
plan = physicalPlan;
final TransientQueryQueue transientQueryQueue = new TransientQueryQueue(analysis.getLimitClause());
final PushQueryMetadata.ResultType resultType = physicalPlan.getScalablePushRegistry().isTable() ? physicalPlan.getScalablePushRegistry().isWindowed() ? ResultType.WINDOWED_TABLE : ResultType.TABLE : ResultType.STREAM;
final PushQueryQueuePopulator populator = () -> pushRouting.handlePushQuery(serviceContext, physicalPlanManager, statement, pushRoutingOptions, physicalPlan.getOutputSchema(), transientQueryQueue, scalablePushQueryMetrics, offsetRange);
final PushQueryPreparer preparer = () -> pushRouting.preparePushQuery(physicalPlanManager, statement, pushRoutingOptions);
final ScalablePushQueryMetadata metadata = new ScalablePushQueryMetadata(physicalPlan.getOutputSchema(), physicalPlan.getQueryId(), transientQueryQueue, scalablePushQueryMetrics, resultType, populator, preparer, physicalPlan.getSourceType(), routingNodeType, physicalPlan::getRowsReadFromDataSource);
return metadata;
} catch (final Exception e) {
if (plan == null) {
scalablePushQueryMetrics.ifPresent(m -> m.recordErrorRateForNoResult(1));
} else {
final PushPhysicalPlan pushPhysicalPlan = plan;
scalablePushQueryMetrics.ifPresent(metrics -> metrics.recordErrorRate(1, pushPhysicalPlan.getSourceType(), routingNodeType));
}
final String stmtLower = statement.getStatementText().toLowerCase(Locale.ROOT);
final String messageLower = e.getMessage().toLowerCase(Locale.ROOT);
final String stackLower = Throwables.getStackTraceAsString(e).toLowerCase(Locale.ROOT);
// the contents of the query
if (messageLower.contains(stmtLower) || stackLower.contains(stmtLower)) {
final StackTraceElement loc = Iterables.getLast(Throwables.getCausalChain(e)).getStackTrace()[0];
LOG.error("Failure to execute push query V2 {} {}, not logging the error message since it " + "contains the query string, which may contain sensitive information." + " If you see this LOG message, please submit a GitHub ticket and" + " we will scrub the statement text from the error at {}", pushRoutingOptions.debugString(), queryPlannerOptions.debugString(), loc);
} else {
LOG.error("Failure to execute push query V2. {} {}", pushRoutingOptions.debugString(), queryPlannerOptions.debugString(), e);
}
LOG.debug("Failed push query V2 text {}, {}", statement.getStatementText(), e);
throw new KsqlStatementException(e.getMessage() == null ? "Server Error" + Arrays.toString(e.getStackTrace()) : e.getMessage(), statement.getStatementText(), e);
}
}
use of io.confluent.ksql.util.KsqlStatementException in project ksql by confluentinc.
the class KsqlEngine method createStreamPullQuery.
public StreamPullQueryMetadata createStreamPullQuery(final ServiceContext serviceContext, final ImmutableAnalysis analysis, final ConfiguredStatement<Query> statementOrig, final boolean excludeTombstones) {
final boolean streamPullQueriesEnabled = statementOrig.getSessionConfig().getConfig(true).getBoolean(KsqlConfig.KSQL_QUERY_STREAM_PULL_QUERY_ENABLED);
if (!streamPullQueriesEnabled) {
throw new KsqlStatementException("Pull queries on streams are disabled. To create a push query on the stream," + " add EMIT CHANGES to the end. To enable pull queries on streams, set" + " the " + KsqlConfig.KSQL_QUERY_STREAM_PULL_QUERY_ENABLED + " config to 'true'.", statementOrig.getStatementText());
}
// Stream pull query overrides.
final Map<String, Object> overrides = new HashMap<>(statementOrig.getSessionConfig().getOverrides());
// Starting from earliest is semantically necessary.
overrides.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");
// Using a single thread keeps these queries as lightweight as possible, since we are
// not counting them against the transient query limit.
overrides.put(StreamsConfig.NUM_STREAM_THREADS_CONFIG, 1);
// There's no point in EOS, since this query only produces side effects.
overrides.put(StreamsConfig.PROCESSING_GUARANTEE_CONFIG, StreamsConfig.AT_LEAST_ONCE);
final ConfiguredStatement<Query> statement = statementOrig.withConfigOverrides(overrides);
final ImmutableMap<TopicPartition, Long> endOffsets = getQueryInputEndOffsets(analysis, serviceContext.getAdminClient());
final TransientQueryMetadata transientQueryMetadata = EngineExecutor.create(primaryContext, serviceContext, statement.getSessionConfig()).executeStreamPullQuery(statement, excludeTombstones, endOffsets);
QueryLogger.info("Streaming stream pull query results '{}' from earliest to " + endOffsets, statement.getStatementText());
return new StreamPullQueryMetadata(transientQueryMetadata, endOffsets);
}
use of io.confluent.ksql.util.KsqlStatementException in project ksql by confluentinc.
the class KsqlEngineTestUtil method execute.
@SuppressWarnings({ "rawtypes", "unchecked" })
private static ExecuteResult execute(final ServiceContext serviceContext, final KsqlExecutionContext executionContext, final ParsedStatement stmt, final KsqlConfig ksqlConfig, final Map<String, Object> overriddenProperties, final Optional<DefaultSchemaInjector> schemaInjector) {
final PreparedStatement<?> prepared = executionContext.prepare(stmt);
final ConfiguredStatement<?> configured = ConfiguredStatement.of(prepared, SessionConfig.of(ksqlConfig, overriddenProperties));
final ConfiguredStatement<?> withFormats = new DefaultFormatInjector().inject(configured);
final ConfiguredStatement<?> withSchema = schemaInjector.map(injector -> injector.inject(withFormats)).orElse((ConfiguredStatement) withFormats);
final ConfiguredStatement<?> reformatted = new SqlFormatInjector(executionContext).inject(withSchema);
try {
return executionContext.execute(serviceContext, reformatted);
} catch (final KsqlStatementException e) {
// can easily check that the failed statement is the input statement
throw new KsqlStatementException(e.getRawMessage(), stmt.getStatementText(), e.getCause());
}
}
Aggregations