Search in sources :

Example 11 with LogicalProject

use of org.apache.calcite.rel.logical.LogicalProject in project samza by apache.

the class TestQueryPlanner method testRemoteJoinFilterPushDownWithUdfInFilterAndOptimizer.

@Test
public void testRemoteJoinFilterPushDownWithUdfInFilterAndOptimizer() throws SamzaSqlValidatorException {
    Map<String, String> staticConfigs = SamzaSqlTestConfig.fetchStaticConfigsWithFactories(1);
    String sql = "Insert into testavro.enrichedPageViewTopic " + "select pv.pageKey as __key__, pv.pageKey as pageKey, coalesce(null, 'N/A') as companyName," + "       p.name as profileName, p.address as profileAddress " + "from testRemoteStore.Profile.`$table` as p " + "join testavro.PAGEVIEW as pv " + " on p.__key__ = pv.profileId" + " where p.name = pv.pageKey AND p.name = 'Mike' AND pv.profileId = MyTest(pv.profileId)";
    staticConfigs.put(SamzaSqlApplicationConfig.CFG_SQL_STMT, sql);
    staticConfigs.put(SamzaSqlApplicationConfig.CFG_SQL_ENABLE_PLAN_OPTIMIZER, Boolean.toString(true));
    Config samzaConfig = new MapConfig(staticConfigs);
    DslConverter dslConverter = new SamzaSqlDslConverterFactory().create(samzaConfig);
    Collection<RelRoot> relRoots = dslConverter.convertDsl(sql);
    /*
      Query plan without optimization:
      LogicalProject(__key__=[$9], pageKey=[$9], companyName=['N/A'], profileName=[$2], profileAddress=[$4])
        LogicalFilter(condition=[AND(=($2, $9), =($2, 'Mike'), =($10, CAST(MyTest($10)):INTEGER))])
          LogicalJoin(condition=[=($0, $10)], joinType=[inner])
            LogicalTableScan(table=[[testRemoteStore, Profile, $table]])
            LogicalTableScan(table=[[testavro, PAGEVIEW]])

      Query plan with optimization:
      LogicalProject(__key__=[$9], pageKey=[$9], companyName=['N/A'], profileName=[$2], profileAddress=[$4])
        LogicalFilter(condition=[AND(=($2, $9), =($2, 'Mike'))])
          LogicalJoin(condition=[=($0, $10)], joinType=[inner])
            LogicalTableScan(table=[[testRemoteStore, Profile, $table]])
            LogicalFilter(condition=[=($2, CAST(MyTest($2)):INTEGER)])
              LogicalTableScan(table=[[testavro, PAGEVIEW]])
     */
    assertEquals(1, relRoots.size());
    RelRoot relRoot = relRoots.iterator().next();
    RelNode relNode = relRoot.rel;
    assertTrue(relNode instanceof LogicalProject);
    relNode = relNode.getInput(0);
    assertTrue(relNode instanceof LogicalFilter);
    assertEquals("AND(=($2, $9), =($2, 'Mike'))", ((LogicalFilter) relNode).getCondition().toString());
    relNode = relNode.getInput(0);
    assertTrue(relNode instanceof LogicalJoin);
    assertEquals(2, relNode.getInputs().size());
    LogicalJoin join = (LogicalJoin) relNode;
    RelNode left = join.getLeft();
    RelNode right = join.getRight();
    assertTrue(left instanceof LogicalTableScan);
    assertTrue(right instanceof LogicalFilter);
    assertEquals("=($2, CAST(MyTest($2)):INTEGER)", ((LogicalFilter) right).getCondition().toString());
    assertTrue(right.getInput(0) instanceof LogicalTableScan);
}
Also used : DslConverter(org.apache.samza.sql.interfaces.DslConverter) SamzaSqlTestConfig(org.apache.samza.sql.util.SamzaSqlTestConfig) SamzaSqlApplicationConfig(org.apache.samza.sql.runner.SamzaSqlApplicationConfig) Config(org.apache.samza.config.Config) MapConfig(org.apache.samza.config.MapConfig) LogicalFilter(org.apache.calcite.rel.logical.LogicalFilter) SamzaSqlDslConverterFactory(org.apache.samza.sql.dsl.SamzaSqlDslConverterFactory) RelRoot(org.apache.calcite.rel.RelRoot) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) RelNode(org.apache.calcite.rel.RelNode) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) MapConfig(org.apache.samza.config.MapConfig) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) Test(org.junit.Test)

