Search in sources :

Example 1 with BeamUnnestRel

use of org.apache.beam.sdk.extensions.sql.impl.rel.BeamUnnestRel in project beam by apache.

the class BeamUnnestRule method onMatch.

@Override
public void onMatch(RelOptRuleCall call) {
    LogicalCorrelate correlate = call.rel(0);
    RelNode outer = call.rel(1);
    RelNode uncollect = call.rel(2);
    if (correlate.getCorrelationId().getId() != 0) {
        // Only one level of correlation nesting is supported
        return;
    }
    if (correlate.getRequiredColumns().cardinality() != 1) {
        // can only unnest a single column
        return;
    }
    if (correlate.getJoinType() != JoinRelType.INNER) {
        return;
    }
    if (!(uncollect instanceof Uncollect)) {
        // Drop projection
        uncollect = ((SingleRel) uncollect).getInput();
        if (uncollect instanceof RelSubset) {
            uncollect = ((RelSubset) uncollect).getOriginal();
        }
        if (!(uncollect instanceof Uncollect)) {
            return;
        }
    }
    RelNode project = ((Uncollect) uncollect).getInput();
    if (project instanceof RelSubset) {
        project = ((RelSubset) project).getOriginal();
    }
    if (!(project instanceof LogicalProject)) {
        return;
    }
    if (((LogicalProject) project).getProjects().size() != 1) {
        // can only unnest a single column
        return;
    }
    RexNode exp = ((LogicalProject) project).getProjects().get(0);
    if (!(exp instanceof RexFieldAccess)) {
        return;
    }
    RexFieldAccess fieldAccess = (RexFieldAccess) exp;
    // Innermost field index comes first (e.g. struct.field1.field2 => [2, 1])
    ImmutableList.Builder<Integer> fieldAccessIndices = ImmutableList.builder();
    while (true) {
        fieldAccessIndices.add(fieldAccess.getField().getIndex());
        if (!(fieldAccess.getReferenceExpr() instanceof RexFieldAccess)) {
            break;
        }
        fieldAccess = (RexFieldAccess) fieldAccess.getReferenceExpr();
    }
    call.transformTo(new BeamUnnestRel(correlate.getCluster(), correlate.getTraitSet().replace(BeamLogicalConvention.INSTANCE), convert(outer, outer.getTraitSet().replace(BeamLogicalConvention.INSTANCE)), call.rel(2).getRowType(), fieldAccessIndices.build()));
}
Also used : Uncollect(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Uncollect) RelNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode) ImmutableList(org.apache.beam.vendor.calcite.v1_28_0.com.google.common.collect.ImmutableList) LogicalCorrelate(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate) LogicalProject(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject) RexFieldAccess(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexFieldAccess) RelSubset(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.volcano.RelSubset) RexNode(org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode) BeamUnnestRel(org.apache.beam.sdk.extensions.sql.impl.rel.BeamUnnestRel)

Aggregations

BeamUnnestRel (org.apache.beam.sdk.extensions.sql.impl.rel.BeamUnnestRel)1 ImmutableList (org.apache.beam.vendor.calcite.v1_28_0.com.google.common.collect.ImmutableList)1 RelSubset (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.plan.volcano.RelSubset)1 RelNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.RelNode)1 Uncollect (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.core.Uncollect)1 LogicalCorrelate (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalCorrelate)1 LogicalProject (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rel.logical.LogicalProject)1 RexFieldAccess (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexFieldAccess)1 RexNode (org.apache.beam.vendor.calcite.v1_28_0.org.apache.calcite.rex.RexNode)1