Search in sources :

Example 1 with PushProjector

use of org.apache.calcite.rel.rules.PushProjector in project hive by apache.

the class HiveProjectJoinTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Project origProj = call.rel(0);
    final Join join = call.rel(1);
    if (join.getJoinType() == JoinRelType.SEMI || join.getJoinType() == JoinRelType.ANTI) {
        // TODO: support SemiJoin
        return;
    }
    // locate all fields referenced in the projection and join condition;
    // determine which inputs are referenced in the projection and
    // join condition; if all fields are being referenced and there are no
    // special expressions, no point in proceeding any further
    PushProjector pushProject = new PushProjector(origProj, join.getCondition(), join, preserveExprCondition, call.builder());
    if (pushProject.locateAllRefs()) {
        return;
    }
    // create left and right projections, projecting only those
    // fields referenced on each side
    RelNode leftProjRel = pushProject.createProjectRefsAndExprs(join.getLeft(), true, false);
    RelNode rightProjRel = pushProject.createProjectRefsAndExprs(join.getRight(), true, true);
    // convert the join condition to reference the projected columns
    RexNode newJoinFilter = null;
    int[] adjustments = pushProject.getAdjustments();
    if (join.getCondition() != null) {
        List<RelDataTypeField> projJoinFieldList = new ArrayList<>();
        projJoinFieldList.addAll(join.getSystemFieldList());
        projJoinFieldList.addAll(leftProjRel.getRowType().getFieldList());
        projJoinFieldList.addAll(rightProjRel.getRowType().getFieldList());
        newJoinFilter = pushProject.convertRefsAndExprs(join.getCondition(), projJoinFieldList, adjustments);
    }
    // create a new join with the projected children
    Join newJoinRel = join.copy(join.getTraitSet(), newJoinFilter, leftProjRel, rightProjRel, join.getJoinType(), join.isSemiJoinDone());
    // put the original project on top of the join, converting it to
    // reference the modified projection list
    RelNode topProject = pushProject.createNewProject(newJoinRel, adjustments);
    call.transformTo(topProject);
}
Also used : Project(org.apache.calcite.rel.core.Project) PushProjector(org.apache.calcite.rel.rules.PushProjector) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) RexNode(org.apache.calcite.rex.RexNode)

Example 2 with PushProjector

use of org.apache.calcite.rel.rules.PushProjector in project flink by apache.

the class FlinkProjectJoinTransposeRule method onMatch.

// ~ Methods ----------------------------------------------------------------
// implement RelOptRule
public void onMatch(RelOptRuleCall call) {
    Project origProj = call.rel(0);
    final Join join = call.rel(1);
    if (!join.getJoinType().projectsRight()) {
        // TODO: support SEMI/ANTI join later
        return;
    }
    // locate all fields referenced in the projection and join condition;
    // determine which inputs are referenced in the projection and
    // join condition; if all fields are being referenced and there are no
    // special expressions, no point in proceeding any further
    PushProjector pushProject = new PushProjector(origProj, join.getCondition(), join, preserveExprCondition, call.builder());
    if (pushProject.locateAllRefs()) {
        return;
    }
    // create left and right projections, projecting only those
    // fields referenced on each side
    RelNode leftProjRel = pushProject.createProjectRefsAndExprs(join.getLeft(), true, false);
    RelNode rightProjRel = pushProject.createProjectRefsAndExprs(join.getRight(), true, true);
    // convert the join condition to reference the projected columns
    RexNode newJoinFilter = null;
    int[] adjustments = pushProject.getAdjustments();
    if (join.getCondition() != null) {
        List<RelDataTypeField> projJoinFieldList = new ArrayList<>();
        projJoinFieldList.addAll(join.getSystemFieldList());
        projJoinFieldList.addAll(leftProjRel.getRowType().getFieldList());
        projJoinFieldList.addAll(rightProjRel.getRowType().getFieldList());
        newJoinFilter = pushProject.convertRefsAndExprs(join.getCondition(), projJoinFieldList, adjustments);
    }
    // create a new join with the projected children
    Join newJoinRel = join.copy(join.getTraitSet(), newJoinFilter, leftProjRel, rightProjRel, join.getJoinType(), join.isSemiJoinDone());
    // put the original project on top of the join, converting it to
    // reference the modified projection list
    RelNode topProject = pushProject.createNewProject(newJoinRel, adjustments);
    call.transformTo(topProject);
}
Also used : Project(org.apache.calcite.rel.core.Project) PushProjector(org.apache.calcite.rel.rules.PushProjector) RelDataTypeField(org.apache.calcite.rel.type.RelDataTypeField) RelNode(org.apache.calcite.rel.RelNode) ArrayList(java.util.ArrayList) Join(org.apache.calcite.rel.core.Join) RexNode(org.apache.calcite.rex.RexNode)

Aggregations

ArrayList (java.util.ArrayList)2 RelNode (org.apache.calcite.rel.RelNode)2 Join (org.apache.calcite.rel.core.Join)2 Project (org.apache.calcite.rel.core.Project)2 PushProjector (org.apache.calcite.rel.rules.PushProjector)2 RelDataTypeField (org.apache.calcite.rel.type.RelDataTypeField)2 RexNode (org.apache.calcite.rex.RexNode)2