private ObjectInspector solveOi(ObjectInspector arg) {

    switch (arg.getCategory()) {
      case PRIMITIVE:

        // VOID, BOOLEAN, BYTE, SHORT, INT, LONG, FLOAT, DOUBLE, STRING, TIMESTAMP, BINARY, DECIMAL,
        // UNKNOWN
        PrimitiveObjectInspector poi = (PrimitiveObjectInspector) arg;
        return PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(
            poi.getPrimitiveCategory());
      case LIST:
        return ObjectInspectorFactory.getStandardListObjectInspector(
            solveOi(((ListObjectInspector) arg).getListElementObjectInspector()));
      case MAP:
        return ObjectInspectorFactory.getStandardMapObjectInspector(
            solveOi(((MapObjectInspector) arg).getMapKeyObjectInspector()),
            solveOi(((MapObjectInspector) arg).getMapValueObjectInspector()));
      case STRUCT:
        StructObjectInspector soi = (StructObjectInspector) arg;
        int size = soi.getAllStructFieldRefs().size();
        ArrayList<String> fnl = new ArrayList<String>(size);
        ArrayList<ObjectInspector> foil = new ArrayList<ObjectInspector>(size);

        for (StructField sf : ((StructObjectInspector) arg).getAllStructFieldRefs()) {
          fnl.add(sf.getFieldName());
          foil.add(solveOi(sf.getFieldObjectInspector()));
        }

        return JsonStructObjectInspector.getJsonStructObjectInspector(fnl, foil);
      default:
        return arg;
    }
  }
 public static ObjectInspector getStandardObjectInspector(
     ObjectInspector oi, ObjectInspectorCopyOption objectInspectorOption) {
   ObjectInspector result = null;
   switch (oi.getCategory()) {
     case PRIMITIVE:
       {
         PrimitiveObjectInspector poi = (PrimitiveObjectInspector) oi;
         switch (objectInspectorOption) {
           case DEFAULT:
             {
               if (poi.preferWritable()) {
                 result =
                     PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(
                         poi.getTypeInfo());
               } else {
                 result =
                     PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(
                         poi.getTypeInfo());
               }
               break;
             }
           case JAVA:
             {
               result =
                   PrimitiveObjectInspectorFactory.getPrimitiveJavaObjectInspector(
                       poi.getTypeInfo());
               break;
             }
           case WRITABLE:
             result =
                 PrimitiveObjectInspectorFactory.getPrimitiveWritableObjectInspector(
                     poi.getTypeInfo());
             break;
         }
         break;
       }
     case LIST:
       {
         ListObjectInspector loi = (ListObjectInspector) oi;
         result =
             ObjectInspectorFactory.getStandardListObjectInspector(
                 getStandardObjectInspector(
                     loi.getListElementObjectInspector(), objectInspectorOption));
         break;
       }
     case MAP:
       {
         MapObjectInspector moi = (MapObjectInspector) oi;
         result =
             ObjectInspectorFactory.getStandardMapObjectInspector(
                 getStandardObjectInspector(moi.getMapKeyObjectInspector(), objectInspectorOption),
                 getStandardObjectInspector(
                     moi.getMapValueObjectInspector(), objectInspectorOption));
         break;
       }
     case STRUCT:
       {
         StructObjectInspector soi = (StructObjectInspector) oi;
         List<? extends StructField> fields = soi.getAllStructFieldRefs();
         List<String> fieldNames = new ArrayList<String>(fields.size());
         List<ObjectInspector> fieldObjectInspectors =
             new ArrayList<ObjectInspector>(fields.size());
         for (StructField f : fields) {
           fieldNames.add(f.getFieldName());
           fieldObjectInspectors.add(
               getStandardObjectInspector(f.getFieldObjectInspector(), objectInspectorOption));
         }
         result =
             ObjectInspectorFactory.getStandardStructObjectInspector(
                 fieldNames, fieldObjectInspectors);
         break;
       }
     case UNION:
       {
         UnionObjectInspector uoi = (UnionObjectInspector) oi;
         List<ObjectInspector> ois = new ArrayList<ObjectInspector>();
         for (ObjectInspector eoi : uoi.getObjectInspectors()) {
           ois.add(getStandardObjectInspector(eoi, objectInspectorOption));
         }
         result = ObjectInspectorFactory.getStandardUnionObjectInspector(ois);
         break;
       }
     default:
       {
         throw new RuntimeException("Unknown ObjectInspector category!");
       }
   }
   return result;
 }