示例#1
0
  /**
   * Copies outer join data from a source MultiJoinRel to a new set of arrays. Also adjusts the
   * conditions to reflect the new position of an input if that input ends up being shifted to the
   * right.
   *
   * @param multiJoinRel the source MultiJoinRel
   * @param destConds the array where the join conditions will be copied
   * @param destJoinTypes the array where the join types will be copied
   * @param destPos starting position in the array where the copying starts
   * @param adjustmentAmount if > 0, the amount the RexInputRefs in the join conditions need to be
   *     adjusted by
   * @param srcFields the source fields that the original join conditions are referencing
   * @param destFields the destination fields that the new join conditions will be referencing
   */
  private void copyOuterJoinInfo(
      MultiJoinRel multiJoinRel,
      RexNode[] destConds,
      JoinRelType[] destJoinTypes,
      int destPos,
      int adjustmentAmount,
      RelDataTypeField[] srcFields,
      RelDataTypeField[] destFields) {
    RexNode[] srcConds = multiJoinRel.getOuterJoinConditions();
    JoinRelType[] srcJoinTypes = multiJoinRel.getJoinTypes();
    RexBuilder rexBuilder = multiJoinRel.getCluster().getRexBuilder();

    int len = srcConds.length;
    System.arraycopy(srcJoinTypes, 0, destJoinTypes, destPos, len);

    if (adjustmentAmount == 0) {
      System.arraycopy(srcConds, 0, destConds, 0, len);
    } else {
      int nFields = srcFields.length;
      int[] adjustments = new int[nFields];
      for (int idx = 0; idx < nFields; idx++) {
        adjustments[idx] = adjustmentAmount;
      }
      for (int i = 0; i < len; i++) {
        if (srcConds[i] != null) {
          destConds[i + destPos] =
              srcConds[i].accept(
                  new RelOptUtil.RexInputConverter(rexBuilder, srcFields, destFields, adjustments));
        }
      }
    }
  }
  // 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);
  }