private static ObjectInspector unflattenObjInspector(ObjectInspector oi) {
    if (oi instanceof StructObjectInspector) {
      // Check if all fields start with "key." or "value."
      // If so, then unflatten by adding a level of nested key and value structs
      // Example: { "key.reducesinkkey0":int, "key.reducesinkkey1": int, "value._col6":int }
      // Becomes
      //   { "key": { "reducesinkkey0":int, "reducesinkkey1":int }, "value": { "_col6":int } }
      ArrayList<StructField> keyFields = new ArrayList<StructField>();
      ArrayList<StructField> valueFields = new ArrayList<StructField>();
      for (StructField field : ((StructObjectInspector) oi).getAllStructFieldRefs()) {
        String fieldNameLower = field.getFieldName().toLowerCase();
        if (fieldNameLower.startsWith(KEY_FIELD_PREFIX)) {
          keyFields.add(field);
        } else if (fieldNameLower.startsWith(VALUE_FIELD_PREFIX)) {
          valueFields.add(field);
        } else {
          // Not a flattened struct, no need to unflatten
          return oi;
        }
      }

      // All field names are of the form "key." or "value."
      // Create key/value structs and add the respective fields to each one
      ArrayList<ObjectInspector> reduceFieldOIs = new ArrayList<ObjectInspector>();
      reduceFieldOIs.add(createStructFromFields(keyFields, Utilities.ReduceField.KEY.toString()));
      reduceFieldOIs.add(createStructFromFields(valueFields, Utilities.ReduceField.VALUE.toString()));

      // Finally create the outer struct to contain the key, value structs
      return ObjectInspectorFactory.getStandardStructObjectInspector(
          Utilities.reduceFieldNameList,
          reduceFieldOIs);
    }

    return oi;
  }
Checks the input object inspector to see if it is in for form of a flattened struct
like the ones generated by a vectorized reduce sink input:
  { 'key.reducesinkkey0':int, 'value._col0':int, 'value._col1':int, .. }
If so, then it creates an "unflattened" struct that contains nested key/value
structs:
  { key: { reducesinkkey0:int }, value: { _col0:int, _col1:int, .. } }

@param oi
@return unflattened object inspector if unflattening is needed,
        otherwise the original object inspector
ql/src/java/org/apache/hadoop/hive/ql/exec/JoinUtil.java