use of io.confluent.ksql.execution.expression.tree.ColumnReferenceExp in project ksql by confluentinc.
the class FinalProjectNode method validateProjection.
/**
* Called to validate that columns referenced in the projection are valid.
*
* <p>This is necessary as some joins can create synthetic key columns that do not come
* from any data source. This means the normal column validation done during analysis can not
* fail on unknown column with generated column names.
*
* <p>Once the logical model has been built the synthetic key names are known and generated
* column names can be validated.
*/
private void validateProjection() {
// Validate any column in the projection that might be a synthetic
// Only really need to include any that might be, but we include all:
final RequiredColumns requiredColumns = RequiredColumns.builder().addAll(projection.singleExpressions()).build();
final Set<ColumnReferenceExp> unknown = getSource().validateColumns(requiredColumns);
if (!unknown.isEmpty()) {
final String errors = unknown.stream().map(columnRef -> NodeLocation.asPrefix(columnRef.getLocation()) + "Column '" + columnRef + "' cannot be resolved.").collect(Collectors.joining(System.lineSeparator()));
throw new KsqlException(errors);
}
}
use of io.confluent.ksql.execution.expression.tree.ColumnReferenceExp in project ksql by confluentinc.
the class LogicalPlanner method buildJoin.
/**
* @param root the root of the Join Tree
* @param prefix the prefix to uniquely identify the plan node
* @return the PlanNode representing this Join Tree
*/
private JoinNode buildJoin(final Join root, final String prefix, final boolean isWindowed) {
final PlanNode preRepartitionLeft;
if (root.getLeft() instanceof JoinTree.Join) {
preRepartitionLeft = buildJoin((Join) root.getLeft(), prefix + "L_", isWindowed);
} else {
final JoinTree.Leaf leaf = (Leaf) root.getLeft();
preRepartitionLeft = new DataSourceNode(new PlanNodeId("KafkaTopic_" + prefix + "Left"), leaf.getSource().getDataSource(), leaf.getSource().getAlias(), isWindowed, ksqlConfig);
}
final PlanNode preRepartitionRight;
if (root.getRight() instanceof JoinTree.Join) {
preRepartitionRight = buildJoin((Join) root.getRight(), prefix + "R_", isWindowed);
} else {
final JoinTree.Leaf leaf = (Leaf) root.getRight();
preRepartitionRight = new DataSourceNode(new PlanNodeId("KafkaTopic_" + prefix + "Right"), leaf.getSource().getDataSource(), leaf.getSource().getAlias(), isWindowed, ksqlConfig);
}
final Optional<Expression> fkExpression = verifyJoin(root.getInfo(), preRepartitionLeft, preRepartitionRight);
final JoinKey joinKey = fkExpression.map(columnReferenceExp -> buildForeignJoinKey(root, fkExpression.get())).orElseGet(() -> buildJoinKey(root));
final PlanNode left = prepareSourceForJoin(root.getLeft(), preRepartitionLeft, prefix + "Left", root.getInfo().getLeftJoinExpression(), fkExpression.isPresent());
final PlanNode right = prepareSourceForJoin(root.getRight(), preRepartitionRight, prefix + "Right", root.getInfo().getRightJoinExpression(), fkExpression.isPresent());
return new JoinNode(new PlanNodeId(prefix + "Join"), root.getInfo().getType(), joinKey.rewriteWith(refRewriter::process), prefix.isEmpty(), left, right, root.getInfo().getWithinExpression(), ksqlConfig.getString(KsqlConfig.KSQL_DEFAULT_KEY_FORMAT_CONFIG));
}
use of io.confluent.ksql.execution.expression.tree.ColumnReferenceExp in project ksql by confluentinc.
the class JoinNode method validateColumns.
@Override
protected Set<ColumnReferenceExp> validateColumns(final RequiredColumns requiredColumns) {
final boolean noSyntheticKey = !finalJoin || !joinKey.isSynthetic();
final RequiredColumns updated = noSyntheticKey ? requiredColumns : requiredColumns.asBuilder().remove(new UnqualifiedColumnReferenceExp(getOnlyElement(schema.key()).name())).build();
final Set<ColumnReferenceExp> leftUnknown = left.validateColumns(updated);
final Set<ColumnReferenceExp> rightUnknown = right.validateColumns(updated);
return Sets.intersection(leftUnknown, rightUnknown);
}
use of io.confluent.ksql.execution.expression.tree.ColumnReferenceExp in project ksql by confluentinc.
the class PartitionByParamsFactory method build.
public static <K> PartitionByParams<K> build(final LogicalSchema sourceSchema, final ExecutionKeyFactory<K> serdeFactory, final List<Expression> partitionBys, final KsqlConfig ksqlConfig, final FunctionRegistry functionRegistry, final ProcessingLogger logger) {
final List<PartitionByColumn> partitionByCols = getPartitionByColumnName(sourceSchema, partitionBys);
final LogicalSchema resultSchema = buildSchema(sourceSchema, partitionBys, functionRegistry, partitionByCols);
final Mapper<K> mapper;
if (isPartitionByNull(partitionBys)) {
// In case of PARTITION BY NULL, it is sufficient to set the new key to null as the old key
// is already present in the current value
mapper = (k, v) -> new KeyValue<>(null, v);
} else {
final List<PartitionByExpressionEvaluator> evaluators = partitionBys.stream().map(pby -> {
final Set<? extends ColumnReferenceExp> sourceColsInPartitionBy = ColumnExtractor.extractColumns(pby);
final boolean partitionByInvolvesKeyColsOnly = sourceColsInPartitionBy.stream().map(ColumnReferenceExp::getColumnName).allMatch(sourceSchema::isKeyColumn);
return buildExpressionEvaluator(sourceSchema, pby, ksqlConfig, functionRegistry, logger, partitionByInvolvesKeyColsOnly);
}).collect(Collectors.toList());
mapper = buildMapper(partitionByCols, evaluators, serdeFactory);
}
return new PartitionByParams<>(resultSchema, mapper);
}
use of io.confluent.ksql.execution.expression.tree.ColumnReferenceExp in project ksql by confluentinc.
the class GroupByParamsFactory method expressionSchema.
private static LogicalSchema expressionSchema(final LogicalSchema sourceSchema, final List<CompiledExpression> groupBys) {
final ColumnAliasGenerator columnAliasGenerator = ColumnNames.columnAliasGenerator(Stream.of(sourceSchema));
final LogicalSchema.Builder schemaBuilder = LogicalSchema.builder();
for (final CompiledExpression groupBy : groupBys) {
final Expression groupByExp = groupBy.getExpression();
final ColumnName columnName = groupByExp instanceof ColumnReferenceExp ? ((ColumnReferenceExp) groupByExp).getColumnName() : columnAliasGenerator.uniqueAliasFor(groupByExp);
schemaBuilder.keyColumn(columnName, groupBy.getExpressionType());
}
schemaBuilder.valueColumns(sourceSchema.value());
return schemaBuilder.build();
}
Aggregations