public static Type fromHiveType(String hiveType) {
        String typeUpperCase = getTypeKeyword(hiveType).toUpperCase();
        PrimitiveType primitiveType;
        switch (typeUpperCase) {
            case "TINYINT":
                primitiveType = PrimitiveType.TINYINT;
                break;
            case "SMALLINT":
                primitiveType = PrimitiveType.SMALLINT;
                break;
            case "INT":
            case "INTEGER":
                primitiveType = PrimitiveType.INT;
                break;
            case "BIGINT":
                primitiveType = PrimitiveType.BIGINT;
                break;
            case "FLOAT":
                primitiveType = PrimitiveType.FLOAT;
                break;
            case "DOUBLE":
            case "DOUBLE PRECISION":
                primitiveType = PrimitiveType.DOUBLE;
                break;
            case "DECIMAL":
            case "NUMERIC":
                primitiveType = PrimitiveType.DECIMAL32;
                break;
            case "TIMESTAMP":
                primitiveType = PrimitiveType.DATETIME;
                break;
            case "DATE":
                primitiveType = PrimitiveType.DATE;
                break;
            case "STRING":
                return ScalarType.createDefaultCatalogString();
            case "VARCHAR":
                return ScalarType.createVarcharType(getVarcharLength(hiveType));
            case "CHAR":
                return ScalarType.createCharType(getCharLength(hiveType));
            case "BINARY":
                return Type.VARBINARY;
            case "BOOLEAN":
                primitiveType = PrimitiveType.BOOLEAN;
                break;
            case "ARRAY":
                Type type = fromHiveTypeToArrayType(hiveType);
                if (type.isArrayType()) {
                    return type;
                } else {
                    return Type.UNKNOWN_TYPE;
                }
            case "MAP":
                Type mapType = fromHiveTypeToMapType(hiveType);
                if (mapType.isMapType()) {
                    return mapType;
                } else {
                    return Type.UNKNOWN_TYPE;
                }
            case  "STRUCT":
                Type structType = fromHiveTypeToStructType(hiveType);
                if (structType.isStructType()) {
                    return structType;
                } else {
                    return Type.UNKNOWN_TYPE;
                }
            default:
                primitiveType = PrimitiveType.UNKNOWN_TYPE;
                break;
        }

        if (primitiveType != PrimitiveType.DECIMAL32) {
            return ScalarType.createType(primitiveType);
        } else {
            int[] parts = getPrecisionAndScale(hiveType);
            return ScalarType.createUnifiedDecimalType(parts[0], parts[1]);
        }
    }
@Test
    public void testStructString() {
        {
            String typeStr = "struct<a:struct<aa:date>,b:int>";
            StructField aa = new StructField("aa", ScalarType.createType(PrimitiveType.DATE));

            StructType innerStruct = new StructType(Lists.newArrayList(aa));
            StructField a = new StructField("a", innerStruct);
            StructField b = new StructField("b", ScalarType.createType(PrimitiveType.INT));
            StructType outerStruct = new StructType(Lists.newArrayList(a, b));

            Type resType = ColumnTypeConverter.fromHiveType(typeStr);
            Assert.assertEquals(outerStruct, resType);
        }

        {
            String typeStr = "array<struct<a:int,b:map<int,int>>>";
            MapType map =
                    new MapType(ScalarType.createType(PrimitiveType.INT), ScalarType.createType(PrimitiveType.INT));
            StructField a = new StructField("a", ScalarType.createType(PrimitiveType.INT));
            StructField b = new StructField("b", map);
            StructType structType = new StructType(Lists.newArrayList(a, b));
            ArrayType arrayType = new ArrayType(structType);

            Type resType = ColumnTypeConverter.fromHiveType(typeStr);
            Assert.assertEquals(arrayType, resType);
        }

        {
            String typeStr = "struct<struct_test:int,c1:struct<c1:int,cc1:string>>";
            StructType c1 = new StructType(Lists.newArrayList(
                    new StructField("c1", ScalarType.createType(PrimitiveType.INT)),
                    new StructField("cc1", ScalarType.createDefaultCatalogString())
            ));
            StructType root = new StructType(Lists.newArrayList(
                    new StructField("struct_test", ScalarType.createType(PrimitiveType.INT)),
                    new StructField("c1", c1)
            ));

            Type resType = ColumnTypeConverter.fromHiveType(typeStr);
            Assert.assertEquals(root, resType);
        }
    }