/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.hadoop.hive.serde2.thrift; import java.sql.DatabaseMetaData; import java.sql.Types; import org.apache.hadoop.hive.common.type.HiveDecimal; import org.apache.hadoop.hive.serde.serdeConstants; import org.apache.hadoop.hive.serde2.typeinfo.PrimitiveTypeInfo; import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo; import org.apache.hive.service.rpc.thrift.TTypeId; /** * Type. * */ public enum Type { NULL_TYPE("VOID", java.sql.Types.NULL, TTypeId.NULL_TYPE), BOOLEAN_TYPE("BOOLEAN", java.sql.Types.BOOLEAN, TTypeId.BOOLEAN_TYPE), TINYINT_TYPE("TINYINT", java.sql.Types.TINYINT, TTypeId.TINYINT_TYPE), SMALLINT_TYPE("SMALLINT", java.sql.Types.SMALLINT, TTypeId.SMALLINT_TYPE), INT_TYPE("INT", java.sql.Types.INTEGER, TTypeId.INT_TYPE), BIGINT_TYPE("BIGINT", java.sql.Types.BIGINT, TTypeId.BIGINT_TYPE), FLOAT_TYPE("FLOAT", java.sql.Types.FLOAT, TTypeId.FLOAT_TYPE), DOUBLE_TYPE("DOUBLE", java.sql.Types.DOUBLE, TTypeId.DOUBLE_TYPE), STRING_TYPE("STRING", java.sql.Types.VARCHAR, TTypeId.STRING_TYPE), CHAR_TYPE("CHAR", java.sql.Types.CHAR, TTypeId.CHAR_TYPE, true, false, false), VARCHAR_TYPE("VARCHAR", java.sql.Types.VARCHAR, TTypeId.VARCHAR_TYPE, true, false, false), DATE_TYPE("DATE", java.sql.Types.DATE, TTypeId.DATE_TYPE), TIMESTAMP_TYPE("TIMESTAMP", java.sql.Types.TIMESTAMP, TTypeId.TIMESTAMP_TYPE), TIMESTAMPTZ_TYPE(serdeConstants.TIMESTAMPTZ_TYPE_NAME.toUpperCase(), Types.TIMESTAMP_WITH_TIMEZONE, TTypeId.TIMESTAMPTZ_TYPE), INTERVAL_YEAR_MONTH_TYPE("INTERVAL_YEAR_MONTH", java.sql.Types.OTHER, TTypeId.INTERVAL_YEAR_MONTH_TYPE), INTERVAL_DAY_TIME_TYPE("INTERVAL_DAY_TIME", java.sql.Types.OTHER, TTypeId.INTERVAL_DAY_TIME_TYPE), BINARY_TYPE("BINARY", java.sql.Types.BINARY, TTypeId.BINARY_TYPE), DECIMAL_TYPE("DECIMAL", java.sql.Types.DECIMAL, TTypeId.DECIMAL_TYPE, true, false, false), ARRAY_TYPE("ARRAY", java.sql.Types.ARRAY, TTypeId.ARRAY_TYPE, true, true), MAP_TYPE("MAP", java.sql.Types.JAVA_OBJECT, TTypeId.MAP_TYPE, true, true), STRUCT_TYPE("STRUCT", java.sql.Types.STRUCT, TTypeId.STRUCT_TYPE, true, false), UNION_TYPE("UNIONTYPE", java.sql.Types.OTHER, TTypeId.UNION_TYPE, true, false), USER_DEFINED_TYPE("USER_DEFINED", java.sql.Types.OTHER, TTypeId.USER_DEFINED_TYPE, true, false); private final String name; private final TTypeId tType; private final int javaSQLType; private final boolean isQualified; private final boolean isComplex; private final boolean isCollection; Type(String name, int javaSQLType, TTypeId tType, boolean isQualified, boolean isComplex, boolean isCollection) { this.name = name; this.javaSQLType = javaSQLType; this.tType = tType; this.isQualified = isQualified; this.isComplex = isComplex; this.isCollection = isCollection; } Type(String name, int javaSQLType, TTypeId tType, boolean isComplex, boolean isCollection) { this(name, javaSQLType, tType, false, isComplex, isCollection); } Type(String name, int javaSqlType, TTypeId tType) { this(name, javaSqlType, tType, false, false, false); } public boolean isPrimitiveType() { return !isComplex; } public boolean isQualifiedType() { return isQualified; } public boolean isComplexType() { return isComplex; } public boolean isCollectionType() { return isCollection; } public static Type getType(TTypeId tType) { for (Type type : values()) { if (tType.equals(type.tType)) { return type; } } throw new IllegalArgumentException("Unrecognized Thrift TTypeId value: " + tType); } public static Type getType(String name) { if (name == null) { throw new IllegalArgumentException("Invalid type name: null"); } for (Type type : values()) { if (name.equalsIgnoreCase(type.name)) { return type; } else if (type.isQualifiedType() || type.isComplexType()) { if (name.toUpperCase().startsWith(type.name)) { return type; } } } throw new IllegalArgumentException("Unrecognized type name: " + name); } /** * Convert TypeInfo to appropriate Type * @param typeInfo * @return */ public static Type getType(TypeInfo typeInfo) { switch (typeInfo.getCategory()) { case PRIMITIVE: { PrimitiveTypeInfo pTypeInfo = (PrimitiveTypeInfo) typeInfo; switch (pTypeInfo.getPrimitiveCategory()) { case VOID: { return Type.NULL_TYPE; } case BOOLEAN: { return Type.BOOLEAN_TYPE; } // Double check if this is the right mapping case BYTE: { return Type.BINARY_TYPE; } // Double check if this is the right mapping case SHORT: { return Type.SMALLINT_TYPE; } case INT: { return Type.INT_TYPE; } // Double check if this is the right mapping case LONG: { return Type.BIGINT_TYPE; } case FLOAT: { return Type.FLOAT_TYPE; } case DOUBLE: { return Type.DOUBLE_TYPE; } case STRING: { return Type.STRING_TYPE; } case CHAR: { return Type.CHAR_TYPE; } case VARCHAR: { return Type.VARCHAR_TYPE; } case BINARY: { return Type.BINARY_TYPE; } case DATE: { return Type.DATE_TYPE; } case TIMESTAMP: { return Type.TIMESTAMP_TYPE; } case TIMESTAMPTZ: { return Type.TIMESTAMPTZ_TYPE; } case INTERVAL_YEAR_MONTH: { return Type.INTERVAL_YEAR_MONTH_TYPE; } case INTERVAL_DAY_TIME: { return Type.INTERVAL_DAY_TIME_TYPE; } case DECIMAL: { return Type.DECIMAL_TYPE; } default: { throw new RuntimeException("Unrecognized type: " + pTypeInfo.getPrimitiveCategory()); } } } // Double check if this is the right mapping case LIST: { return Type.STRING_TYPE; } case MAP: { return Type.MAP_TYPE; } case STRUCT: { return Type.STRUCT_TYPE; } case UNION: { return Type.UNION_TYPE; } default: { throw new RuntimeException("Unrecognized type: " + typeInfo.getCategory()); } } } /** * Radix for this type (typically either 2 or 10) * Null is returned for data types where this is not applicable. */ public Integer getNumPrecRadix() { if (this.isNumericType()) { return 10; } return null; } /** * Maximum precision for numeric types. * Returns null for non-numeric types. * @return */ public Integer getMaxPrecision() { switch (this) { case TINYINT_TYPE: return 3; case SMALLINT_TYPE: return 5; case INT_TYPE: return 10; case BIGINT_TYPE: return 19; case FLOAT_TYPE: return 7; case DOUBLE_TYPE: return 15; case DECIMAL_TYPE: return HiveDecimal.MAX_PRECISION; default: return null; } } public boolean isNumericType() { switch (this) { case TINYINT_TYPE: case SMALLINT_TYPE: case INT_TYPE: case BIGINT_TYPE: case FLOAT_TYPE: case DOUBLE_TYPE: case DECIMAL_TYPE: return true; default: return false; } } /** * Prefix used to quote a literal of this type (may be null) */ public String getLiteralPrefix() { return null; } /** * Suffix used to quote a literal of this type (may be null) * @return */ public String getLiteralSuffix() { return null; } /** * Can you use NULL for this type? * @return * DatabaseMetaData.typeNoNulls - does not allow NULL values * DatabaseMetaData.typeNullable - allows NULL values * DatabaseMetaData.typeNullableUnknown - nullability unknown */ public Short getNullable() { // All Hive types are nullable return DatabaseMetaData.typeNullable; } /** * Is the type case sensitive? * @return */ public Boolean isCaseSensitive() { switch (this) { case STRING_TYPE: return true; default: return false; } } /** * Parameters used in creating the type (may be null) * @return */ public String getCreateParams() { return null; } /** * Can you use WHERE based on this type? * @return * DatabaseMetaData.typePredNone - No support * DatabaseMetaData.typePredChar - Only support with WHERE .. LIKE * DatabaseMetaData.typePredBasic - Supported except for WHERE .. LIKE * DatabaseMetaData.typeSearchable - Supported for all WHERE .. */ public Short getSearchable() { if (isPrimitiveType()) { return DatabaseMetaData.typeSearchable; } return DatabaseMetaData.typePredNone; } /** * Is this type unsigned? * @return */ public Boolean isUnsignedAttribute() { if (isNumericType()) { return false; } return true; } /** * Can this type represent money? * @return */ public Boolean isFixedPrecScale() { return false; } /** * Can this type be used for an auto-increment value? * @return */ public Boolean isAutoIncrement() { return false; } /** * Localized version of type name (may be null). * @return */ public String getLocalizedName() { return null; } /** * Minimum scale supported for this type * @return */ public Short getMinimumScale() { return 0; } /** * Maximum scale supported for this type * @return */ public Short getMaximumScale() { return 0; } public TTypeId toTType() { return tType; } public int toJavaSQLType() { return javaSQLType; } public String getName() { return name; } }