private List<Object> unpack(WriteBuffers.ByteSegmentRef ref) throws HiveException {
   if (ref.getLength() == 0) {
     return EMPTY_LIST; // shortcut, 0 length means no fields
   }
   uselessIndirection.setData(ref.getBytes());
   valueStruct.init(uselessIndirection, (int) ref.getOffset(), ref.getLength());
   List<Object> result;
   if (!needsComplexObjectFixup) {
     // Good performance for common case where small table has no complex objects.
     result = valueStruct.getFieldsAsList();
   } else {
     // Convert the complex LazyBinary objects to standard (Java) objects so downstream
     // operators like FileSinkOperator can serialize complex objects in the form they expect
     // (i.e. Java objects).
     result = getComplexFieldsAsList(valueStruct, complexObjectArrayBuffer, internalValueOi);
   }
   return result;
 }
  /*
   * For primitive types, use LazyBinary's object.
   * For complex types, make a standard (Java) object from LazyBinary's object.
   */
  public static List<Object> getComplexFieldsAsList(
      LazyBinaryStruct lazyBinaryStruct,
      ArrayList<Object> objectArrayBuffer,
      LazyBinaryStructObjectInspector lazyBinaryStructObjectInspector) {

    List<? extends StructField> fields = lazyBinaryStructObjectInspector.getAllStructFieldRefs();
    for (int i = 0; i < fields.size(); i++) {
      StructField field = fields.get(i);
      ObjectInspector objectInspector = field.getFieldObjectInspector();
      Category category = objectInspector.getCategory();
      Object object = lazyBinaryStruct.getField(i);
      if (category == Category.PRIMITIVE) {
        objectArrayBuffer.set(i, object);
      } else {
        objectArrayBuffer.set(
            i,
            ObjectInspectorUtils.copyToStandardObject(
                object, objectInspector, ObjectInspectorCopyOption.WRITABLE));
      }
    }
    return objectArrayBuffer;
  }