/** * 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); }