protected T swapInputs(final Join join, final T topOperator, final RelBuilder builder) {
      RexBuilder rexBuilder = join.getCluster().getRexBuilder();

      int rightInputSize = join.getRight().getRowType().getFieldCount();
      int leftInputSize = join.getLeft().getRowType().getFieldCount();
      List<RelDataTypeField> joinFields = join.getRowType().getFieldList();

      //swap the join inputs
      //adjust join condition
      int[] adjustments = new int[joinFields.size()];
      for (int i=0; i<joinFields.size(); i++) {
        if(i < leftInputSize) {
          //left side refs need to be moved by right input size
          adjustments[i] = rightInputSize;
        } else {
          //right side refs need to move "down" by left input size
          adjustments[i] = -leftInputSize;
        }
      }
      RexNode newJoinCond = join.getCondition().accept(
          new RelOptUtil.RexInputConverter(rexBuilder, joinFields, joinFields, adjustments));
      RelNode swappedJoin = builder
          .push(join.getRight())
          .push(join.getLeft())
          .join(join.getJoinType(), newJoinCond)
          .build();
      // need to adjust top refs
      return recreateTopOperator(builder, rexBuilder, adjustments, topOperator, swappedJoin);
    }
Rule that swaps Join inputs if they can potentially lead to SemiJoin conversion.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/calcite/rules/HiveSemiJoinRule.java