private LazyBinaryStructObjectInspector createInternalOi(MapJoinObjectSerDeContext valCtx)
      throws SerDeException {
    // We are going to use LBSerDe to serialize values; create OI for retrieval.
    List<? extends StructField> fields =
        ((StructObjectInspector) valCtx.getSerDe().getObjectInspector()).getAllStructFieldRefs();
    List<String> colNames = new ArrayList<String>(fields.size());
    List<ObjectInspector> colOis = new ArrayList<ObjectInspector>(fields.size());
    for (int i = 0; i < fields.size(); ++i) {
      StructField field = fields.get(i);
      colNames.add(field.getFieldName());
      // It would be nice if OI could return typeInfo...
      TypeInfo typeInfo =
          TypeInfoUtils.getTypeInfoFromTypeString(field.getFieldObjectInspector().getTypeName());
      colOis.add(LazyBinaryUtils.getLazyBinaryObjectInspectorFromTypeInfo(typeInfo));
    }

    return LazyBinaryObjectInspectorFactory.getLazyBinaryStructObjectInspector(colNames, colOis);
  }
 /**
  * Returns the lazy binary object inspector that can be used to inspect an lazy binary object of
  * that typeInfo
  *
  * <p>For primitive types, we use the standard writable object inspector.
  */
 public static ObjectInspector getLazyBinaryObjectInspectorFromTypeInfo(TypeInfo typeInfo) {
   ObjectInspector result = cachedLazyBinaryObjectInspector.get(typeInfo);
   if (result == null) {
     switch (typeInfo.getCategory()) {
       case PRIMITIVE:
         {
           result =
               PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(
                   ((PrimitiveTypeInfo) typeInfo));
           break;
         }
       case LIST:
         {
           ObjectInspector elementObjectInspector =
               getLazyBinaryObjectInspectorFromTypeInfo(
                   ((ListTypeInfo) typeInfo).getListElementTypeInfo());
           result =
               LazyBinaryObjectInspectorFactory.getLazyBinaryListObjectInspector(
                   elementObjectInspector);
           break;
         }
       case MAP:
         {
           MapTypeInfo mapTypeInfo = (MapTypeInfo) typeInfo;
           ObjectInspector keyObjectInspector =
               getLazyBinaryObjectInspectorFromTypeInfo(mapTypeInfo.getMapKeyTypeInfo());
           ObjectInspector valueObjectInspector =
               getLazyBinaryObjectInspectorFromTypeInfo(mapTypeInfo.getMapValueTypeInfo());
           result =
               LazyBinaryObjectInspectorFactory.getLazyBinaryMapObjectInspector(
                   keyObjectInspector, valueObjectInspector);
           break;
         }
       case STRUCT:
         {
           StructTypeInfo structTypeInfo = (StructTypeInfo) typeInfo;
           List<String> fieldNames = structTypeInfo.getAllStructFieldNames();
           List<TypeInfo> fieldTypeInfos = structTypeInfo.getAllStructFieldTypeInfos();
           List<ObjectInspector> fieldObjectInspectors =
               new ArrayList<ObjectInspector>(fieldTypeInfos.size());
           for (int i = 0; i < fieldTypeInfos.size(); i++) {
             fieldObjectInspectors.add(
                 getLazyBinaryObjectInspectorFromTypeInfo(fieldTypeInfos.get(i)));
           }
           result =
               LazyBinaryObjectInspectorFactory.getLazyBinaryStructObjectInspector(
                   fieldNames, fieldObjectInspectors);
           break;
         }
       case UNION:
         {
           UnionTypeInfo unionTypeInfo = (UnionTypeInfo) typeInfo;
           final List<TypeInfo> fieldTypeInfos = unionTypeInfo.getAllUnionObjectTypeInfos();
           List<ObjectInspector> fieldObjectInspectors =
               new ArrayList<ObjectInspector>(fieldTypeInfos.size());
           for (int i = 0; i < fieldTypeInfos.size(); i++) {
             fieldObjectInspectors.add(
                 getLazyBinaryObjectInspectorFromTypeInfo(fieldTypeInfos.get(i)));
           }
           result =
               LazyBinaryObjectInspectorFactory.getLazyBinaryUnionObjectInspector(
                   fieldObjectInspectors);
           break;
         }
       default:
         {
           result = null;
         }
     }
     ObjectInspector prev = cachedLazyBinaryObjectInspector.putIfAbsent(typeInfo, result);
     if (prev != null) {
       result = prev;
     }
   }
   return result;
 }