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