use of io.confluent.ksql.planner.plan.JoinNode.JoinType in project ksql by confluentinc.
the class LogicalPlanner method verifyForeignKeyJoin.
private Optional<Expression> verifyForeignKeyJoin(final JoinInfo joinInfo, final PlanNode leftNode, final PlanNode rightNode) {
final JoinType joinType = joinInfo.getType();
final Expression leftExpression = joinInfo.getLeftJoinExpression();
final Expression rightExpression = joinInfo.getRightJoinExpression();
if (joinInfo.getType().equals(JoinType.OUTER)) {
throw new KsqlException(String.format("Invalid join type:" + " full-outer join not supported for foreign-key table-table join." + " Got %s %s %s.", joinInfo.getLeftSource().getDataSource().getName().text(), joinType, joinInfo.getRightSource().getDataSource().getName().text()));
}
// because a FK-join output table has the same PK as its left input table
if (!(leftNode instanceof DataSourceNode) || !(rightNode instanceof DataSourceNode)) {
throw new KsqlException(String.format("Invalid join condition:" + " foreign-key table-table joins are not supported as part of n-way joins." + " Got %s = %s.", joinInfo.getFlippedLeftJoinExpression(), joinInfo.getFlippedRightJoinExpression()));
}
final CodeGenRunner codeGenRunner = new CodeGenRunner(leftNode.getSchema(), ksqlConfig, metaStore);
final VisitParentExpressionVisitor<Optional<Expression>, Context<Void>> unqualifiedRewritter = new VisitParentExpressionVisitor<Optional<Expression>, Context<Void>>(Optional.empty()) {
@Override
public Optional<Expression> visitQualifiedColumnReference(final QualifiedColumnReferenceExp node, final Context<Void> ctx) {
return Optional.of(new UnqualifiedColumnReferenceExp(node.getColumnName()));
}
};
final Expression leftExpressionUnqualified = ExpressionTreeRewriter.rewriteWith(unqualifiedRewritter::process, leftExpression);
final ExpressionEvaluator expressionEvaluator = codeGenRunner.buildCodeGenFromParseTree(leftExpressionUnqualified, "Left Join Expression");
final SqlType fkType = expressionEvaluator.getExpressionType();
final SqlType rightKeyType = Iterables.getOnlyElement(rightNode.getSchema().key()).type();
verifyJoinConditionTypes(fkType, rightKeyType, leftExpression, rightExpression, joinInfo.hasFlippedJoinCondition());
if (((DataSourceNode) rightNode).isWindowed()) {
throw new KsqlException("Foreign-key table-table joins are not supported on windowed tables.");
}
return Optional.of(leftExpression);
}
use of io.confluent.ksql.planner.plan.JoinNode.JoinType in project ksql by confluentinc.
the class LogicalPlanner method verifyJoin.
/**
* @return the foreign key column if this is a foreign key join
*/
private Optional<Expression> verifyJoin(final JoinInfo joinInfo, final PlanNode leftNode, final PlanNode rightNode) {
final JoinType joinType = joinInfo.getType();
final Expression leftExpression = joinInfo.getLeftJoinExpression();
final Expression rightExpression = joinInfo.getRightJoinExpression();
if (leftNode.getNodeOutputType() == DataSourceType.KSTREAM) {
if (rightNode.getNodeOutputType() == DataSourceType.KTABLE) {
verifyStreamTableJoin(joinInfo, rightNode);
}
// stream-stream join detected: nothing to verify
} else {
if (rightNode.getNodeOutputType() == DataSourceType.KSTREAM) {
throw new KsqlException(String.format("Invalid join order:" + " table-stream joins are not supported; only stream-table joins. Got %s %s %s.", joinInfo.getLeftSource().getDataSource().getName().text(), joinType, joinInfo.getRightSource().getDataSource().getName().text()));
}
if (joinOnNonKeyAttribute(rightExpression, rightNode, joinInfo.getRightSource())) {
throw new KsqlException(String.format("Invalid join condition:" + " table-table joins require to join on the primary key of the right input" + " table. Got %s = %s.", joinInfo.getFlippedLeftJoinExpression(), joinInfo.getFlippedRightJoinExpression()));
}
if (joinOnNonKeyAttribute(leftExpression, leftNode, joinInfo.getLeftSource())) {
return verifyForeignKeyJoin(joinInfo, leftNode, rightNode);
} else {
// primary key join detected
final SqlType leftKeyType = Iterables.getOnlyElement(leftNode.getSchema().key()).type();
final SqlType rightKeyType = Iterables.getOnlyElement(rightNode.getSchema().key()).type();
verifyJoinConditionTypes(leftKeyType, rightKeyType, leftExpression, rightExpression, joinInfo.hasFlippedJoinCondition());
}
}
return Optional.empty();
}
use of io.confluent.ksql.planner.plan.JoinNode.JoinType in project ksql by confluentinc.
the class LogicalPlanner method verifyStreamTableJoin.
private static void verifyStreamTableJoin(final JoinInfo joinInfo, final PlanNode rightNode) {
final JoinType joinType = joinInfo.getType();
final Expression rightExpression = joinInfo.getRightJoinExpression();
if (joinType.equals(JoinType.OUTER)) {
throw new KsqlException(String.format("Invalid join type: " + "full-outer join not supported for stream-table join. Got %s %s %s.", joinInfo.getLeftSource().getDataSource().getName().text(), joinType, joinInfo.getRightSource().getDataSource().getName().text()));
}
if (joinOnNonKeyAttribute(rightExpression, rightNode, joinInfo.getRightSource())) {
throw new KsqlException(String.format("Invalid join condition:" + " stream-table joins require to join on the table's primary key." + " Got %s = %s.", joinInfo.getFlippedLeftJoinExpression(), joinInfo.getFlippedRightJoinExpression()));
}
}
Aggregations