예제 #1
0
            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);
            }
예제 #2
0
            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 + "'");
            }