/** * Return the extended TypeInfo from a Java type. By extended TypeInfo, we * allow unknownType for java.lang.Object. * * @param t * The Java type. * @param m * The method, only used for generating error messages. */ private static TypeInfo getExtendedTypeInfoFromJavaType(Type t, MethodInfo m) { if (t == typeof(object)) { return(TypeInfoFactory.unknownTypeInfo); } if (t.IsGenericType) { Type bt = t.GetGenericTypeDefinition(); Type[] pt = t.GenericTypeArguments; // List? if (bt == typeof(List <>)) { return(TypeInfoFactory.getListTypeInfo(getExtendedTypeInfoFromJavaType( pt[0], m))); } // Map? if (bt == typeof(Dictionary <,>)) { return(TypeInfoFactory.getMapTypeInfo( getExtendedTypeInfoFromJavaType(pt[0], m), getExtendedTypeInfoFromJavaType(pt[1], m))); } } // Java Primitive Type? if (PrimitiveObjectInspectorUtils.isPrimitiveJavaType(t)) { return(TypeInfoUtils .getTypeInfoFromObjectInspector(PrimitiveObjectInspectorFactory .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils .getTypeEntryFromPrimitiveJavaType(t).primitiveCategory))); } // Java Primitive Class? if (PrimitiveObjectInspectorUtils.isPrimitiveJavaClass(t)) { return(TypeInfoUtils .getTypeInfoFromObjectInspector(PrimitiveObjectInspectorFactory .getPrimitiveJavaObjectInspector(PrimitiveObjectInspectorUtils .getTypeEntryFromPrimitiveJavaClass(t).primitiveCategory))); } // Primitive Writable class? if (PrimitiveObjectInspectorUtils.isPrimitiveWritableClass(t)) { return(TypeInfoUtils .getTypeInfoFromObjectInspector(PrimitiveObjectInspectorFactory .getPrimitiveWritableObjectInspector(PrimitiveObjectInspectorUtils .getTypeEntryFromPrimitiveWritableClass(t).primitiveCategory))); } // Must be a struct FieldInfo[] fields = ObjectInspectorUtils.getDeclaredNonStaticFields(t); List <string> fieldNames = new List <string>(fields.Length); List <TypeInfo> fieldTypeInfos = new List <TypeInfo>(fields.Length); foreach (FieldInfo field in fields) { fieldNames.Add(field.Name); fieldTypeInfos.Add(getExtendedTypeInfoFromJavaType( field.FieldType, m)); } return(TypeInfoFactory.getStructTypeInfo(fieldNames, fieldTypeInfos)); }
/** * Get the TypeInfo object from the ObjectInspector object by recursively * going into the ObjectInspector structure. */ public static TypeInfo getTypeInfoFromObjectInspector(ObjectInspector oi) { // OPTIMIZATION for later. // if (oi instanceof TypeInfoBasedObjectInspector) { // TypeInfoBasedObjectInspector typeInfoBasedObjectInspector = // (ObjectInspector)oi; // return typeInfoBasedObjectInspector.getTypeInfo(); // } if (oi == null) { return(null); } // Recursively going into ObjectInspector structure TypeInfo result = null; switch (oi.getCategory()) { case ObjectInspectorCategory.PRIMITIVE: { PrimitiveObjectInspector poi = (PrimitiveObjectInspector)oi; result = poi.getTypeInfo(); break; } case ObjectInspectorCategory.LIST: { ListObjectInspector loi = (ListObjectInspector)oi; result = TypeInfoFactory .getListTypeInfo(getTypeInfoFromObjectInspector(loi .getListElementObjectInspector())); break; } case ObjectInspectorCategory.MAP: { MapObjectInspector moi = (MapObjectInspector)oi; result = TypeInfoFactory.getMapTypeInfo( getTypeInfoFromObjectInspector(moi.getMapKeyObjectInspector()), getTypeInfoFromObjectInspector(moi.getMapValueObjectInspector())); break; } case ObjectInspectorCategory.STRUCT: { StructObjectInspector soi = (StructObjectInspector)oi; IList <StructField> fields = soi.getAllStructFieldRefs(); List <String> fieldNames = new List <String>(fields.Count); List <TypeInfo> fieldTypeInfos = new List <TypeInfo>(fields.Count); foreach (StructField f in fields) { fieldNames.Add(f.getFieldName()); fieldTypeInfos.Add(getTypeInfoFromObjectInspector(f .getFieldObjectInspector())); } result = TypeInfoFactory.getStructTypeInfo(fieldNames, fieldTypeInfos); break; } case ObjectInspectorCategory.UNION: { UnionObjectInspector uoi = (UnionObjectInspector)oi; List <TypeInfo> objectTypeInfos = new List <TypeInfo>(); foreach (ObjectInspector eoi in uoi.getObjectInspectors()) { objectTypeInfos.Add(getTypeInfoFromObjectInspector(eoi)); } result = TypeInfoFactory.getUnionTypeInfo(objectTypeInfos); break; } default: { throw new InvalidOperationException("Unknown ObjectInspector category!"); } } return(result); }
private TypeInfo parseType() { Token t = expect("type"); // Is this a primitive type? PrimitiveTypeEntry typeEntry = PrimitiveObjectInspectorUtils.getTypeEntryFromTypeName(t.text); if (typeEntry != null && typeEntry.primitiveCategory != PrimitiveCategory.UNKNOWN) { String[] @params = parseParams(); switch (typeEntry.primitiveCategory) { case PrimitiveCategory.CHAR: case PrimitiveCategory.VARCHAR: if (@params == null || @params.Length == 0) { throw new ArgumentException(typeEntry.typeName + " type is specified without length: " + typeInfoString); } int length = 1; if (@params.Length == 1) { length = Int32.Parse(@params[0]); if (typeEntry.primitiveCategory == PrimitiveCategory.VARCHAR) { BaseCharUtils.validateVarcharParameter(length); return(TypeInfoFactory.getVarcharTypeInfo(length)); } else { BaseCharUtils.validateCharParameter(length); return(TypeInfoFactory.getCharTypeInfo(length)); } } else if (@params.Length > 1) { throw new ArgumentException( "Type " + typeEntry.typeName + " only takes one parameter, but " + @params.Length + " is seen"); } break; case PrimitiveCategory.DECIMAL: int precision = HiveDecimal.USER_DEFAULT_PRECISION; int scale = HiveDecimal.USER_DEFAULT_SCALE; if (@params == null || @params.Length == 0) { // It's possible that old metadata still refers to "decimal" as a column type w/o // precision/scale. In this case, the default (10,0) is assumed. Thus, do nothing here. } else if (@params.Length == 2) { // New metadata always have two parameters. precision = Int32.Parse(@params[0]); scale = Int32.Parse(@params[1]); HiveDecimalUtils.validateParameter(precision, scale); } else if (@params.Length > 2) { throw new ArgumentException("Type decimal only takes two parameter, but " + @params.Length + " is seen"); } return(TypeInfoFactory.getDecimalTypeInfo(precision, scale)); default: return(TypeInfoFactory.getPrimitiveTypeInfo(typeEntry.typeName)); } } // Is this a list type? if (serdeConstants.LIST_TYPE_NAME.Equals(t.text)) { expect("<"); TypeInfo listElementType = parseType(); expect(">"); return(TypeInfoFactory.getListTypeInfo(listElementType)); } // Is this a map type? if (serdeConstants.MAP_TYPE_NAME.Equals(t.text)) { expect("<"); TypeInfo mapKeyType = parseType(); expect(","); TypeInfo mapValueType = parseType(); expect(">"); return(TypeInfoFactory.getMapTypeInfo(mapKeyType, mapValueType)); } // Is this a struct type? if (serdeConstants.STRUCT_TYPE_NAME.Equals(t.text)) { List <string> fieldNames = new List <string>(); List <TypeInfo> fieldTypeInfos = new List <TypeInfo>(); bool first = true; do { if (first) { expect("<"); first = false; } else { Token separator = expect(">", ","); if (separator.text.Equals(">")) { // end of struct break; } } Token name = expect("name", ">"); if (name.text.Equals(">")) { break; } fieldNames.Add(name.text); expect(":"); fieldTypeInfos.Add(parseType()); } while (true); return(TypeInfoFactory.getStructTypeInfo(fieldNames, fieldTypeInfos)); } // Is this a union type? if (serdeConstants.UNION_TYPE_NAME.Equals(t.text)) { List <TypeInfo> objectTypeInfos = new List <TypeInfo>(); bool first = true; do { if (first) { expect("<"); first = false; } else { Token separator = expect(">", ","); if (separator.text.Equals(">")) { // end of union break; } } objectTypeInfos.Add(parseType()); } while (true); return(TypeInfoFactory.getUnionTypeInfo(objectTypeInfos)); } throw new ArgumentException("Internal error parsing position " + t.position + " of '" + typeInfoString + "'"); }