/*
* Copyright (c) 2013, OpenCloudDB/MyCAT and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software;Designed and Developed mainly by many Chinese
* opensource volunteers. you can redistribute it and/or modify it under the
* terms of the GNU General Public License version 2 only, as published by the
* Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Any questions about this component can be directed to it's project Web address
* https://code.google.com/p/opencloudb/.
*
*/
package com.akiban.sql.types;
import com.akiban.sql.StandardException;
import java.sql.Types;
/**
* TypeId describes the static information about a SQL type
* independent of any specific attributes of the type such
* as length. So the TypeId for CHARACTER describes the
* fundamental information about CHARACTER. A specific
* type (e.g. CHARACTER(10)) is described by a TypeDescriptor for
* a catlog type and a DataTypeDescriptor for a runtime type.
* (note a DataTypeDescriptor adds runtime attributes to the
* TypeDescriptor it has).
* <P>
* A TypeId is immutable.
<P>
* The equals(Object) method can be used to determine if two typeIds are for the same type,
* which defines type id equality.
@see DataTypeDescriptor
*/
public class TypeId
{
/**
* Various fixed numbers related to datatypes.
*/
public static final int LONGINT_PRECISION = 19;
public static final int LONGINT_SCALE = 0;
public static final int LONGINT_MAXWIDTH = 20;
public static final int INT_PRECISION = 10;
public static final int INT_SCALE = 0;
public static final int INT_MAXWIDTH = 11;
public static final int SMALLINT_PRECISION = 5;
public static final int SMALLINT_SCALE = 0;
public static final int SMALLINT_MAXWIDTH = 6;
public static final int TINYINT_PRECISION = 3;
public static final int TINYINT_SCALE = 0;
public static final int TINYINT_MAXWIDTH = 4;
// precision in number of bits
public static final int DOUBLE_PRECISION = 52;
// the ResultSetMetaData needs to have the precision for numeric data
// in decimal digits, rather than number of bits, so need a separate constant.
public static final int DOUBLE_PRECISION_IN_DIGITS = 15;
public static final int DOUBLE_SCALE = 0;
public static final int DOUBLE_MAXWIDTH = 17;
// precision in number of bits
public static final int REAL_PRECISION = 23;
// the ResultSetMetaData needs to have the precision for numeric data
// in decimal digits, rather than number of bits, so need a separate constant.
public static final int REAL_PRECISION_IN_DIGITS = 7;
public static final int REAL_SCALE = 0;
public static final int REAL_MAXWIDTH = 9;
public static final int DECIMAL_PRECISION = 31;
public static final int DECIMAL_SCALE = 31;
public static final int DECIMAL_MAXWIDTH = 31;
// TODO: Is there a better place for these?
public static final int DEFAULT_DECIMAL_PRECISION = 5;
public static final int DEFAULT_DECIMAL_SCALE = 0;
public static final int BOOLEAN_MAXWIDTH = 5; // false
public static final int CHAR_MAXWIDTH = 254;
public static final int VARCHAR_MAXWIDTH = 32672;
public static final int LONGVARCHAR_MAXWIDTH = 32700;
public static final int BIT_MAXWIDTH = 254;
public static final int VARBIT_MAXWIDTH = 32672;
public static final int LONGVARBIT_MAXWIDTH = 32700;
// not supposed to be limited! 4096G should be ok(?), if Derby can handle...
public static final int BLOB_MAXWIDTH = Integer.MAX_VALUE; // to change long
public static final int CLOB_MAXWIDTH = Integer.MAX_VALUE; // to change long
public static final int XML_MAXWIDTH = Integer.MAX_VALUE;
// Max width for datetime values is the length of the
// string returned from a call to "toString()" on the
// java.sql.Date, java.sql.Time, and java.sql.Timestamp
// classes (the result of toString() on those classes
// is defined by the JDBC API). This value is also
// used as the "precision" for those types.
public static final int DATE_MAXWIDTH = 10; // yyyy-mm-dd
public static final int TIME_MAXWIDTH = 8; // hh:mm:ss
// The format of java.sql.Timestamp.toString()
// is yyyy-mm-dd hh:mm:ss.fffffffff
public static final int TIMESTAMP_MAXWIDTH = 29; // yyyy-mm-dd hh:mm:ss.fffffffff
// Scale DOES exist for time values. For a TIMESTAMP value,
// it's 9 ('fffffffff'); for a TIME value, it's 0 (because there
// are no fractional seconds). Note that date values do
// not have a scale.
public static final int TIME_SCALE = 0;
public static final int TIMESTAMP_SCALE = 9;
public static final int INTERVAL_YEAR_MONTH_PRECISION = 8;
public static final int INTERVAL_YEAR_MONTH_SCALE = 0;
public static final int INTERVAL_YEAR_MONTH_MAXWIDTH = 11; // yyyyyyyy-mm
public static final int INTERVAL_DAY_SECOND_PRECISION = 8;
public static final int INTERVAL_DAY_SECOND_SCALE = 6;
public static final int INTERVAL_DAY_SECOND_MAXWIDTH = 24; // dddddddd hh:mm:ss.uuuuuu
/* These define all the type names for SQL92 and JDBC
* NOTE: boolean is SQL3
*/
//public static final String BIT_NAME = "BIT";
//public static final String VARBIT_NAME = "BIT VARYING";
//public static final String LONGVARBIT_NAME = "LONG BIT VARYING";
public static final String BIT_NAME = "CHAR () FOR BIT DATA";
public static final String VARBIT_NAME = "VARCHAR () FOR BIT DATA";
public static final String LONGVARBIT_NAME = "LONG VARCHAR FOR BIT DATA";
public static final String TINYINT_NAME = "TINYINT";
public static final String SMALLINT_NAME = "SMALLINT";
public static final String MEDIUMINT_NAME = "MEDIUMINT";
public static final String INTEGER_NAME = "INTEGER";
public static final String INT_NAME = "INT";
public static final String LONGINT_NAME = "BIGINT";
public static final String FLOAT_NAME = "FLOAT";
public static final String REAL_NAME = "REAL";
public static final String DOUBLE_NAME = "DOUBLE";
public static final String NUMERIC_NAME = "NUMERIC";
public static final String DECIMAL_NAME = "DECIMAL";
public static final String CHAR_NAME = "CHAR";
public static final String VARCHAR_NAME = "VARCHAR";
public static final String LONGVARCHAR_NAME = "LONG VARCHAR";
public static final String DATE_NAME = "DATE";
public static final String TIME_NAME = "TIME";
public static final String TIMESTAMP_NAME = "TIMESTAMP";
public static final String BINARY_NAME = "BINARY";
public static final String VARBINARY_NAME = "VARBINARY";
public static final String LONGVARBINARY_NAME = "LONGVARBINARY";
public static final String BOOLEAN_NAME = "BOOLEAN";
public static final String REF_NAME = "REF";
public static final String NATIONAL_CHAR_NAME = "NATIONAL CHAR";
public static final String NATIONAL_VARCHAR_NAME = "NATIONAL CHAR VARYING";
public static final String NATIONAL_LONGVARCHAR_NAME = "LONG NVARCHAR";
public static final String BLOB_NAME = "BLOB";
public static final String CLOB_NAME = "CLOB";
public static final String NCLOB_NAME = "NCLOB";
public static final String TEXT_NAME = "TEXT";
public static final String TINYBLOB_NAME = "TINYBLOB";
public static final String TINYTEXT_NAME = "TINYTEXT";
public static final String MEDIUMBLOB_NAME = "MEDIUMBLOB";
public static final String MEDIUMTEXT_NAME = "MEDIUMTEXT";
public static final String LONGBLOB_NAME = "LONGBLOB";
public static final String LONGTEXT_NAME = "LONGTEXT";
public static final String INTERVAL_YEAR_NAME = "INTERVAL YEAR";
public static final String INTERVAL_MONTH_NAME = "INTERVAL MONTH";
public static final String INTERVAL_YEAR_MONTH_NAME = "INTERVAL YEAR TO MONTH";
public static final String INTERVAL_DAY_NAME = "INTERVAL DAY";
public static final String INTERVAL_HOUR_NAME = "INTERVAL HOUR";
public static final String INTERVAL_MINUTE_NAME = "INTERVAL MINUTE";
public static final String INTERVAL_SECOND_NAME = "INTERVAL SECOND";
public static final String INTERVAL_DAY_HOUR_NAME = "INTERVAL DAY TO HOUR";
public static final String INTERVAL_DAY_MINUTE_NAME = "INTERVAL DAY TO MINUTE";
public static final String INTERVAL_DAY_SECOND_NAME = "INTERVAL DAY TO SECOND";
public static final String INTERVAL_HOUR_MINUTE_NAME = "INTERVAL HOUR TO MINUTE";
public static final String INTERVAL_HOUR_SECOND_NAME = "INTERVAL HOUR TO SECOND";
public static final String INTERVAL_MINUTE_SECOND_NAME = "INTERVAL MINUTE TO SECOND";
// Following use of "XML" is per SQL/XML (2003) spec,
// section "10.2 Type name determination".
public static final String XML_NAME = "XML";
// ARRAY and STRUCT are JDBC 2.0 data types that are not
// supported by Derby.
public static final String ARRAY_NAME = "ARRAY";
public static final String STRUCT_NAME = "STRUCT";
// DATALINK is a JDBC 3.0 data type. Not supported by Derby.
public static final String DATALINK_NAME = "DATALINK";
// ROWID and SQLXML are new types in JDBC 4.0. Not supported
// by Derby.
public static final String ROWID_NAME = "ROWID";
public static final String SQLXML_NAME = "SQLXML";
// MySQL compatible types.
public static final String TINYINT_UNSIGNED_NAME = "TINYINT UNSIGNED";
public static final String SMALLINT_UNSIGNED_NAME = "SMALLINT UNSIGNED";
public static final String MEDIUMINT_UNSIGNED_NAME = "MEDIUMINT UNSIGNED";
public static final String INTEGER_UNSIGNED_NAME = "INTEGER UNSIGNED";
public static final String INT_UNSIGNED_NAME = "INT UNSIGNED";
public static final String LONGINT_UNSIGNED_NAME = "BIGINT UNSIGNED";
public static final String FLOAT_UNSIGNED_NAME = "FLOAT UNSIGNED";
public static final String REAL_UNSIGNED_NAME = "REAL UNSIGNED";
public static final String DOUBLE_UNSIGNED_NAME = "DOUBLE UNSIGNED";
public static final String NUMERIC_UNSIGNED_NAME = "NUMERIC UNSIGNED";
public static final String DECIMAL_UNSIGNED_NAME = "DECIMAL UNSIGNED";
public static final String DATETIME_NAME = "DATETIME";
public static final String YEAR_NAME = "YEAR";
/**
* The following constants define the type precedence hierarchy.
*/
public static final int USER_PRECEDENCE = 1000;
public static final int XML_PRECEDENCE = 180;
public static final int BLOB_PRECEDENCE = 170;
public static final int LONGVARBIT_PRECEDENCE = 160;
public static final int VARBIT_PRECEDENCE = 150;
public static final int BIT_PRECEDENCE = 140;
public static final int BOOLEAN_PRECEDENCE = 130;
public static final int INTERVAL_PRECEDENCE = 125;
public static final int TIME_PRECEDENCE = 120;
public static final int TIMESTAMP_PRECEDENCE = 110;
public static final int DATE_PRECEDENCE = 100;
public static final int DOUBLE_PRECEDENCE = 90;
public static final int REAL_PRECEDENCE = 80;
public static final int DECIMAL_PRECEDENCE = 70;
public static final int NUMERIC_PRECEDENCE = 69;
public static final int LONGINT_PRECEDENCE = 60;
public static final int INT_PRECEDENCE = 50;
public static final int SMALLINT_PRECEDENCE = 40;
public static final int TINYINT_PRECEDENCE = 30;
public static final int REF_PRECEDENCE = 25;
public static final int CLOB_PRECEDENCE = 14;
public static final int LONGVARCHAR_PRECEDENCE = 12;
public static final int VARCHAR_PRECEDENCE = 10;
public static final int CHAR_PRECEDENCE = 0;
// This makes it easier to keep the modularity somewhat similar but
// without all the extra instances.
public static class FormatIds {
public static final int BIT_TYPE_ID = 0;
public static final int BOOLEAN_TYPE_ID = 1;
public static final int CHAR_TYPE_ID = 2;
public static final int DATE_TYPE_ID = 3;
public static final int DECIMAL_TYPE_ID = 4;
public static final int NUMERIC_TYPE_ID = 5;
public static final int DOUBLE_TYPE_ID = 6;
public static final int INT_TYPE_ID = 7;
public static final int LONGINT_TYPE_ID = 8;
public static final int LONGVARBIT_TYPE_ID = 9;
public static final int LONGVARCHAR_TYPE_ID = 10;
public static final int REAL_TYPE_ID = 11;
public static final int REF_TYPE_ID = 12;
public static final int SMALLINT_TYPE_ID = 13;
public static final int TIME_TYPE_ID = 14;
public static final int TIMESTAMP_TYPE_ID = 15;
public static final int TINYINT_TYPE_ID = 16;
public static final int USERDEFINED_TYPE_ID = 17;
public static final int VARBIT_TYPE_ID = 18;
public static final int BLOB_TYPE_ID = 19;
public static final int VARCHAR_TYPE_ID = 20;
public static final int CLOB_TYPE_ID = 21;
public static final int XML_TYPE_ID = 22;
public static final int ROW_MULTISET_TYPE_ID_IMPL = 23;
public static final int INTERVAL_YEAR_MONTH_ID = 24;
public static final int INTERVAL_DAY_SECOND_ID = 25;
public static final int MEDIUMINT_ID = 26;
}
public static final TypeId BOOLEAN_ID = new TypeId(FormatIds.BOOLEAN_TYPE_ID);
public static final TypeId SMALLINT_ID = new TypeId(FormatIds.SMALLINT_TYPE_ID);
public static final TypeId MEDIUMINT_ID = new TypeId(FormatIds.MEDIUMINT_ID);
public static final TypeId INTEGER_ID = new TypeId(FormatIds.INT_TYPE_ID);
public static final TypeId CHAR_ID = new TypeId(FormatIds.CHAR_TYPE_ID);
public static final TypeId TINYINT_ID = new TypeId(FormatIds.TINYINT_TYPE_ID);
public static final TypeId BIGINT_ID = new TypeId(FormatIds.LONGINT_TYPE_ID);
public static final TypeId REAL_ID = new TypeId(FormatIds.REAL_TYPE_ID);
public static final TypeId DOUBLE_ID = new TypeId(FormatIds.DOUBLE_TYPE_ID);
public static final TypeId DECIMAL_ID = new TypeId(FormatIds.DECIMAL_TYPE_ID);
public static final TypeId NUMERIC_ID = new TypeId(FormatIds.NUMERIC_TYPE_ID);
public static final TypeId VARCHAR_ID = new TypeId(FormatIds.VARCHAR_TYPE_ID);
public static final TypeId DATE_ID = new TypeId(FormatIds.DATE_TYPE_ID);
public static final TypeId TIME_ID = new TypeId(FormatIds.TIME_TYPE_ID);
public static final TypeId TIMESTAMP_ID = new TypeId(FormatIds.TIMESTAMP_TYPE_ID);
public static final TypeId BIT_ID = new TypeId(FormatIds.BIT_TYPE_ID);
public static final TypeId VARBIT_ID = new TypeId(FormatIds.VARBIT_TYPE_ID);
public static final TypeId REF_ID = new TypeId(FormatIds.REF_TYPE_ID);
public static final TypeId LONGVARCHAR_ID = new TypeId(FormatIds.LONGVARCHAR_TYPE_ID);
public static final TypeId LONGVARBIT_ID = new TypeId(FormatIds.LONGVARBIT_TYPE_ID);
public static final TypeId BLOB_ID = new TypeId(FormatIds.BLOB_TYPE_ID);
public static final TypeId CLOB_ID = new TypeId(FormatIds.CLOB_TYPE_ID);
public static final TypeId XML_ID = new TypeId(FormatIds.XML_TYPE_ID);
public static final TypeId INTERVAL_YEAR_ID = new TypeId(FormatIds.INTERVAL_YEAR_MONTH_ID, INTERVAL_YEAR_NAME);
public static final TypeId INTERVAL_MONTH_ID = new TypeId(FormatIds.INTERVAL_YEAR_MONTH_ID, INTERVAL_MONTH_NAME);
public static final TypeId INTERVAL_YEAR_MONTH_ID = new TypeId(FormatIds.INTERVAL_YEAR_MONTH_ID, INTERVAL_YEAR_MONTH_NAME);
public static final TypeId INTERVAL_DAY_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_DAY_NAME);
public static final TypeId INTERVAL_HOUR_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_HOUR_NAME);
public static final TypeId INTERVAL_MINUTE_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_MINUTE_NAME);
public static final TypeId INTERVAL_SECOND_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_SECOND_NAME);
public static final TypeId INTERVAL_DAY_HOUR_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_DAY_HOUR_NAME);
public static final TypeId INTERVAL_DAY_MINUTE_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_DAY_MINUTE_NAME);
public static final TypeId INTERVAL_DAY_SECOND_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_DAY_SECOND_NAME);
public static final TypeId INTERVAL_HOUR_MINUTE_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_HOUR_MINUTE_NAME);
public static final TypeId INTERVAL_HOUR_SECOND_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_HOUR_SECOND_NAME);
public static final TypeId INTERVAL_MINUTE_SECOND_ID = new TypeId(FormatIds.INTERVAL_DAY_SECOND_ID, INTERVAL_MINUTE_SECOND_NAME);
public static final TypeId SMALLINT_UNSIGNED_ID = new TypeId(FormatIds.SMALLINT_TYPE_ID, true);
public static final TypeId MEDIUMINT_UNSIGNED_ID = new TypeId(FormatIds.MEDIUMINT_ID, true);
public static final TypeId INTEGER_UNSIGNED_ID = new TypeId(FormatIds.INT_TYPE_ID, true);
public static final TypeId TINYINT_UNSIGNED_ID = new TypeId(FormatIds.TINYINT_TYPE_ID, true);
public static final TypeId BIGINT_UNSIGNED_ID = new TypeId(FormatIds.LONGINT_TYPE_ID, true);
public static final TypeId REAL_UNSIGNED_ID = new TypeId(FormatIds.REAL_TYPE_ID, true);
public static final TypeId DOUBLE_UNSIGNED_ID = new TypeId(FormatIds.DOUBLE_TYPE_ID, true);
public static final TypeId DECIMAL_UNSIGNED_ID = new TypeId(FormatIds.DECIMAL_TYPE_ID, true);
public static final TypeId NUMERIC_UNSIGNED_ID = new TypeId(FormatIds.NUMERIC_TYPE_ID, true);
public static final TypeId DATETIME_ID = new TypeId(FormatIds.TIMESTAMP_TYPE_ID, DATETIME_NAME);
public static final TypeId YEAR_ID = new TypeId(FormatIds.SMALLINT_TYPE_ID, YEAR_NAME);
public static final TypeId TEXT_ID = new TypeId(FormatIds.CLOB_TYPE_ID, TEXT_NAME);
public static final TypeId TINYBLOB_ID = new TypeId(FormatIds.BLOB_TYPE_ID, TINYBLOB_NAME);
public static final TypeId TINYTEXT_ID = new TypeId(FormatIds.CLOB_TYPE_ID, TINYTEXT_NAME);
public static final TypeId MEDIUMBLOB_ID = new TypeId(FormatIds.BLOB_TYPE_ID, MEDIUMBLOB_NAME);
public static final TypeId MEDIUMTEXT_ID = new TypeId(FormatIds.CLOB_TYPE_ID, MEDIUMTEXT_NAME);
public static final TypeId LONGBLOB_ID = new TypeId(FormatIds.BLOB_TYPE_ID, LONGBLOB_NAME);
public static final TypeId LONGTEXT_ID = new TypeId(FormatIds.CLOB_TYPE_ID, LONGTEXT_NAME);
private static final TypeId[] ALL_BUILTIN_TYPE_IDS = {
BOOLEAN_ID,
SMALLINT_ID,
MEDIUMINT_ID,
INTEGER_ID,
CHAR_ID,
TINYINT_ID,
BIGINT_ID,
REAL_ID,
DOUBLE_ID,
DECIMAL_ID,
NUMERIC_ID,
VARCHAR_ID,
DATE_ID,
TIME_ID,
TIMESTAMP_ID,
BIT_ID,
VARBIT_ID,
REF_ID,
LONGVARCHAR_ID,
LONGVARBIT_ID,
BLOB_ID,
CLOB_ID,
XML_ID,
INTERVAL_YEAR_ID,
INTERVAL_MONTH_ID,
INTERVAL_YEAR_MONTH_ID,
INTERVAL_DAY_ID,
INTERVAL_HOUR_ID,
INTERVAL_MINUTE_ID,
INTERVAL_SECOND_ID,
INTERVAL_DAY_HOUR_ID,
INTERVAL_DAY_MINUTE_ID,
INTERVAL_DAY_SECOND_ID,
INTERVAL_HOUR_MINUTE_ID,
INTERVAL_HOUR_SECOND_ID,
INTERVAL_MINUTE_SECOND_ID,
SMALLINT_UNSIGNED_ID,
INTEGER_UNSIGNED_ID,
TINYINT_UNSIGNED_ID,
BIGINT_UNSIGNED_ID,
REAL_UNSIGNED_ID,
DOUBLE_UNSIGNED_ID,
DECIMAL_UNSIGNED_ID,
NUMERIC_UNSIGNED_ID,
DATETIME_ID,
YEAR_ID,
TEXT_ID,
TINYBLOB_ID,
TINYTEXT_ID,
MEDIUMBLOB_ID,
MEDIUMTEXT_ID,
LONGBLOB_ID,
LONGTEXT_ID,
};
/*
** Static methods to obtain TypeIds
*/
/**
* Return all of the builtin type ids.
*/
public static TypeId[] getAllBuiltinTypeIds() {
int count = ALL_BUILTIN_TYPE_IDS.length;
TypeId[] retval = new TypeId[count];
for (int i = 0; i < count; i++) {
retval[i] = ALL_BUILTIN_TYPE_IDS[i];
}
return retval;
}
/**
* Get a TypeId of the given JDBC type. This factory method is
* intended to be used for built-in types. For user-defined types,
* we will need a factory method that takes a Java type name.
*
* @param JDBCTypeId The JDBC Id of the type, as listed in
* java.sql.Types
*
* @return The appropriate TypeId, or null if there is no such
* TypeId.
*/
public static TypeId getBuiltInTypeId(int JDBCTypeId) {
switch (JDBCTypeId) {
case Types.TINYINT:
return TINYINT_ID;
case Types.SMALLINT:
return SMALLINT_ID;
case Types.INTEGER:
return INTEGER_ID;
case Types.BIGINT:
return BIGINT_ID;
case Types.FLOAT:
case Types.REAL:
return REAL_ID;
case Types.DOUBLE:
return DOUBLE_ID;
case Types.DECIMAL:
return DECIMAL_ID;
case Types.NUMERIC:
return NUMERIC_ID;
case Types.CHAR:
return CHAR_ID;
case Types.VARCHAR:
return VARCHAR_ID;
case Types.DATE:
return DATE_ID;
case Types.TIME:
return TIME_ID;
case Types.TIMESTAMP:
return TIMESTAMP_ID;
case Types.BIT:
case Types.BOOLEAN:
return BOOLEAN_ID;
case Types.BINARY:
return BIT_ID;
case Types.VARBINARY:
return VARBIT_ID;
case Types.LONGVARBINARY:
return LONGVARBIT_ID;
case Types.LONGVARCHAR:
return LONGVARCHAR_ID;
case Types.BLOB:
return BLOB_ID;
case Types.CLOB:
return CLOB_ID;
case Types.SQLXML: // 2009
return XML_ID;
default:
return null;
}
}
public static TypeId getUserDefinedTypeId(String className,
boolean delimitedIdentifier)
throws StandardException {
return new TypeId(className, delimitedIdentifier);
}
/**
* This factory method is used for ANSI UDTs. If the className argument is null,
* then this TypeId will have to be bound.
*
* @param schemaName Schema that the type definition lives in.
* @param unqualifiedName The second part of the ANSI dot-separated name for the type.
* @param className The Java class which is bound to the schema-qualified name by the CREATE TYPE statement.
*
* @return A bound type TypeId describing this ANSI UDT.
*/
public static TypeId getUserDefinedTypeId(String schemaName, String unqualifiedName,
String className)
throws StandardException {
return new TypeId(schemaName, unqualifiedName, className);
}
/** Return true if this is this type id describes an ANSI UDT */
public boolean isAnsiUDT() {
return (schemaName != null);
}
/**
* Get a TypeId for the class that corresponds to the given Java type
* name.
*
* @param javaTypeName The name of the Java type
*
* @return A TypeId for the SQL type that corresponds to the Java type,
* null if there is no corresponding type.
*/
public static TypeId getSQLTypeForJavaType(String javaTypeName)
throws StandardException {
if (javaTypeName.equals("java.lang.Boolean") ||
javaTypeName.equals("boolean")) {
return BOOLEAN_ID;
}
else if (javaTypeName.equals("byte[]")) {
return VARBIT_ID;
}
else if (javaTypeName.equals("java.lang.String")) {
return VARCHAR_ID;
}
else if (javaTypeName.equals("java.lang.Integer") ||
javaTypeName.equals("int")) {
return INTEGER_ID;
}
else if (javaTypeName.equals("byte")) {
return TINYINT_ID;
}
else if (javaTypeName.equals("short")) {
return SMALLINT_ID;
}
else if (javaTypeName.equals("java.lang.Long") ||
javaTypeName.equals("long")) {
return BIGINT_ID;
}
else if (javaTypeName.equals("java.lang.Float") ||
javaTypeName.equals("float")) {
return REAL_ID;
}
else if (javaTypeName.equals("java.lang.Double") ||
javaTypeName.equals("double")) {
return DOUBLE_ID;
}
else if (javaTypeName.equals("java.math.BigDecimal")) {
return DECIMAL_ID;
}
else if (javaTypeName.equals("java.sql.Date")) {
return DATE_ID;
}
else if (javaTypeName.equals("java.sql.Time")) {
return TIME_ID;
}
else if (javaTypeName.equals("java.sql.Timestamp")) {
return TIMESTAMP_ID;
}
else if (javaTypeName.equals("java.sql.Blob")) {
return BLOB_ID;
}
else if (javaTypeName.equals("java.sql.Clob")) {
return CLOB_ID;
}
else if (javaTypeName.equals("com.akiban.sql.types.XML")) {
return XML_ID;
}
else {
/*
** If it's a Java primitive type, return null to indicate that
** there is no corresponding SQL type (all the Java primitive
** types that have corresponding SQL types are handled above).
**
** There is only one primitive type not mentioned above, char.
*/
if (javaTypeName.equals("char")) {
return null;
}
/*
** It's a non-primitive type (a class) that does not correspond
** to a SQL built-in type, so treat it as a user-defined type.
*/
return TypeId.getUserDefinedTypeId(javaTypeName, false);
}
}
/**
* Given a SQL type name return the corresponding TypeId.
* @param SQLTypeName Name of SQL type
* @return TypeId or null if there is no corresponding SQL type.
*/
public static TypeId getBuiltInTypeId(String SQLTypeName) {
if (SQLTypeName.equals(BOOLEAN_NAME)) {
return BOOLEAN_ID;
}
if (SQLTypeName.equals(CHAR_NAME)) {
return CHAR_ID;
}
if (SQLTypeName.equals(DATE_NAME)) {
return DATE_ID;
}
if (SQLTypeName.equals(DOUBLE_NAME)) {
return DOUBLE_ID;
}
if (SQLTypeName.equals(FLOAT_NAME)) {
return REAL_ID;
}
if (SQLTypeName.equals(MEDIUMINT_NAME))
return MEDIUMINT_ID;
if (SQLTypeName.equals(INTEGER_NAME) ||
SQLTypeName.equals(INT_NAME)) {
return INTEGER_ID;
}
if (SQLTypeName.equals(LONGINT_NAME)) {
return BIGINT_ID;
}
if (SQLTypeName.equals(REAL_NAME)) {
return REAL_ID;
}
if (SQLTypeName.equals(SMALLINT_NAME)) {
return SMALLINT_ID;
}
if (SQLTypeName.equals(TIME_NAME)) {
return TIME_ID;
}
if (SQLTypeName.equals(TIMESTAMP_NAME)) {
return TIMESTAMP_ID;
}
if (SQLTypeName.equals(VARCHAR_NAME)) {
return VARCHAR_ID;
}
if (SQLTypeName.equals(BIT_NAME)) {
return BIT_ID;
}
if (SQLTypeName.equals(VARBIT_NAME)) {
return VARBIT_ID;
}
if (SQLTypeName.equals(TINYINT_NAME)) {
return TINYINT_ID;
}
if (SQLTypeName.equals(DECIMAL_NAME)) {
return DECIMAL_ID;
}
if (SQLTypeName.equals(NUMERIC_NAME)) {
return NUMERIC_ID;
}
if (SQLTypeName.equals(LONGVARCHAR_NAME)) {
return LONGVARCHAR_ID;
}
if (SQLTypeName.equals(LONGVARBIT_NAME)) {
return LONGVARBIT_ID;
}
if (SQLTypeName.equals(BLOB_NAME)) {
return BLOB_ID;
}
if (SQLTypeName.equals(CLOB_NAME)) {
return CLOB_ID;
}
if (SQLTypeName.equals(TEXT_NAME)) {
return TEXT_ID;
}
if (SQLTypeName.equals(TINYBLOB_NAME)) {
return TINYBLOB_ID;
}
if (SQLTypeName.equals(TINYTEXT_NAME)) {
return TINYTEXT_ID;
}
if (SQLTypeName.equals(MEDIUMBLOB_NAME)) {
return MEDIUMBLOB_ID;
}
if (SQLTypeName.equals(MEDIUMTEXT_NAME)) {
return MEDIUMTEXT_ID;
}
if (SQLTypeName.equals(LONGBLOB_NAME)) {
return LONGBLOB_ID;
}
if (SQLTypeName.equals(LONGTEXT_NAME)) {
return LONGTEXT_ID;
}
if (SQLTypeName.equals(XML_NAME)) {
return XML_ID;
}
if (SQLTypeName.equals(INTERVAL_YEAR_NAME)) {
return INTERVAL_YEAR_ID;
}
if (SQLTypeName.equals(INTERVAL_MONTH_NAME)) {
return INTERVAL_MONTH_ID;
}
if (SQLTypeName.equals(INTERVAL_YEAR_MONTH_NAME)) {
return INTERVAL_YEAR_MONTH_ID;
}
if (SQLTypeName.equals(INTERVAL_DAY_NAME)) {
return INTERVAL_DAY_ID;
}
if (SQLTypeName.equals(INTERVAL_HOUR_NAME)) {
return INTERVAL_HOUR_ID;
}
if (SQLTypeName.equals(INTERVAL_MINUTE_NAME)) {
return INTERVAL_MINUTE_ID;
}
if (SQLTypeName.equals(INTERVAL_SECOND_NAME)) {
return INTERVAL_SECOND_ID;
}
if (SQLTypeName.equals(INTERVAL_DAY_HOUR_NAME)) {
return INTERVAL_DAY_HOUR_ID;
}
if (SQLTypeName.equals(INTERVAL_DAY_MINUTE_NAME)) {
return INTERVAL_DAY_MINUTE_ID;
}
if (SQLTypeName.equals(INTERVAL_DAY_SECOND_NAME)) {
return INTERVAL_DAY_SECOND_ID;
}
if (SQLTypeName.equals(INTERVAL_HOUR_MINUTE_NAME)) {
return INTERVAL_HOUR_MINUTE_ID;
}
if (SQLTypeName.equals(INTERVAL_HOUR_SECOND_NAME)) {
return INTERVAL_HOUR_SECOND_ID;
}
if (SQLTypeName.equals(INTERVAL_MINUTE_SECOND_NAME)) {
return INTERVAL_MINUTE_SECOND_ID;
}
if (SQLTypeName.equals(TINYINT_UNSIGNED_NAME)) {
return TINYINT_UNSIGNED_ID;
}
if (SQLTypeName.equals(SMALLINT_UNSIGNED_NAME)) {
return SMALLINT_UNSIGNED_ID;
}
if (SQLTypeName.equals(INTEGER_UNSIGNED_NAME) ||
SQLTypeName.equals(INT_UNSIGNED_NAME)) {
return INTEGER_UNSIGNED_ID;
}
if (SQLTypeName.equals(LONGINT_UNSIGNED_NAME)) {
return BIGINT_UNSIGNED_ID;
}
if (SQLTypeName.equals(FLOAT_UNSIGNED_NAME)) {
return REAL_UNSIGNED_ID;
}
if (SQLTypeName.equals(REAL_UNSIGNED_NAME)) {
return REAL_UNSIGNED_ID;
}
if (SQLTypeName.equals(DOUBLE_UNSIGNED_NAME)) {
return DOUBLE_UNSIGNED_ID;
}
if (SQLTypeName.equals(NUMERIC_UNSIGNED_NAME)) {
return NUMERIC_UNSIGNED_ID;
}
if (SQLTypeName.equals(DECIMAL_UNSIGNED_NAME)) {
return DECIMAL_UNSIGNED_ID;
}
if (SQLTypeName.equals(DATETIME_NAME)) {
return DATETIME_ID;
}
if (SQLTypeName.equals(YEAR_NAME)) {
return YEAR_ID;
}
// Types defined below here are SQL types and non-JDBC types that are
// supported by Derby
if (SQLTypeName.equals(REF_NAME)) {
return REF_ID;
}
return null;
}
/*
* * Instance fields and methods
*/
/* Set in setTypeIdSpecificInstanceVariables() as needed */
private int formatId;
private String schemaName;
private String unqualifiedName;
private int JDBCTypeId;
private String javaTypeName;
private boolean classNameWasDelimitedIdentifier;
private boolean isBitTypeId;
private boolean isLOBTypeId;
private boolean isBooleanTypeId;
private boolean isConcatableTypeId;
private boolean isDecimalTypeId;
private boolean isLongConcatableTypeId;
private boolean isNumericTypeId;
private boolean isRefTypeId;
private boolean isStringTypeId;
private boolean isFloatingPointTypeId;
private boolean isRealTypeId;
private boolean isDateTimeTimeStampTypeId;
private boolean isIntervalTypeId;
private boolean isUserDefinedTypeId;
private boolean isComparable;
private int maxPrecision;
private int maxScale;
private int maxMaxWidth;
private int typePrecedence;
/**
* Constructor for a TypeId
*
* @param formatId Internal format id
*/
private TypeId(int formatId) {
this.formatId = formatId;
// most types are comparable to themselves (with a few exceptions)
isComparable = true;
switch (formatId) {
case FormatIds.BIT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.BIT_NAME;
JDBCTypeId = Types.BINARY;
typePrecedence = BIT_PRECEDENCE;
javaTypeName = "byte[]";
maxMaxWidth = TypeId.BIT_MAXWIDTH;
isBitTypeId = true;
isConcatableTypeId = true;
break;
case FormatIds.BOOLEAN_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.BOOLEAN_NAME;
JDBCTypeId = Types.BOOLEAN;
maxPrecision = TypeId.BOOLEAN_MAXWIDTH;
typePrecedence = BOOLEAN_PRECEDENCE;
javaTypeName = "java.lang.Boolean";
maxMaxWidth = TypeId.BOOLEAN_MAXWIDTH;
isBooleanTypeId = true;
break;
case FormatIds.CHAR_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.CHAR_NAME;
JDBCTypeId = Types.CHAR;
typePrecedence = CHAR_PRECEDENCE;
javaTypeName = "java.lang.String";
maxMaxWidth = TypeId.CHAR_MAXWIDTH;
isStringTypeId = true;
isConcatableTypeId = true;
break;
case FormatIds.DATE_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.DATE_NAME;
JDBCTypeId = Types.DATE;
typePrecedence = DATE_PRECEDENCE;
javaTypeName = "java.sql.Date";
maxMaxWidth = TypeId.DATE_MAXWIDTH;
maxPrecision = TypeId.DATE_MAXWIDTH;
isDateTimeTimeStampTypeId = true;
break;
case FormatIds.DECIMAL_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.DECIMAL_NAME;
JDBCTypeId = Types.DECIMAL;
maxPrecision = TypeId.DECIMAL_PRECISION;
maxScale = TypeId.DECIMAL_SCALE;
typePrecedence = DECIMAL_PRECEDENCE;
javaTypeName = "java.math.BigDecimal";
maxMaxWidth = TypeId.DECIMAL_MAXWIDTH;
isDecimalTypeId = true;
isNumericTypeId = true;
break;
case FormatIds.NUMERIC_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.NUMERIC_NAME;
JDBCTypeId = Types.NUMERIC;
maxPrecision = TypeId.DECIMAL_PRECISION;
maxScale = TypeId.DECIMAL_SCALE;
typePrecedence = DECIMAL_PRECEDENCE;
javaTypeName = "java.math.BigDecimal";
maxMaxWidth = TypeId.DECIMAL_MAXWIDTH;
isDecimalTypeId = true;
isNumericTypeId = true;
break;
case FormatIds.DOUBLE_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.DOUBLE_NAME;
JDBCTypeId = Types.DOUBLE;
maxPrecision = TypeId.DOUBLE_PRECISION;
maxScale = TypeId.DOUBLE_SCALE;
typePrecedence = DOUBLE_PRECEDENCE;
javaTypeName = "java.lang.Double";
maxMaxWidth = TypeId.DOUBLE_MAXWIDTH;
isNumericTypeId = true;
isFloatingPointTypeId = true;
break;
case FormatIds.MEDIUMINT_ID:
schemaName = null;
unqualifiedName = TypeId.MEDIUMINT_NAME;
JDBCTypeId = Types.OTHER;
maxPrecision = TypeId.INT_PRECISION;
maxScale = TypeId.INT_SCALE;
typePrecedence = INT_PRECEDENCE;
javaTypeName = "java.lang.Integer";
maxMaxWidth = TypeId.INT_MAXWIDTH;
isNumericTypeId = true;
break;
case FormatIds.INT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.INTEGER_NAME;
JDBCTypeId = Types.INTEGER;
maxPrecision = TypeId.INT_PRECISION;
maxScale = TypeId.INT_SCALE;
typePrecedence = INT_PRECEDENCE;
javaTypeName = "java.lang.Integer";
maxMaxWidth = TypeId.INT_MAXWIDTH;
isNumericTypeId = true;
break;
case FormatIds.LONGINT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.LONGINT_NAME;
JDBCTypeId = Types.BIGINT;
maxPrecision = TypeId.LONGINT_PRECISION;
maxScale = TypeId.LONGINT_SCALE;
typePrecedence = LONGINT_PRECEDENCE;
javaTypeName = "java.lang.Long";
maxMaxWidth = TypeId.LONGINT_MAXWIDTH;
isNumericTypeId = true;
break;
case FormatIds.LONGVARBIT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.LONGVARBIT_NAME;
JDBCTypeId = Types.LONGVARBINARY;
typePrecedence = LONGVARBIT_PRECEDENCE;
javaTypeName = "byte[]";
maxMaxWidth = TypeId.LONGVARBIT_MAXWIDTH;
isBitTypeId = true;
isConcatableTypeId = true;
isLongConcatableTypeId = true;
break;
case FormatIds.LONGVARCHAR_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.LONGVARCHAR_NAME;
JDBCTypeId = Types.LONGVARCHAR;
typePrecedence = LONGVARCHAR_PRECEDENCE;
javaTypeName = "java.lang.String";
maxMaxWidth = TypeId.LONGVARCHAR_MAXWIDTH;
isStringTypeId = true;
isConcatableTypeId = true;
isLongConcatableTypeId = true;
isComparable = false;
break;
case FormatIds.REAL_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.REAL_NAME;
JDBCTypeId = Types.REAL;
maxPrecision = TypeId.REAL_PRECISION;
maxScale = TypeId.REAL_SCALE;
typePrecedence = REAL_PRECEDENCE;
javaTypeName = "java.lang.Float";
maxMaxWidth = TypeId.REAL_MAXWIDTH;
isNumericTypeId = true;
isRealTypeId = true;
isFloatingPointTypeId = true;
break;
case FormatIds.REF_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.REF_NAME;
JDBCTypeId = Types.OTHER;
typePrecedence = REF_PRECEDENCE;
javaTypeName = "java.sql.Ref";
isRefTypeId = true;
isComparable = false;
break;
case FormatIds.SMALLINT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.SMALLINT_NAME;
JDBCTypeId = Types.SMALLINT;
maxPrecision = TypeId.SMALLINT_PRECISION;
maxScale = TypeId.SMALLINT_SCALE;
typePrecedence = SMALLINT_PRECEDENCE;
javaTypeName = "java.lang.Integer";
maxMaxWidth = TypeId.SMALLINT_MAXWIDTH;
isNumericTypeId = true;
break;
case FormatIds.TIME_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.TIME_NAME;
JDBCTypeId = Types.TIME;
typePrecedence = TIME_PRECEDENCE;
javaTypeName = "java.sql.Time";
maxScale = TypeId.TIME_SCALE;
maxMaxWidth = TypeId.TIME_MAXWIDTH;
maxPrecision = TypeId.TIME_MAXWIDTH;
isDateTimeTimeStampTypeId = true;
break;
case FormatIds.TIMESTAMP_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.TIMESTAMP_NAME;
JDBCTypeId = Types.TIMESTAMP;
typePrecedence = TIMESTAMP_PRECEDENCE;
javaTypeName = "java.sql.Timestamp";
maxScale = TypeId.TIMESTAMP_SCALE;
maxMaxWidth = TypeId.TIMESTAMP_MAXWIDTH;
maxPrecision = TypeId.TIMESTAMP_MAXWIDTH;
isDateTimeTimeStampTypeId = true;
break;
case FormatIds.TINYINT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.TINYINT_NAME;
JDBCTypeId = Types.TINYINT;
maxPrecision = TypeId.TINYINT_PRECISION;
maxScale = TypeId.TINYINT_SCALE;
typePrecedence = TINYINT_PRECEDENCE;
javaTypeName = "java.lang.Integer";
maxMaxWidth = TypeId.TINYINT_MAXWIDTH;
isNumericTypeId = true;
break;
case FormatIds.VARBIT_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.VARBIT_NAME;
JDBCTypeId = Types.VARBINARY;
typePrecedence = VARBIT_PRECEDENCE;
javaTypeName = "byte[]";
maxMaxWidth = TypeId.VARBIT_MAXWIDTH;
isBitTypeId = true;
isConcatableTypeId = true;
break;
case FormatIds.BLOB_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.BLOB_NAME;
JDBCTypeId = Types.BLOB;
typePrecedence = BLOB_PRECEDENCE;
javaTypeName = "java.sql.Blob";
maxMaxWidth = TypeId.BLOB_MAXWIDTH;
isBitTypeId = true;
isConcatableTypeId = true;
isComparable = false;
isLOBTypeId = true;
break;
case FormatIds.VARCHAR_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.VARCHAR_NAME;
JDBCTypeId = Types.VARCHAR;
typePrecedence = VARCHAR_PRECEDENCE;
javaTypeName = "java.lang.String";
maxMaxWidth = TypeId.VARCHAR_MAXWIDTH;
isStringTypeId = true;
isConcatableTypeId = true;
break;
case FormatIds.CLOB_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.CLOB_NAME;
JDBCTypeId = Types.CLOB;
typePrecedence = CLOB_PRECEDENCE;
javaTypeName = "java.sql.Clob";
maxMaxWidth = TypeId.CLOB_MAXWIDTH;
isStringTypeId = true;
isConcatableTypeId = true;
isComparable = false;
isLOBTypeId = true;
break;
case FormatIds.XML_TYPE_ID:
schemaName = null;
unqualifiedName = TypeId.XML_NAME;
JDBCTypeId = Types.SQLXML;
typePrecedence = XML_PRECEDENCE;
javaTypeName = "com.akiban.sql.types.XML";
maxMaxWidth = TypeId.XML_MAXWIDTH;
isComparable = false;
break;
case FormatIds.INTERVAL_YEAR_MONTH_ID:
schemaName = null;
typePrecedence = INTERVAL_PRECEDENCE;
JDBCTypeId = Types.OTHER;
maxPrecision = TypeId.INTERVAL_YEAR_MONTH_PRECISION;
maxScale = TypeId.INTERVAL_YEAR_MONTH_SCALE;
maxMaxWidth = TypeId.INTERVAL_YEAR_MONTH_MAXWIDTH;
isIntervalTypeId = true;
break;
case FormatIds.INTERVAL_DAY_SECOND_ID:
schemaName = null;
typePrecedence = INTERVAL_PRECEDENCE;
JDBCTypeId = Types.OTHER;
maxPrecision = TypeId.INTERVAL_DAY_SECOND_PRECISION;
maxScale = TypeId.INTERVAL_DAY_SECOND_SCALE;
maxMaxWidth = TypeId.INTERVAL_DAY_SECOND_MAXWIDTH;
isIntervalTypeId = true;
break;
case FormatIds.USERDEFINED_TYPE_ID:
JDBCTypeId = java.sql.Types.JAVA_OBJECT;
maxMaxWidth = -1;
isUserDefinedTypeId = true;
typePrecedence = USER_PRECEDENCE;
break;
case FormatIds.ROW_MULTISET_TYPE_ID_IMPL:
schemaName = null;
JDBCTypeId = Types.OTHER;
javaTypeName = "java.sql.ResultSet";
maxMaxWidth = -1;
break;
default:
assert false;
break;
}
}
public int getTypeFormatId() {
return formatId;
}
private boolean unsigned;
private TypeId(int formatId, boolean unsigned) {
this(formatId);
if (unsigned) {
this.unsigned = true;
switch (formatId) {
case FormatIds.DECIMAL_TYPE_ID:
unqualifiedName = TypeId.DECIMAL_UNSIGNED_NAME;
break;
case FormatIds.NUMERIC_TYPE_ID:
unqualifiedName = TypeId.NUMERIC_UNSIGNED_NAME;
break;
case FormatIds.DOUBLE_TYPE_ID:
unqualifiedName = TypeId.DOUBLE_UNSIGNED_NAME;
break;
case FormatIds.INT_TYPE_ID:
unqualifiedName = TypeId.INTEGER_UNSIGNED_NAME;
break;
case FormatIds.LONGINT_TYPE_ID:
unqualifiedName = TypeId.LONGINT_UNSIGNED_NAME;
break;
case FormatIds.REAL_TYPE_ID:
unqualifiedName = TypeId.REAL_UNSIGNED_NAME;
break;
case FormatIds.SMALLINT_TYPE_ID:
unqualifiedName = TypeId.SMALLINT_UNSIGNED_NAME;
break;
case FormatIds.TINYINT_TYPE_ID:
unqualifiedName = TypeId.TINYINT_UNSIGNED_NAME;
break;
case FormatIds.MEDIUMINT_ID:
unqualifiedName = TypeId.MEDIUMINT_UNSIGNED_NAME;
break;
default:
assert false : "unknown formatId: " + formatId;
}
}
}
private TypeId(int formatId, String name) {
this(formatId);
unqualifiedName = name;
}
/**
* Constructor for a TypeId for user defined types
*
* @param className The class name / delimited identifier.
* @param classNameWasDelimitedIdentifier Whether or not the class name
* was a delimited identifier.
*/
private TypeId(String className, boolean classNameWasDelimitedIdentifier) {
this(FormatIds.USERDEFINED_TYPE_ID);
if (classNameWasDelimitedIdentifier) {
// TODO: Need to split?
}
else {
schemaName = null;
unqualifiedName = className;
}
javaTypeName = className;
this.classNameWasDelimitedIdentifier = classNameWasDelimitedIdentifier;
}
private TypeId(String schemaName, String unqualifiedName, String className) {
this(FormatIds.USERDEFINED_TYPE_ID);
this.schemaName = schemaName;
this.unqualifiedName = unqualifiedName;
this.javaTypeName = className;
}
/**
* we want equals to say if these are the same type id or not.
*/
public boolean equals(Object that) {
if (that instanceof TypeId)
return this.getSQLTypeName().equals(((TypeId)that).getSQLTypeName());
else
return false;
}
/*
Hashcode which works with equals.
*/
public int hashCode() {
return this.getSQLTypeName().hashCode();
}
/**
* JDBC has its own idea of type identifiers which is different from
* the Derby internal type ids. The JDBC type ids are defined
* as public final static ints in java.sql.Types. This method translates
* a Derby internal TypeId to a JDBC type id. For java objects this
* returns JAVA_OBJECT in Java2 and OTHER in JDK 1.1. For Boolean datatypes,
* this returns Type.BOOLEAN in JDK1.4 and Type.BIT for jdks prior to 1.4
*
* @return The JDBC type Id for this type
*/
public final int getJDBCTypeId() {
return JDBCTypeId;
}
/**
* Returns the SQL name of the datatype. If it is a user-defined type,
* it returns the full Java path name for the datatype, meaning the
* dot-separated path including the package names.
*
* @return A String containing the SQL name of this type.
*/
public String getSQLTypeName() {
if (schemaName == null) {
return unqualifiedName;
}
else {
// TODO: Need some quotes?
return schemaName + "." + unqualifiedName;
}
}
/**
* Tell whether this is a built-in type.
* NOTE: There are 3 "classes" of types:
* built-in - system provided types which are implemented internally
* (int, smallint, etc.)
* system built-in - system provided types, independent of implementation
* (date, time, etc.)
* user types - types implemented outside of the system
* (java.lang.Integer, asdf.asdf.asdf, etc.)
*
* @return false for built-in types, true for user-defined types.
*/
public final boolean userType() {
return isUserDefinedTypeId;
}
/**
* Get the maximum precision of the type. For types with variable
* precision, this is an arbitrary high precision.
*
* @return The maximum precision of the type
*/
public int getMaximumPrecision() {
return maxPrecision;
}
/**
* Get the maximum scale of the type. For types with variable scale,
* this is an arbitrary high scale.
*
* @return The maximum scale of the type
*/
public int getMaximumScale() {
return maxScale;
}
/**
* For user types, tell whether or not the class name was a
* delimited identifier. For all other types, return false.
*
* @return Whether or not the class name was a delimited identifier.
*/
public boolean getClassNameWasDelimitedIdentifier() {
return classNameWasDelimitedIdentifier;
}
/**
* Does this TypeId represent a TypeId for a StringDataType.
*
* @return Whether or not this TypeId represents a TypeId for a StringDataType.
*/
public boolean isStringTypeId() {
return isStringTypeId;
}
/**
* Is this a TypeId for DATE/TIME/TIMESTAMP
*
* @return true if this is a DATE/TIME/TIMESTAMP
*/
public boolean isDateTimeTimeStampTypeId() {
return isDateTimeTimeStampTypeId;
}
/**
* Is this a TypeId for REAL
*
* @return true if this is a REAL
*/
public boolean isRealTypeId() {
return isRealTypeId;
}
/**
* Is this a TypeId for floating point (REAL/DOUBLE)
*
* @return true if this is a REAL or DOUBLE
*/
public boolean isFloatingPointTypeId() {
return isFloatingPointTypeId;
}
/**
* Is this a TypeId for DOUBLE
*
* @return true if this is a DOUBLE
*/
public boolean isDoubleTypeId() {
return isFloatingPointTypeId && (!isRealTypeId);
}
/**
* Is this a fixed string type?
* @return true if this is CHAR
*/
public boolean isFixedStringTypeId() {
return (formatId == FormatIds.CHAR_TYPE_ID);
}
/**
*Is this a Clob?
* @return true if this is CLOB
*/
public boolean isClobTypeId()
{
return (formatId == FormatIds.CLOB_TYPE_ID);
}
/**
*Is this a Blob?
* @return true if this is BLOB
*/
public boolean isBlobTypeId()
{
return (formatId == FormatIds.BLOB_TYPE_ID);
}
/**
*Is this a LongVarchar?
* @return true if this is LongVarchar
*/
public boolean isLongVarcharTypeId()
{
return (formatId == FormatIds.LONGVARCHAR_TYPE_ID);
}
/**
*Is this a LongVarbinary?
* @return true if this is LongVarbinary
*/
public boolean isLongVarbinaryTypeId()
{
return (formatId == FormatIds.LONGVARBIT_TYPE_ID);
}
/**
* Is this DATE/TIME or TIMESTAMP?
*
* @return true if this DATE/TIME or TIMESTAMP
*/
public boolean isDateTimeTimeStampTypeID()
{
return ((formatId == FormatIds.DATE_TYPE_ID) ||
(formatId == FormatIds.TIME_TYPE_ID) ||
(formatId == FormatIds.TIMESTAMP_TYPE_ID));
}
/**
*Is this an XML doc?
* @return true if this is XML
*/
public boolean isXMLTypeId()
{
return (formatId == FormatIds.XML_TYPE_ID);
}
/**
* @return <code>false</code> if this type is not comparable to any other types or even to itself
* <code>true</code> otherwise.
*/
public boolean isComparable()
{
return isComparable;
}
/**
* Each built-in type in JSQL has a precedence. This precedence determines
* how to do type promotion when using binary operators. For example, float
* has a higher precedence than int, so when adding an int to a float, the
* result type is float.
*
* The precedence for some types is arbitrary. For example, it doesn't
* matter what the precedence of the boolean type is, since it can't be
* mixed with other types. But the precedence for the number types is
* critical. The SQL standard requires that exact numeric types be
* promoted to approximate numeric when one operator uses both. Also,
* the precedence is arranged so that one will not lose precision when
* promoting a type.
* NOTE: char, varchar, and longvarchar must appear at the bottom of
* the hierarchy, but above USER_PRECEDENCE, since we allow the implicit
* conversion of those types to any other built-in system type.
*
* @return The precedence of this type.
*/
public int typePrecedence()
{
return typePrecedence;
}
/**
* Get the name of the corresponding Java type.
*
* Each SQL type has a corresponding Java type. When a SQL value is
* passed to a Java method, it is translated to its corresponding Java
* type. For example, when a SQL date column is passed to a method,
* it is translated to a java.sql.Date.
*
* @return The name of the corresponding Java type.
*/
public String getCorrespondingJavaTypeName() {
return javaTypeName;
}
/**
* Get the name of the corresponding Java type.
*
* This method is used directly from EmbedResultSetMetaData (jdbc)
* to return the corresponding type (as choosen by getObject).
* It solves a specific problem for BLOB types where the
* getCorrespondingJavaTypeName() is used internally for casting
* which doesn't work if changed from byte[] to java.sql.Blob.
* So we do it here instead, to avoid unexpected side effects.
*
* @return The name of the corresponding Java type.
*/
public String getResultSetMetaDataTypeName() {
if (BLOB_ID.equals(this))
return "java.sql.Blob";
if (CLOB_ID.equals(this))
return "java.sql.Clob";
return getCorrespondingJavaTypeName();
}
/**
* Get the maximum maximum width of the type (that's not a typo). For
* types with variable length, this is the absolute maximum for the type.
*
* @return The maximum maximum width of the type
*/
public int getMaximumMaximumWidth() {
return maxMaxWidth;
}
/**
* Converts this TypeId, given a data type descriptor (including length/precision),
* to a string. E.g.
*
* VARCHAR(30)
*
*
* For most data types, we just return the SQL type name.
*
* @param dts Data type descriptor that holds the length/precision etc. as necessary
*
* @return String version of datatype, suitable for running through
* the Parser.
*/
// TODO: Consider consolitation with DataTypeDescriptor.getFullSQLTypeName().
public String toParsableString(DataTypeDescriptor dts) {
String retval = getSQLTypeName();
switch (formatId) {
case FormatIds.BIT_TYPE_ID:
case FormatIds.VARBIT_TYPE_ID:
int rparen = retval.indexOf(')');
String lead = retval.substring(0, rparen);
retval = lead + dts.getMaximumWidth() + retval.substring(rparen);
break;
case FormatIds.CHAR_TYPE_ID:
case FormatIds.VARCHAR_TYPE_ID:
case FormatIds.BLOB_TYPE_ID:
case FormatIds.CLOB_TYPE_ID:
retval += "(" + dts.getMaximumWidth() + ")";
break;
case FormatIds.DECIMAL_TYPE_ID:
if (unsigned) {
retval = retval.substring(0, retval.length() - 9) +
"(" + dts.getPrecision() + "," + dts.getScale() + ")" +
retval.substring(retval.length() - 9);
}
else
retval += "(" + dts.getPrecision() + "," + dts.getScale() + ")";
break;
case FormatIds.INTERVAL_YEAR_MONTH_ID:
case FormatIds.INTERVAL_DAY_SECOND_ID:
if (this == INTERVAL_SECOND_ID) {
if (dts.getPrecision() > 0) {
retval += "(" + dts.getPrecision();
if (dts.getScale() > 0)
retval += ", " + dts.getScale();
retval += ")";
}
}
else {
if (dts.getPrecision() > 0) {
int idx = retval.indexOf(" ", 9);
if (idx < 0) idx = retval.length();
retval = retval.substring(0, idx) +
"(" + dts.getPrecision() + ")" +
retval.substring(idx);
}
if (dts.getScale() > 0)
retval += "(" + dts.getScale() +")";
}
break;
}
return retval;
}
/**
* Is this a type id for a numeric type?
*
* @return Whether or not this a type id for a numeric type.
*/
public boolean isNumericTypeId() {
return isNumericTypeId;
}
/**
* Is this a type id for a decimal type?
*
* @return Whether or not this a type id for a decimal type.
*/
public boolean isDecimalTypeId() {
return isDecimalTypeId;
}
/**
* Is this a type id for an integer type?
*
* @return Whether or not this a type id for a integer type.
*/
public boolean isIntegerTypeId() {
return isNumericTypeId && !isDecimalTypeId && !isFloatingPointTypeId;
}
/**
* Is this a type id for a boolean type?
*
* @return Whether or not this a type id for a boolean type.
*/
public boolean isBooleanTypeId() {
return isBooleanTypeId;
}
/**
* Is this a type id for a ref type?
*
* @return Whether or not this a type id for a ref type.
*/
public boolean isRefTypeId() {
return isRefTypeId;
}
/**
* Is this a type id for a concatable type?
*
* @return Whether or not this a type id for a concatable type.
*/
public boolean isConcatableTypeId() {
return isConcatableTypeId;
}
/**
* Is this a type id for a bit type?
*
* @return Whether or not this a type id for a bit type.
*/
public boolean isBitTypeId() {
return isBitTypeId;
}
/**
* Is this a type id for a LOB type?
*
* @return Whether or not this a type id for a LOB type.
*/
public boolean isLOBTypeId() {
return isLOBTypeId;
}
/**
* Is this a type id for a long concatable type?
*
* @return Whether or not this a type id for a long concatable type.
*/
public boolean isLongConcatableTypeId() {
return isLongConcatableTypeId;
}
/**
* Is this a type id for a user defined type?
*
* @return Whether or not this a type id for a user defined type.
*/
public boolean isUserDefinedTypeId() {
return isUserDefinedTypeId;
}
/**
* Get the precision of the merge of two Decimals
*
* @param leftType the left type
* @param rightType the left type
*
* @return the resultant precision
*/
public int getPrecision(DataTypeDescriptor leftType,
DataTypeDescriptor rightType) {
long lscale = (long)leftType.getScale();
long rscale = (long)rightType.getScale();
long lprec = (long)leftType.getPrecision();
long rprec = (long)rightType.getPrecision();
long val;
assert (formatId == FormatIds.DECIMAL_TYPE_ID) : formatId;
/*
** Take the maximum left of decimal digits plus the scale.
*/
val = this.getScale(leftType, rightType) + Math.max(lprec - lscale, rprec - rscale);
if (val > Integer.MAX_VALUE) {
val = Integer.MAX_VALUE;
}
return (int)val;
}
/**
* Get the scale of the merge of two decimals
*
* @param leftType the left type
* @param rightType the left type
*
* @return the resultant precision
*/
public int getScale(DataTypeDescriptor leftType,
DataTypeDescriptor rightType) {
assert (formatId == FormatIds.DECIMAL_TYPE_ID) : formatId;
/*
** Retain greatest scale
*/
return Math.max(leftType.getScale(), rightType.getScale());
}
/**
* Does type hava a declared variable length (defined by the application).
* Examples are CHAR(10), CLOB(1M).
* Unbounded long types, like LONG VARCHAR return false here.
* @return boolean true if type is variable length false if not.
*/
public boolean variableLength() {
switch (formatId) {
case FormatIds.BIT_TYPE_ID:
case FormatIds.VARBIT_TYPE_ID:
case FormatIds.DECIMAL_TYPE_ID:
case FormatIds.CHAR_TYPE_ID:
case FormatIds.VARCHAR_TYPE_ID:
case FormatIds.BLOB_TYPE_ID:
case FormatIds.CLOB_TYPE_ID:
return true;
default:
return false;
}
}
public static class RowMultiSetTypeId extends TypeId {
String[] columnNames;
DataTypeDescriptor[] columnTypes;
public RowMultiSetTypeId(String[] columnNames, DataTypeDescriptor[] columnTypes) {
super(FormatIds.ROW_MULTISET_TYPE_ID_IMPL);
this.columnNames = columnNames;
this.columnTypes = columnTypes;
}
/**
* <p>
* Get the SQL name of this multi set. This is the name suitable for
* replaying the DDL to create a Table Function.
* </p>
*/
public String getSQLTypeName() {
StringBuffer buffer = new StringBuffer();
int count = columnNames.length;
buffer.append("TABLE ( ");
for (int i = 0; i < count; i++) {
if (i > 0) {
buffer.append( ", " );
}
buffer.append('\"');
buffer.append(columnNames[i]);
buffer.append('\"');
buffer.append(' ');
buffer.append(columnTypes[i].getSQLstring());
}
buffer.append( " )" );
return buffer.toString();
}
public boolean isRowMultiSet() {
return true;
}
public String[] getColumnNames() {
return columnNames;
}
public DataTypeDescriptor[] getColumnTypes() {
return columnTypes;
}
}
public static TypeId getRowMultiSet(String[] columnNames,
DataTypeDescriptor[] columnTypes) {
return new RowMultiSetTypeId(columnNames, columnTypes);
}
public boolean isRowMultiSet() {
return false;
}
/** Is this one of the unsigned numeric types? */
public boolean isUnsigned() {
return unsigned;
}
public static TypeId intervalTypeId(TypeId startField, TypeId endField)
throws StandardException {
if (startField == INTERVAL_YEAR_ID) {
if (endField == INTERVAL_MONTH_ID)
return INTERVAL_YEAR_MONTH_ID;
}
if (startField == INTERVAL_DAY_ID) {
if (endField == INTERVAL_HOUR_ID)
return INTERVAL_DAY_HOUR_ID;
if (endField == INTERVAL_MINUTE_ID)
return INTERVAL_DAY_MINUTE_ID;
if (endField == INTERVAL_SECOND_ID)
return INTERVAL_DAY_SECOND_ID;
}
if (startField == INTERVAL_HOUR_ID) {
if (endField == INTERVAL_MINUTE_ID)
return INTERVAL_HOUR_MINUTE_ID;
if (endField == INTERVAL_SECOND_ID)
return INTERVAL_HOUR_SECOND_ID;
}
if (startField == INTERVAL_MINUTE_ID) {
if (endField == INTERVAL_SECOND_ID)
return INTERVAL_MINUTE_SECOND_ID;
}
throw new StandardException("Illegal " + startField.unqualifiedName +
" TO " + endField.unqualifiedName.substring("INTERVAL ".length()));
}
public boolean isIntervalTypeId() {
return isIntervalTypeId;
}
}