private Operator insertSelectForSemijoin(List<ASTNode> fields,
                                           Operator<?> input) throws SemanticException {

    RowResolver inputRR = opParseCtx.get(input).getRowResolver();
    List<ExprNodeDesc> colList = new ArrayList<ExprNodeDesc>();
    List<String> outputColumnNames = new ArrayList<String>();
    Map<String, ExprNodeDesc> colExprMap = new HashMap<String, ExprNodeDesc>();

    RowResolver outputRR = new RowResolver();

    // construct the list of columns that need to be projected
    for (int i = 0; i < fields.size(); ++i) {
      ASTNode field = fields.get(i);
      String[] nm;
      String[] nm2;
      ExprNodeDesc expr = genExprNodeDesc(field, inputRR);
      if (expr instanceof ExprNodeColumnDesc) {
        // In most of the cases, this is a column reference
        ExprNodeColumnDesc columnExpr = (ExprNodeColumnDesc) expr;
        nm = inputRR.reverseLookup(columnExpr.getColumn());
        nm2 = inputRR.getAlternateMappings(columnExpr.getColumn());
      } else if (expr instanceof ExprNodeConstantDesc) {
        // However, it can be a constant too. In that case, we need to track
        // the column that it originated from in the input operator so we can
        // propagate the aliases.
        ExprNodeConstantDesc constantExpr = (ExprNodeConstantDesc) expr;
        String inputCol = constantExpr.getFoldedFromCol();
        nm = inputRR.reverseLookup(inputCol);
        nm2 = inputRR.getAlternateMappings(inputCol);
      } else {
        // We might generate other types that are not recognized, e.g., a field reference
        // if it is a nested field, but since this is just an additional optimization,
        // we bail out without introducing the Select + GroupBy below the right input
        // of the left semijoin
        return input;
      }
      String colName = getColumnInternalName(i);
      outputColumnNames.add(colName);
      ColumnInfo colInfo = new ColumnInfo(colName, expr.getTypeInfo(), "", false);
      outputRR.put(nm[0], nm[1], colInfo);
      if (nm2 != null) {
        outputRR.addMappingOnly(nm2[0], nm2[1], colInfo);
      }
      colList.add(expr);
      colExprMap.put(colName, expr);
    }

    // create selection operator
    Operator output = putOpInsertMap(OperatorFactory.getAndMakeChild(
        new SelectDesc(colList, outputColumnNames, false),
        new RowSchema(outputRR.getColumnInfos()), input), outputRR);

    output.setColumnExprMap(colExprMap);
    return output;
  }
Construct a selection operator for semijoin that filter out all fields
other than the group by keys.

@param fields
         list of fields need to be output
@param input
         input operator
@return the selection operator.
@throws SemanticException
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java