public static ExprNodeDesc resolveJoinKeysAsRSColumns(ExprNodeDesc source, Operator<?> reduceSinkOp) {
    // Assuming this is only being done for join keys. As a result we shouldn't have to recursively
    // check any nested child expressions, because the result of the expression should exist as an
    // output column of the ReduceSink operator
    if (source == null) {
      return null;
    }

    // columnExprMap has the reverse of what we need - a mapping of the internal column names
    // to the ExprNodeDesc from the previous operation.
    // Find the key/value where the ExprNodeDesc value matches the column we are searching for.
    // The key portion of the entry will be the internal column name for the join key expression.
    for (Map.Entry<String, ExprNodeDesc> mapEntry : reduceSinkOp.getColumnExprMap().entrySet()) {
      if (mapEntry.getValue().equals(source)) {
        String columnInternalName = mapEntry.getKey();
        // Joins always use KEY columns for the keys, so avoid resolving to VALUE columns
        if(columnInternalName.startsWith(Utilities.ReduceField.VALUE.toString())) {
          continue;
        }
        ColumnInfo columnInfo = reduceSinkOp.getSchema().getColumnInfo(columnInternalName);
        if (source instanceof ExprNodeColumnDesc && columnInfo != null) {
          // The join key is a table column. Create the ExprNodeDesc based on this column.
          return new ExprNodeColumnDesc(columnInfo);
        } else {
          // Join key expression is likely some expression involving functions/operators, so there
          // is no actual table column for this. But the ReduceSink operator should still have an
          // output column corresponding to this expression, using the columnInternalName.
          String tabAlias = "";
          // HIVE-21746: Set tabAlias when possible, such as for constant folded column
          // that has foldedFromTab info.
          if (source instanceof ExprNodeConstantDesc) {
            tabAlias = ((ExprNodeConstantDesc) source).getFoldedFromTab();
          }
          return new ExprNodeColumnDesc(source.getTypeInfo(), columnInternalName, tabAlias, false);
        }
      }
    }

    return null;  // Couldn't find reference to expression
  }
Join keys are expressions based on the select operator. Resolve the expressions so they
are based on the ReduceSink operator
  SEL -&gt; RS -&gt; JOIN
@param source
@param reduceSinkOp
@return
ql/src/java/org/apache/hadoop/hive/ql/plan/ExprNodeDescUtils.java