Example 12 with LogicalProject

use of org.apache.calcite.rel.logical.LogicalProject in project flink by apache.

the class PushProjectIntoTableSourceScanRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    final LogicalProject project = call.rel(0);
    final LogicalTableScan scan = call.rel(1);
    final TableSourceTable sourceTable = scan.getTable().unwrap(TableSourceTable.class);
    final boolean supportsNestedProjection = supportsNestedProjection(sourceTable.tableSource());
    final int[] refFields = RexNodeExtractor.extractRefInputFields(project.getProjects());
    if (!supportsNestedProjection && refFields.length == scan.getRowType().getFieldCount()) {
        // There is no top-level projection and nested projections aren't supported.
        return;
    }
    final FlinkTypeFactory typeFactory = unwrapTypeFactory(scan);
    final ResolvedSchema schema = sourceTable.contextResolvedTable().getResolvedSchema();
    final RowType producedType = createProducedType(schema, sourceTable.tableSource());
    final NestedSchema projectedSchema = NestedProjectionUtil.build(getProjections(project, scan), typeFactory.buildRelNodeRowType(producedType));
    if (!supportsNestedProjection) {
        for (NestedColumn column : projectedSchema.columns().values()) {
            column.markLeaf();
        }
    }
    final List<SourceAbilitySpec> abilitySpecs = new ArrayList<>();
    final RowType newProducedType = performPushDown(sourceTable, projectedSchema, producedType, abilitySpecs);
    final DynamicTableSource newTableSource = sourceTable.tableSource().copy();
    final SourceAbilityContext context = SourceAbilityContext.from(scan);
    abilitySpecs.forEach(spec -> spec.apply(newTableSource, context));
    final RelDataType newRowType = typeFactory.buildRelNodeRowType(newProducedType);
    final TableSourceTable newSource = sourceTable.copy(newTableSource, newRowType, abilitySpecs.toArray(new SourceAbilitySpec[0]));
    final LogicalTableScan newScan = new LogicalTableScan(scan.getCluster(), scan.getTraitSet(), scan.getHints(), newSource);
    final LogicalProject newProject = project.copy(project.getTraitSet(), newScan, rewriteProjections(call, newSource, projectedSchema), project.getRowType());
    if (ProjectRemoveRule.isTrivial(newProject)) {
        call.transformTo(newScan);
    } else {
        call.transformTo(newProject);
    }
}
Also used : SourceAbilitySpec(org.apache.flink.table.planner.plan.abilities.source.SourceAbilitySpec) ArrayList(java.util.ArrayList) RowType(org.apache.flink.table.types.logical.RowType) NestedColumn(org.apache.flink.table.planner.plan.utils.NestedColumn) RelDataType(org.apache.calcite.rel.type.RelDataType) LogicalTableScan(org.apache.calcite.rel.logical.LogicalTableScan) FlinkTypeFactory(org.apache.flink.table.planner.calcite.FlinkTypeFactory) SourceAbilityContext(org.apache.flink.table.planner.plan.abilities.source.SourceAbilityContext) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) TableSourceTable(org.apache.flink.table.planner.plan.schema.TableSourceTable) ResolvedSchema(org.apache.flink.table.catalog.ResolvedSchema) DynamicTableSource(org.apache.flink.table.connector.source.DynamicTableSource) NestedSchema(org.apache.flink.table.planner.plan.utils.NestedSchema)

Example 13 with LogicalProject

use of org.apache.calcite.rel.logical.LogicalProject in project flink by apache.

the class SubQueryDecorrelator method addProjectionForIn.

/**
 * Adds Projection to adjust the field index for join condition.
 *
 * <p>e.g. SQL: SELECT * FROM l WHERE b IN (SELECT COUNT(*) FROM r WHERE l.c = r.f the rel in
 * SubQuery is `LogicalAggregate(group=[{}], EXPR$1=[COUNT()])`. After decorrelated, it was
 * changed to `LogicalAggregate(group=[{0}], EXPR$0=[COUNT()])`, and the output index of
 * `COUNT()` was changed from 0 to 1. So, add a project (`LogicalProject(EXPR$0=[$1], f=[$0])`)
 * to adjust output fields order.
 */
