private HCatFieldSchema getHCatFSFromPigFS(FieldSchema fSchema, HCatFieldSchema hcatFieldSchema,
                                             Schema pigSchema, HCatSchema tableSchema)
          throws FrontendException, HCatException {
    if(hcatFieldSchema == null) {
      if(LOG.isDebugEnabled()) {
        LOG.debug("hcatFieldSchema is null for fSchema '" + fSchema.alias + "'");
        //throw new IllegalArgumentException("hcatFiledSchema is null; fSchema=" + fSchema + " " +
        //      "(pigSchema, tableSchema)=(" + pigSchema + "," + tableSchema + ")");
      }
    }
    byte type = fSchema.type;
    switch (type) {

    case DataType.CHARARRAY:
    case DataType.BIGCHARARRAY:
      if(hcatFieldSchema != null && hcatFieldSchema.getTypeInfo() != null) {
        return new HCatFieldSchema(fSchema.alias, hcatFieldSchema.getTypeInfo(), null);
      }
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.stringTypeInfo, null);
    case DataType.INTEGER:
      if (hcatFieldSchema != null) {
        if (!SUPPORTED_INTEGER_CONVERSIONS.contains(hcatFieldSchema.getType())) {
          throw new FrontendException("Unsupported type: " + type + "  in Pig's schema",
            PigHCatUtil.PIG_EXCEPTION_CODE);
        }
        return new HCatFieldSchema(fSchema.alias, hcatFieldSchema.getTypeInfo(), null);
      }
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.intTypeInfo, null);
    case DataType.LONG:
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.longTypeInfo, null);
    case DataType.FLOAT:
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.floatTypeInfo, null);
    case DataType.DOUBLE:
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.doubleTypeInfo, null);
    case DataType.BYTEARRAY:
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.binaryTypeInfo, null);
    case DataType.BOOLEAN:
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.booleanTypeInfo, null);
    case DataType.DATETIME:
      //Pig DATETIME can map to DATE or TIMESTAMP (see HCatBaseStorer#validateSchema()) which
      //is controlled by Hive target table information
      if(hcatFieldSchema != null && hcatFieldSchema.getTypeInfo() != null) {
        return new HCatFieldSchema(fSchema.alias, hcatFieldSchema.getTypeInfo(), null);
      }
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.timestampTypeInfo, null);
    case DataType.BIGDECIMAL:
      if(hcatFieldSchema != null && hcatFieldSchema.getTypeInfo() != null) {
        return new HCatFieldSchema(fSchema.alias, hcatFieldSchema.getTypeInfo(), null);
      }
      return new HCatFieldSchema(fSchema.alias, TypeInfoFactory.decimalTypeInfo, null);
    case DataType.BAG:
      Schema bagSchema = fSchema.schema;
      FieldSchema field;
      // Find out if we need to throw away the tuple or not.
      if (removeTupleFromBag(hcatFieldSchema, fSchema)) {
        field = bagSchema.getField(0).schema.getField(0);
      } else {
        field = bagSchema.getField(0);
      }
      List<HCatFieldSchema> arrFields = Collections.singletonList(getHCatFSFromPigFS(field,
          hcatFieldSchema == null ? null : hcatFieldSchema.getArrayElementSchema().get(0), pigSchema, tableSchema));
      return new HCatFieldSchema(fSchema.alias, Type.ARRAY, new HCatSchema(arrFields), "");
    case DataType.TUPLE:
      List<HCatFieldSchema> hcatFSs = new ArrayList<HCatFieldSchema>();
      HCatSchema structSubSchema = hcatFieldSchema == null ? null : hcatFieldSchema.getStructSubSchema();
      List<FieldSchema> fields = fSchema.schema.getFields();
      for (int i = 0; i < fields.size(); i++) {
        FieldSchema fieldSchema = fields.get(i);
        hcatFSs.add(getHCatFSFromPigFS(fieldSchema, structSubSchema == null ? null : structSubSchema.get(i), pigSchema, tableSchema));
      }
      return new HCatFieldSchema(fSchema.alias, Type.STRUCT, new HCatSchema(hcatFSs), "");
    case DataType.MAP: {
      // Pig's schema contain no type information about map's keys and
      // values. So, if its a new column assume <string,string> if its existing
      // return whatever is contained in the existing column.

      if (hcatFieldSchema != null) {
        return HCatFieldSchema.createMapTypeFieldSchema(fSchema.alias, hcatFieldSchema.getMapKeyTypeInfo(), 
          hcatFieldSchema.getMapValueSchema(), "");
      }

      // Column not found in target table. Its a new column. Its schema is map<string,string>
      List<HCatFieldSchema> valFSList =
          Collections.singletonList(new HCatFieldSchema(fSchema.alias, TypeInfoFactory.stringTypeInfo, ""));
      return HCatFieldSchema.createMapTypeFieldSchema(fSchema.alias,
        TypeInfoFactory.stringTypeInfo, new HCatSchema(valFSList), "");
    }
    case DataType.BIGINTEGER:
      //fall through; doesn't map to Hive/Hcat type; here for completeness
    default:
      throw new FrontendException("Unsupported type: " + type + "  in Pig's schema", PigHCatUtil.PIG_EXCEPTION_CODE);
    }
  }
Here we are processing HCat table schema as derived from metastore, 
thus it should have information about all fields/sub-fields, but not for partition columns
hcatalog/hcatalog-pig-adapter/src/main/java/org/apache/hive/hcatalog/pig/HCatBaseStorer.java