private Token expect(string item, string alternative) { if (iToken >= typeInfoTokens.Count) { throw new ArgumentException("Error: " + item + " expected at the end of '" + typeInfoString + "'"); } Token t = typeInfoTokens[iToken]; if (item.Equals("type")) { if (!serdeConstants.LIST_TYPE_NAME.Equals(t.text) && !serdeConstants.MAP_TYPE_NAME.Equals(t.text) && !serdeConstants.STRUCT_TYPE_NAME.Equals(t.text) && !serdeConstants.UNION_TYPE_NAME.Equals(t.text) && null == PrimitiveObjectInspectorUtils .getTypeEntryFromTypeName(t.text) && !t.text.Equals(alternative)) { throw new ArgumentException("Error: " + item + " expected at the position " + t.position + " of '" + typeInfoString + "' but '" + t.text + "' is found."); } } else if (item.Equals("name")) { if (!t.isType && !t.text.Equals(alternative)) { throw new ArgumentException("Error: " + item + " expected at the position " + t.position + " of '" + typeInfoString + "' but '" + t.text + "' is found."); } } else { if (!item.Equals(t.text) && !t.text.Equals(alternative)) { throw new ArgumentException("Error: " + item + " expected at the position " + t.position + " of '" + typeInfoString + "' but '" + t.text + "' is found."); } } iToken++; return(t); }
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 + "'"); }