private RelNode addProjectionForIn(RelNode relNode) {
    if (relNode instanceof LogicalProject) {
        return relNode;
    }
    RelDataType rowType = relNode.getRowType();
    final List<RexNode> projects = new ArrayList<>();
    for (int i = 0; i < rowType.getFieldCount(); ++i) {
        projects.add(RexInputRef.of(i, rowType));
    }
    relBuilder.clear();
    relBuilder.push(relNode);
    relBuilder.project(projects, rowType.getFieldNames(), true);
    return relBuilder.build();
}
Also used : ArrayList(java.util.ArrayList) RelDataType(org.apache.calcite.rel.type.RelDataType) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode)

Example 14 with LogicalProject

use of org.apache.calcite.rel.logical.LogicalProject in project flink by apache.

the class FlinkSemiAntiJoinProjectTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
public void onMatch(RelOptRuleCall call) {
    LogicalJoin join = call.rel(0);
    LogicalProject project = call.rel(1);
    // convert the semi/anti join condition to reflect the LHS with the project
    // pulled up
    RexNode newCondition = adjustCondition(project, join);
    Join newJoin = LogicalJoin.create(project.getInput(), join.getRight(), join.getHints(), newCondition, join.getVariablesSet(), join.getJoinType());
    // Create the new projection. Note that the projection expressions
    // are the same as the original because they only reference the LHS
    // of the semi/anti join and the semi/anti join only projects out the LHS
    final RelBuilder relBuilder = call.builder();
    relBuilder.push(newJoin);
    relBuilder.project(project.getProjects(), project.getRowType().getFieldNames());
    call.transformTo(relBuilder.build());
}
Also used : RelBuilder(org.apache.calcite.tools.RelBuilder) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) Join(org.apache.calcite.rel.core.Join) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode)

Example 15 with LogicalProject

use of org.apache.calcite.rel.logical.LogicalProject in project flink by apache.

the class FlinkSemiAntiJoinProjectTransposeRule method matches.

@Override
public boolean matches(RelOptRuleCall call) {
    LogicalJoin join = call.rel(0);
    LogicalProject project = call.rel(1);
    // only accept SEMI/ANTI join
    JoinRelType joinType = join.getJoinType();
    if (joinType != JoinRelType.SEMI && joinType != JoinRelType.ANTI) {
        return false;
    }
    // all expressions in Project should be RexInputRef
    for (RexNode p : project.getProjects()) {
        if (!(p instanceof RexInputRef)) {
            return false;
        }
    }
    return true;
}
Also used : JoinRelType(org.apache.calcite.rel.core.JoinRelType) LogicalJoin(org.apache.calcite.rel.logical.LogicalJoin) RexInputRef(org.apache.calcite.rex.RexInputRef) LogicalProject(org.apache.calcite.rel.logical.LogicalProject) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

LogicalProject (org.apache.calcite.rel.logical.LogicalProject)38 RexNode (org.apache.calcite.rex.RexNode)20 ArrayList (java.util.ArrayList)13 RelNode (org.apache.calcite.rel.RelNode)12 LogicalJoin (org.apache.calcite.rel.logical.LogicalJoin)11 LogicalFilter (org.apache.calcite.rel.logical.LogicalFilter)9 RelDataType (org.apache.calcite.rel.type.RelDataType)8 LogicalTableScan (org.apache.calcite.rel.logical.LogicalTableScan)6 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)6 RexBuilder (org.apache.calcite.rex.RexBuilder)6 Test (org.junit.Test)6 RexInputRef (org.apache.calcite.rex.RexInputRef)5 RelBuilder (org.apache.calcite.tools.RelBuilder)4 LogicalProject (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject)3 TableScan (org.apache.calcite.rel.core.TableScan)3 RexCall (org.apache.calcite.rex.RexCall)3 SqlOperator (org.apache.calcite.sql.SqlOperator)3 NlsString (org.apache.calcite.util.NlsString)3 ImmutableList (com.google.common.collect.ImmutableList)2 PrintWriter (java.io.PrintWriter)2