示例#1
0
  /**
   * Combines the join filters from the left and right inputs (if they are MultiJoinRels) with the
   * join filter in the joinrel into a single AND'd join filter, unless the inputs correspond to
   * null generating inputs in an outer join
   *
   * @param joinRel join rel
   * @param left left child of the joinrel
   * @param right right child of the joinrel
   * @return combined join filters AND'd together
   */
  private RexNode combineJoinFilters(JoinRel joinRel, RelNode left, RelNode right) {
    RexBuilder rexBuilder = joinRel.getCluster().getRexBuilder();
    JoinRelType joinType = joinRel.getJoinType();

    // first need to adjust the RexInputs of the right child, since
    // those need to shift over to the right
    RexNode rightFilter = null;
    if (canCombine(right, joinType.generatesNullsOnRight())) {
      MultiJoinRel multiJoin = (MultiJoinRel) right;
      rightFilter = shiftRightFilter(joinRel, left, multiJoin, multiJoin.getJoinFilter());
    }

    // AND the join condition if this isn't a left or right outer join;
    // in those cases, the outer join condition is already tracked
    // separately
    RexNode newFilter = null;
    if ((joinType != JoinRelType.LEFT) && (joinType != JoinRelType.RIGHT)) {
      newFilter = joinRel.getCondition();
    }
    if (canCombine(left, joinType.generatesNullsOnLeft())) {
      RexNode leftFilter = ((MultiJoinRel) left).getJoinFilter();
      newFilter = RelOptUtil.andJoinFilters(rexBuilder, newFilter, leftFilter);
    }
    newFilter = RelOptUtil.andJoinFilters(rexBuilder, newFilter, rightFilter);

    return newFilter;
  }
  // implement RelOptRule
  public void onMatch(RelOptRuleCall call) {
    FilterRel filterRel = call.rel(0);
    MultiJoinRel multiJoinRel = call.rel(1);

    MultiJoinRel newMultiJoinRel =
        new MultiJoinRel(
            multiJoinRel.getCluster(),
            multiJoinRel.getInputs(),
            multiJoinRel.getJoinFilter(),
            multiJoinRel.getRowType(),
            multiJoinRel.isFullOuterJoin(),
            multiJoinRel.getOuterJoinConditions(),
            multiJoinRel.getJoinTypes(),
            multiJoinRel.getProjFields(),
            multiJoinRel.getJoinFieldRefCountsMap(),
            filterRel.getCondition());

    call.transformTo(newMultiJoinRel);
  }