use of io.confluent.ksql.name.SourceName in project ksql by confluentinc.
the class QueryIdUtil method buildId.
/**
* Builds a {@link QueryId} for a physical plan specification.
*
* @param statement the statement that requires the query ID
* @param engineContext the context representing the current state of the engine
* @param idGenerator generates query ids
* @param outputNode the logical plan
* @param createOrReplaceEnabled whether or not the queryID can replace an existing one
* @return the {@link QueryId} to be used
*/
static QueryId buildId(final Statement statement, final EngineContext engineContext, final QueryIdGenerator idGenerator, final OutputNode outputNode, final boolean createOrReplaceEnabled, final Optional<String> withQueryId) {
if (withQueryId.isPresent()) {
final String queryId = withQueryId.get().toUpperCase();
validateWithQueryId(queryId);
return new QueryId(queryId);
}
if (statement instanceof CreateTable && ((CreateTable) statement).isSource()) {
// Use the CST name as part of the QueryID
final String suffix = ((CreateTable) statement).getName().text().toUpperCase() + "_" + idGenerator.getNext().toUpperCase();
return new QueryId(ReservedQueryIdsPrefixes.CST + suffix);
}
if (!outputNode.getSinkName().isPresent()) {
final String prefix = "transient_" + outputNode.getSource().getLeftmostSourceNode().getAlias().text() + "_";
return new QueryId(prefix + Math.abs(ThreadLocalRandom.current().nextLong()));
}
final KsqlStructuredDataOutputNode structured = (KsqlStructuredDataOutputNode) outputNode;
if (!structured.createInto()) {
return new QueryId(ReservedQueryIdsPrefixes.INSERT + idGenerator.getNext());
}
final SourceName sink = outputNode.getSinkName().get();
final Set<QueryId> queriesForSink = engineContext.getQueryRegistry().getQueriesWithSink(sink);
if (queriesForSink.size() > 1) {
throw new KsqlException("REPLACE for sink " + sink + " is not supported because there are " + "multiple queries writing into it: " + queriesForSink);
} else if (!queriesForSink.isEmpty()) {
if (!createOrReplaceEnabled) {
final String type = outputNode.getNodeOutputType().getKsqlType().toLowerCase();
throw new UnsupportedOperationException(String.format("Cannot add %s '%s': A %s with the same name already exists", type, sink.text(), type));
}
return Iterables.getOnlyElement(queriesForSink);
}
final String suffix = outputNode.getId().toString().toUpperCase() + "_" + idGenerator.getNext().toUpperCase();
return new QueryId(outputNode.getNodeOutputType() == DataSourceType.KTABLE ? ReservedQueryIdsPrefixes.CTAS + suffix : ReservedQueryIdsPrefixes.CSAS + suffix);
}
use of io.confluent.ksql.name.SourceName in project ksql by confluentinc.
the class ScalablePushQueryExecutionUtil method findQuery.
static PersistentQueryMetadata findQuery(final EngineContext engineContext, final ImmutableAnalysis analysis) {
final DataSource source = analysis.getFrom().getDataSource();
final SourceName sourceName = source.getName();
final Set<QueryId> queries = engineContext.getQueryRegistry().getQueriesWithSink(sourceName);
if (queries.isEmpty()) {
throw new IllegalStateException("Scalable push queries require a query that has a sink. " + "Source Name: " + sourceName);
}
if (queries.size() > 1) {
throw new IllegalStateException("Scalable push queries only work on sources that have a single writer query. " + "Source Name: " + sourceName + " Queries: " + queries);
}
final QueryId queryId = Iterables.getOnlyElement(queries);
return engineContext.getQueryRegistry().getPersistentQuery(queryId).orElseThrow(() -> new KsqlException("Persistent query has been stopped: " + queryId));
}
use of io.confluent.ksql.name.SourceName in project ksql by confluentinc.
the class EngineExecutor method validateExistingSink.
private void validateExistingSink(final KsqlStructuredDataOutputNode outputNode) {
final SourceName name = outputNode.getSinkName().get();
final DataSource existing = engineContext.getMetaStore().getSource(name);
if (existing == null) {
throw new KsqlException(String.format("%s does not exist.", outputNode));
}
if (existing.getDataSourceType() != outputNode.getNodeOutputType()) {
throw new KsqlException(String.format("Incompatible data sink and query result. Data sink" + " (%s) type is %s but select query result is %s.", name.text(), existing.getDataSourceType(), outputNode.getNodeOutputType()));
}
final LogicalSchema resultSchema = outputNode.getSchema();
final LogicalSchema existingSchema = existing.getSchema();
if (!resultSchema.compatibleSchema(existingSchema)) {
throw new KsqlException("Incompatible schema between results and sink." + System.lineSeparator() + "Result schema is " + resultSchema + System.lineSeparator() + "Sink schema is " + existingSchema);
}
}
use of io.confluent.ksql.name.SourceName in project ksql by confluentinc.
the class SourceSchemas method matchesNonValueField.
/**
* Determines if the supplied {@code column} matches a source(s) meta or key fields.
*
* <p>The supplied name can be prefixed with a source name. In which case, only that specific
* source is checked. If no prefix is present, all sources are checked.
*
* @param column the field name to search for. Can be prefixed by source name.
* @return true if this the supplied {@code column} matches a non-value field
*/
boolean matchesNonValueField(final Optional<SourceName> source, final ColumnName column) {
if (!source.isPresent()) {
return sourceSchemas.values().stream().anyMatch(schema -> SystemColumns.isPseudoColumn(column, rowpartitionRowoffsetEnabled) || schema.isKeyColumn(column));
}
final SourceName sourceName = source.get();
final LogicalSchema sourceSchema = sourceSchemas.get(sourceName);
if (sourceSchema == null) {
throw new IllegalArgumentException("Unknown source: " + sourceName);
}
return sourceSchema.isKeyColumn(column) || SystemColumns.isPseudoColumn(column, rowpartitionRowoffsetEnabled);
}
use of io.confluent.ksql.name.SourceName in project ksql by confluentinc.
the class CreateSourceFactory method createStreamCommand.
// This method is called by simple CREATE statements
public CreateStreamCommand createStreamCommand(final CreateStream statement, final KsqlConfig ksqlConfig) {
final SourceName sourceName = statement.getName();
final CreateSourceProperties props = statement.getProperties();
final String topicName = ensureTopicExists(props, serviceContext);
final LogicalSchema schema = buildSchema(statement.getElements(), ksqlConfig);
final Optional<TimestampColumn> timestampColumn = buildTimestampColumn(ksqlConfig, props, schema);
final DataSource dataSource = metaStore.getSource(sourceName);
if (dataSource != null && !statement.isOrReplace() && !statement.isNotExists()) {
final String sourceType = dataSource.getDataSourceType().getKsqlType();
throw new KsqlException(String.format("Cannot add stream '%s': A %s with the same name already exists", sourceName.text(), sourceType.toLowerCase()));
}
throwIfCreateOrReplaceOnSourceStreamOrTable(statement, dataSource);
return new CreateStreamCommand(sourceName, schema, timestampColumn, topicName, buildFormats(statement.getName(), schema, props, ksqlConfig), getWindowInfo(props), Optional.of(statement.isOrReplace()), Optional.of(statement.isSource()));
}
Aggregations