private static RuntimeValuesInfo createRuntimeValuesInfo(ReduceSinkOperator rs, List<ReduceSinkOperator> sjBranches,
      ParseContext parseContext) {
    List<ExprNodeDesc> valueCols = rs.getConf().getValueCols();
    RuntimeValuesInfo info = new RuntimeValuesInfo();
    TableDesc rsFinalTableDesc =
        PlanUtils.getReduceValueTableDesc(PlanUtils.getFieldSchemasFromColumnList(valueCols, "_col"));
    List<String> dynamicValueIDs = new ArrayList<>();
    for (ExprNodeDesc rsCol : valueCols) {
      dynamicValueIDs.add(rs.toString() + rsCol.getExprString());
    }

    info.setTableDesc(rsFinalTableDesc);
    info.setDynamicValueIDs(dynamicValueIDs);
    info.setColExprs(valueCols);
    List<ExprNodeDesc> targetTableExpressions = new ArrayList<>();
    for (ReduceSinkOperator sjBranch : sjBranches) {
      RuntimeValuesInfo sjInfo = parseContext.getRsToRuntimeValuesInfoMap().get(sjBranch);
      checkState(sjInfo.getTargetColumns().size() == 1, "Cannot handle multi-column semijoin branches.");
      targetTableExpressions.add(sjInfo.getTargetColumns().get(0));
    }
    info.setTargetColumns(targetTableExpressions);
    return info;
  }
Creates the necessary information in order to execute the multi-column semi join and perform further optimizations.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/SemiJoinReductionMerge.java