Search in sources :

Example 1 with JoinNode

use of io.confluent.ksql.planner.plan.JoinNode in project ksql by confluentinc.

the class LogicalPlannerTest method testSimpleLeftJoinFilterLogicalPlan.

@Test
public void testSimpleLeftJoinFilterLogicalPlan() throws Exception {
    String simpleQuery = "SELECT t1.col1, t2.col1, col5, t2.col4, t2.col2 FROM test1 t1 LEFT JOIN test2 t2 ON " + "t1.col1 = t2.col1 WHERE t1.col1 > 10 AND t2.col4 = 10.8;";
    PlanNode logicalPlan = buildLogicalPlan(simpleQuery);
    assertThat(logicalPlan.getSources().get(0), instanceOf(ProjectNode.class));
    ProjectNode projectNode = (ProjectNode) logicalPlan.getSources().get(0);
    assertThat(projectNode.getKeyField().name(), equalTo("t1.col1".toUpperCase()));
    assertThat(projectNode.getSchema().fields().size(), equalTo(5));
    assertThat(projectNode.getSources().get(0), instanceOf(FilterNode.class));
    FilterNode filterNode = (FilterNode) projectNode.getSources().get(0);
    assertThat(filterNode.getPredicate().toString(), equalTo("((T1.COL1 > 10) AND (T2.COL4 = 10.8))"));
    assertThat(filterNode.getSources().get(0), instanceOf(JoinNode.class));
    JoinNode joinNode = (JoinNode) filterNode.getSources().get(0);
    assertThat(joinNode.getSources().get(0), instanceOf(StructuredDataSourceNode.class));
    assertThat(joinNode.getSources().get(1), instanceOf(StructuredDataSourceNode.class));
}
Also used : PlanNode(io.confluent.ksql.planner.plan.PlanNode) JoinNode(io.confluent.ksql.planner.plan.JoinNode) FilterNode(io.confluent.ksql.planner.plan.FilterNode) ProjectNode(io.confluent.ksql.planner.plan.ProjectNode) StructuredDataSourceNode(io.confluent.ksql.planner.plan.StructuredDataSourceNode) Test(org.junit.Test)

Example 2 with JoinNode

use of io.confluent.ksql.planner.plan.JoinNode in project ksql by confluentinc.

the class Analyzer method visitJoin.

@Override
protected Node visitJoin(final Join node, final AnalysisContext context) {
    AliasedRelation left = (AliasedRelation) process(node.getLeft(), context);
    AliasedRelation right = (AliasedRelation) process(node.getRight(), context);
    String leftSideName = ((Table) left.getRelation()).getName().getSuffix();
    StructuredDataSource leftDataSource = metaStore.getSource(leftSideName);
    if (leftDataSource == null) {
        throw new KsqlException(format("Resource %s does not exist.", leftSideName));
    }
    leftDataSource = timestampColumn(left, leftDataSource);
    String rightSideName = ((Table) right.getRelation()).getName().getSuffix();
    StructuredDataSource rightDataSource = metaStore.getSource(rightSideName);
    if (rightDataSource == null) {
        throw new KsqlException(format("Resource %s does not exist.", rightSideName));
    }
    rightDataSource = timestampColumn(right, rightDataSource);
    String leftAlias = left.getAlias();
    String rightAlias = right.getAlias();
    JoinNode.Type joinType = getJoinType(node);
    if (!node.getCriteria().isPresent()) {
        throw new KsqlException(String.format("%s Join criteria is not set.", node.getLocation().isPresent() ? node.getLocation().get().toString() : ""));
    }
    JoinOn joinOn = (JoinOn) (node.getCriteria().get());
    ComparisonExpression comparisonExpression = (ComparisonExpression) joinOn.getExpression();
    Pair<String, String> leftSide = fetchKeyFieldName(comparisonExpression, leftAlias, leftDataSource.getSchema());
    Pair<String, String> rightSide = fetchKeyFieldName(comparisonExpression, rightAlias, rightDataSource.getSchema());
    String leftKeyFieldName = leftSide.getRight();
    String rightKeyFieldName = rightSide.getRight();
    if (comparisonExpression.getType() != ComparisonExpression.Type.EQUAL) {
        throw new KsqlException("Only equality join criteria is supported.");
    }
    StructuredDataSourceNode leftSourceKafkaTopicNode = new StructuredDataSourceNode(new PlanNodeId("KafkaTopic_Left"), leftDataSource, leftDataSource.getSchema());
    StructuredDataSourceNode rightSourceKafkaTopicNode = new StructuredDataSourceNode(new PlanNodeId("KafkaTopic_Right"), rightDataSource, rightDataSource.getSchema());
    JoinNode joinNode = new JoinNode(new PlanNodeId("Join"), joinType, leftSourceKafkaTopicNode, rightSourceKafkaTopicNode, leftKeyFieldName, rightKeyFieldName, leftAlias, rightAlias);
    analysis.setJoin(joinNode);
    return null;
}
Also used : PlanNodeId(io.confluent.ksql.planner.plan.PlanNodeId) StructuredDataSource(io.confluent.ksql.metastore.StructuredDataSource) ComparisonExpression(io.confluent.ksql.parser.tree.ComparisonExpression) JoinNode(io.confluent.ksql.planner.plan.JoinNode) StructuredDataSourceNode(io.confluent.ksql.planner.plan.StructuredDataSourceNode) KsqlException(io.confluent.ksql.util.KsqlException) JoinOn(io.confluent.ksql.parser.tree.JoinOn) AliasedRelation(io.confluent.ksql.parser.tree.AliasedRelation)

