示例#1
0
  /**
   * Shifts a filter originating from the right child of the JoinRel to the right, to reflect the
   * filter now being applied on the resulting MultiJoinRel.
   *
   * @param joinRel the original JoinRel
   * @param left the left child of the JoinRel
   * @param right the right child of the JoinRel
   * @param rightFilter the filter originating from the right child
   * @return the adjusted right filter
   */
  private RexNode shiftRightFilter(
      JoinRel joinRel, RelNode left, MultiJoinRel right, RexNode rightFilter) {
    if (rightFilter == null) {
      return null;
    }

    int nFieldsOnLeft = left.getRowType().getFields().length;
    int nFieldsOnRight = right.getRowType().getFields().length;
    int[] adjustments = new int[nFieldsOnRight];
    for (int i = 0; i < nFieldsOnRight; i++) {
      adjustments[i] = nFieldsOnLeft;
    }
    rightFilter =
        rightFilter.accept(
            new RelOptUtil.RexInputConverter(
                joinRel.getCluster().getRexBuilder(),
                right.getRowType().getFields(),
                joinRel.getRowType().getFields(),
                adjustments));
    return rightFilter;
  }
  // 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);
  }