private ExprNodeDesc[][] genJoinKeys(QBJoinTree joinTree, Operator[] inputs)
      throws SemanticException {
    ExprNodeDesc[][] joinKeys = new ExprNodeDesc[inputs.length][];
    for (int i = 0; i < inputs.length; i++) {
      RowResolver inputRR = opParseCtx.get(inputs[i]).getRowResolver();
      List<ASTNode> expressions = joinTree.getExpressions().get(i);
      joinKeys[i] = new ExprNodeDesc[expressions.size()];
      for (int j = 0; j < joinKeys[i].length; j++) {
        joinKeys[i][j] = genExprNodeDesc(expressions.get(j), inputRR, true, isCBOExecuted());
      }
    }
    // Type checking and implicit type conversion for join keys
    return genJoinOperatorTypeCheck(joinKeys);
  }
Creates an expression for converting from a table column to a row column. For example:
The table column is int but the query provides a string in the row, then we need to cast automatically.
@param tableField The target table column
@param rowField The source row column
@param conversion The value of this boolean is set to true if we detect that a conversion is needed. This is a
                  hidden return value hidden here, to notify the caller that a cast was needed.
@param dest The destination table for the error message
@param columnNum The destination column id for the error message
@return The Expression describing the selected column. Note that `conversion` can be considered as a return value
        as well
@throws SemanticException If conversion were needed, but automatic conversion is not available
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java