Example 3 with JoinNode

use of io.confluent.ksql.planner.plan.JoinNode in project ksql by confluentinc.

the class Analyzer method visitSelect.

@Override
protected Node visitSelect(final Select node, final AnalysisContext context) {
    for (SelectItem selectItem : node.getSelectItems()) {
        if (selectItem instanceof AllColumns) {
            // expand * and T.*
            AllColumns allColumns = (AllColumns) selectItem;
            if ((this.analysis.getFromDataSources() == null) || (this.analysis.getFromDataSources().isEmpty())) {
                throw new KsqlException("FROM clause was not resolved!");
            }
            if (analysis.getJoin() != null) {
                JoinNode joinNode = analysis.getJoin();
                for (Field field : joinNode.getLeft().getSchema().fields()) {
                    QualifiedNameReference qualifiedNameReference = new QualifiedNameReference(allColumns.getLocation().get(), QualifiedName.of(joinNode.getLeftAlias() + "." + field.name()));
                    analysis.addSelectItem(qualifiedNameReference, joinNode.getLeftAlias() + "_" + field.name());
                }
                for (Field field : joinNode.getRight().getSchema().fields()) {
                    QualifiedNameReference qualifiedNameReference = new QualifiedNameReference(allColumns.getLocation().get(), QualifiedName.of(joinNode.getRightAlias() + "." + field.name()));
                    analysis.addSelectItem(qualifiedNameReference, joinNode.getRightAlias() + "_" + field.name());
                }
            } else {
                for (Field field : this.analysis.getFromDataSources().get(0).getLeft().getSchema().fields()) {
                    QualifiedNameReference qualifiedNameReference = new QualifiedNameReference(allColumns.getLocation().get(), QualifiedName.of(this.analysis.getFromDataSources().get(0).getRight() + "." + field.name()));
                    analysis.addSelectItem(qualifiedNameReference, field.name());
                }
            }
        } else if (selectItem instanceof SingleColumn) {
            SingleColumn column = (SingleColumn) selectItem;
            analysis.addSelectItem(column.getExpression(), column.getAlias().get());
        } else {
            throw new IllegalArgumentException("Unsupported SelectItem type: " + selectItem.getClass().getName());
        }
    }
    return null;
}
Also used : Field(org.apache.kafka.connect.data.Field) SelectItem(io.confluent.ksql.parser.tree.SelectItem) JoinNode(io.confluent.ksql.planner.plan.JoinNode) AllColumns(io.confluent.ksql.parser.tree.AllColumns) SingleColumn(io.confluent.ksql.parser.tree.SingleColumn) KsqlException(io.confluent.ksql.util.KsqlException) QualifiedNameReference(io.confluent.ksql.parser.tree.QualifiedNameReference)

Aggregations

JoinNode (io.confluent.ksql.planner.plan.JoinNode)3 StructuredDataSourceNode (io.confluent.ksql.planner.plan.StructuredDataSourceNode)2 KsqlException (io.confluent.ksql.util.KsqlException)2 StructuredDataSource (io.confluent.ksql.metastore.StructuredDataSource)1 AliasedRelation (io.confluent.ksql.parser.tree.AliasedRelation)1 AllColumns (io.confluent.ksql.parser.tree.AllColumns)1 ComparisonExpression (io.confluent.ksql.parser.tree.ComparisonExpression)1 JoinOn (io.confluent.ksql.parser.tree.JoinOn)1 QualifiedNameReference (io.confluent.ksql.parser.tree.QualifiedNameReference)1 SelectItem (io.confluent.ksql.parser.tree.SelectItem)1 SingleColumn (io.confluent.ksql.parser.tree.SingleColumn)1 FilterNode (io.confluent.ksql.planner.plan.FilterNode)1 PlanNode (io.confluent.ksql.planner.plan.PlanNode)1 PlanNodeId (io.confluent.ksql.planner.plan.PlanNodeId)1 ProjectNode (io.confluent.ksql.planner.plan.ProjectNode)1 Field (org.apache.kafka.connect.data.Field)1 Test (org.junit.Test)1