/* Copyright (c) 2001-2008, The HSQL Development Group
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* Neither the name of the HSQL Development Group nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.hsqldb;
import org.hsqldb.lib.IntKeyHashMap;
import org.hsqldb.lib.IntValueHashMap;
import org.hsqldb.lib.HashMap;
/**
* Defines the constants that are used to identify SQL types for HSQLDB JDBC
* inteface type reporting. The actual type constant values are equivalent
* to those defined in the latest java.sql.Types, where available,
* or those defined by ansi/iso SQL 200n otherwise. A type sub-identifer
* has been added to differentiate HSQLDB-specific type specializations.
*
* @author boucherb@users
* @version 1.7.2
* @since 1.7.2
*/
public class Types {
/**
* Names of types.
* Used for external, JDBC reporting
* Used for library and user function arguments
*/
public static final String DecimalClassName = "java.math.BigDecimal";
public static final String DateClassName = "java.sql.Date";
public static final String TimeClassName = "java.sql.Time";
public static final String TimestampClassName = "java.sql.Timestamp";
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* ARRAY
.
*
* @since JDK 1.2
*/
public static final int ARRAY = 2003;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* BIGINT
.
*/
public static final int BIGINT = -5;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* BINARY
.
*/
public static final int BINARY = -2;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* BLOB
.
*
* @since JDK 1.2
*/
public static final int BLOB = 2004;
/**
* The constant in the Java programming language, somtimes referred to
* as a type code, that identifies the generic SQL type
* BOOLEAN
.
*
* @since JDK 1.4
*/
public static final int BOOLEAN = 16;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* CHAR
.
*/
public static final int CHAR = 1;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* CLOB
*
* @since JDK 1.2
*/
public static final int CLOB = 2005;
/**
* The constant in the Java programming language, somtimes referred to
* as a type code, that identifies the generic SQL type DATALINK
.
*
* @since JDK 1.4
*/
public static final int DATALINK = 70;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* DATE
.
*/
public static final int DATE = 91;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* DECIMAL
.
*/
public static final int DECIMAL = 3;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* DISTINCT
.
*
* @since JDK 1.2
*/
public static final int DISTINCT = 2001;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* DOUBLE
.
*/
public static final int DOUBLE = 8;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* FLOAT
.
*/
public static final int FLOAT = 6;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* INTEGER
.
*/
public static final int INTEGER = 4;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* JAVA_OBJECT
.
*
* @since JDK 1.2
*/
public static final int JAVA_OBJECT = 2000;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* LONGVARBINARY
.
*/
public static final int LONGVARBINARY = -4;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* LONGVARCHAR
.
*/
public static final int LONGVARCHAR = -1;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* NULL
.
*/
public static final int NULL = 0;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* NUMERIC
.
*/
public static final int NUMERIC = 2;
/**
* The constant in the Java programming language that indicates
* that the SQL type is database-specific and
* gets mapped to a Java object that can be accessed via
* the methods getObject
and setObject
.
*/
public static final int OTHER = 1111;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* REAL
.
*/
public static final int REAL = 7;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* REF
.
*
* @since JDK 1.2
*/
public static final int REF = 2006;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* SMALLINT
.
*/
public static final int SMALLINT = 5;
/**
* The constant in the Java programming language, sometimes referred to
* as a type code, that identifies the generic SQL type
* STRUCT
.
*
* @since JDK 1.2
*/
public static final int STRUCT = 2002;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* TIME
.
*/
public static final int TIME = 92;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* TIMESTAMP
.
*/
public static final int TIMESTAMP = 93;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* TINYINT
.
*/
public static final int TINYINT = -6;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* VARBINARY
.
*/
public static final int VARBINARY = -3;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the generic SQL type
* VARCHAR
.
*/
public static final int VARCHAR = 12;
/**
*
The constant in the Java programming language, sometimes referred
* to as a type code, that identifies the recent SQL 200n SQL type
*
*
* This method extends getTypeNr to return OTHER for
* primitive arrays, classes that directly implement
* java.io.Serializable and non-primitive arrays whose
* base component implements java.io.Serializable,
* allowing, for instance, arguments and return types of
* primitive arrays, Serializable objects and arrays,
* of Serializable objects. Direct primitive types
* other than those mapping directly to the internal
* wrapper form are not yet handled. That is, HSQLDB
* cannot yet properly deal with CALLs involving methods
* with primitive byte, short, float or their
* corresponding wrappers, due to the way internal
* conversion works and lack of detection and narrowing
* code in Function to allow this. In other words,
* passing in or retrieving any of the mentioned types
* always causes conversion to a wider internal wrapper
* which is genrally incompatible under reflective
* invocation, resulting in an IllegalArgumentException.
*
* @param c a Class instance
* @return java.sql.Types int value
* @throws HsqlException
*/
static int getParameterTypeNr(Class c) throws HsqlException {
String name;
int type;
if (c == null) {
Trace.doAssert(false, "c is null");
}
//TODO: void.class.equals(c)
//if (void.class.equals(c)) {
// return Types.NULL;
//}
if (illegalParameterClasses.contains(c)) {
throw Trace.error(Trace.WRONG_DATA_TYPE,
Trace.UNSUPPORTED_PARAM_CLASS, c.getName());
}
name = c.getName();
type = typeAliases.get(name, Integer.MIN_VALUE);
/*if (type == Integer.MIN_VALUE) {
// ensure all nested types are serializable
// byte[] is already covered as BINARY in typeAliases
if (c.isArray()) {
while (c.isArray()) {
c = c.getComponentType();
}
if (c.isPrimitive()
|| java.io.Serializable.class.isAssignableFrom(c)) {
type = OTHER;
}
} else if (java.io.Serializable.class.isAssignableFrom(c)) {
type = OTHER;
}
}*/
Trace.check(type != Integer.MIN_VALUE, Trace.WRONG_DATA_TYPE, name);
return type;
}
/*
static boolean areSimilar(int t1, int t2) {
if (t1 == t2) {
return true;
}
if (isNumberType(t1)) {
return isNumberType(t2);
}
if (isCharacterType(t1)) {
return isCharacterType(t2);
}
if (isBinaryType(t1)) {
return isBinaryType(t2);
}
return false;
}
static boolean haveSameInternalRepresentation(int t1, int t2) {
if (t1 == t2) {
return true;
}
if (isCharacterType(t1)) {
return isCharacterType(t2);
}
if (isBinaryType(t1)) {
return isBinaryType(t2);
}
switch (t1) {
case TINYINT :
case SMALLINT :
case INTEGER : {
switch (t2) {
case TINYINT :
case SMALLINT :
case INTEGER : {
return true;
}
default : {
return false;
}
}
}
case FLOAT :
case REAL :
case DOUBLE : {
switch (t2) {
case FLOAT :
case REAL :
case DOUBLE : {
return true;
}
default : {
return false;
}
}
}
case DECIMAL :
case NUMERIC : {
switch (t2) {
case DECIMAL :
case NUMERIC : {
return true;
}
default : {
return false;
}
}
}
default : {
return false;
}
}
}
static boolean isExactNumberType(int type) {
switch (type) {
case BIGINT :
case DECIMAL :
case INTEGER :
case NUMERIC :
case SMALLINT :
case TINYINT :
return true;
default :
return false;
}
}
static boolean isStrictlyIntegralNumberType(int type) {
switch (type) {
case BIGINT :
case INTEGER :
case SMALLINT :
case TINYINT :
return true;
default :
return false;
}
}
static boolean isApproximateNumberType(int type) {
switch (type) {
case DOUBLE :
case FLOAT :
case REAL :
return true;
default :
return false;
}
}
public static boolean isBinaryType(int type) {
switch (type) {
case BINARY :
case BLOB :
case LONGVARBINARY :
case VARBINARY :
return true;
default :
return false;
}
}
*/
static boolean isDatetimeType(int type) {
switch (type) {
case DATE :
case TIME :
case TIMESTAMP :
return true;
default :
return false;
}
}
/**
* Types that accept precition params in column definition or casts.
* We ignore the parameter in many cases but accept it for compatibility
* with other engines. CHAR, VARCHAR and VARCHAR_IGNORECASE params
* are used when the sql.enforce_strict_types is true.
*
*/
public static boolean acceptsPrecisionCreateParam(int type) {
switch (type) {
case BINARY :
case BLOB :
case CHAR :
case CLOB :
// case LONGVARBINARY :
// case LONGVARCHAR :
case VARBINARY :
case VARCHAR :
case VARCHAR_IGNORECASE :
case DECIMAL :
case NUMERIC :
case FLOAT :
case TIMESTAMP :
case TIME :
return true;
default :
return false;
}
}
public static int numericPrecisionCreateParamRadix(int type) {
switch (type) {
case Types.DECIMAL :
case Types.NUMERIC :
return 10;
case FLOAT :
return 2;
default :
// to mean NOT APPLICABLE (i.e. NULL)
return 0;
}
}
public static boolean acceptsScaleCreateParam(int type) {
switch (type) {
case Types.DECIMAL :
case Types.NUMERIC :
return true;
default :
return false;
}
}
public static boolean isNumberType(int type) {
switch (type) {
case BIGINT :
case DECIMAL :
case DOUBLE :
case FLOAT :
case INTEGER :
case NUMERIC :
case REAL :
case SMALLINT :
case TINYINT :
return true;
default :
return false;
}
}
public static boolean isCharacterType(int type) {
switch (type) {
case CHAR :
case CLOB :
case LONGVARCHAR :
case VARCHAR :
case VARCHAR_IGNORECASE :
return true;
default :
return false;
}
}
public static String getTypeName(int type) {
switch (type) {
case Types.ARRAY :
return "ARRAY";
case Types.BIGINT :
return "BIGINT";
case Types.BINARY :
return "BINARY";
case Types.BLOB :
return "BLOB";
case Types.BOOLEAN :
return "BOOLEAN";
case Types.CHAR :
return "CHAR";
case Types.CLOB :
return "CLOB";
case Types.DATALINK :
return "DATALINK";
case Types.DATE :
return "DATE";
case Types.DECIMAL :
return "DECIMAL";
case Types.DISTINCT :
return "DISTINCT";
case Types.DOUBLE :
return "DOUBLE";
case Types.FLOAT :
return "FLOAT";
case Types.INTEGER :
return "INTEGER";
case Types.JAVA_OBJECT :
return "JAVA_OBJECT";
case Types.LONGVARBINARY :
return "LONGVARBINARY";
case Types.LONGVARCHAR :
return "LONGVARCHAR";
case Types.NULL :
return "NULL";
case Types.NUMERIC :
return "NUMERIC";
case Types.OTHER :
return "OTHER";
case Types.REAL :
return "REAL";
case Types.REF :
return "REF";
case Types.SMALLINT :
return "SMALLINT";
case Types.STRUCT :
return "STRUCT";
case Types.TIME :
return "TIME";
case Types.TIMESTAMP :
return "TIMESTAMP";
case Types.TINYINT :
return "TINYINT";
case Types.VARBINARY :
return "VARBINARY";
case Types.VARCHAR :
return "VARCHAR";
case Types.VARCHAR_IGNORECASE :
return "VARCHAR_IGNORECASE";
case Types.XML :
return "XML";
default :
return null;
}
}
/**
* A reasonable/customizable number to avoid the shortcomings/defects
* associated with doing a dynamic scan of results to determine
* the value. In practice, it turns out that single query yielding
* widely varying values for display size of CHAR and VARCHAR columns
* on repeated execution results in patently poor usability, as some fairly
* high-profile, otherwise "enterprise-quality" RAD tools depend on
* on the first value returned to lay out forms and limit the size of
* single line edit controls, set corresponding local datastore storage
* sizes, etc. In practice, It also turns out that many tools (due to
* the original lack of PreparedStatement.getMetaData() in JDK 1.1) emulate
* a SQL_DESCRIBE by executing a query hopefully guaranteed to return no
* or very few rows for example: select ... from ... where 1=0.
* Using the dynamic scan of 1.7.2 RC5 and previous, therefore, the
* minimum display size value (1) was often being generated during
* a tool's describe phase. Upon subsequent "real" retrievals, some
* tools complain that CHAR and VARCHAR result values exceeded the
* originally reported display size and refused to fetch further values.
*/
public static final int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE =
MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE();
// So that the variable can be both public static final and
// customizable through system properties if required.
//
// 32766 (0x7ffe) seems to be a magic number over which several
// rather high-profile RAD tools start to have problems
// regarding layout and allocation stress. It is gently
// recommended that LONGVARCHAR be used for larger values in RAD
// tool layout & presentation use cases until such time as we provide
// true BLOB support (at which point, LONGVARCHAR will most likely become
// an alias for CLOB).
//
// Most GUI tools seem to handle LONGVARCHAR gracefully by:
//
// 1.) refusing to directly display such columns in graphical query results
// 2.) providing other means to retrieve and display such values
private static int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE() {
/* try {
return Integer.getInteger(
"hsqldb.max_char_or_varchar_display_size", 32766).intValue();
} catch (SecurityException e) {*/
return 32766;
//}
}
public static int getMaxDisplaySize(int type) {
switch (type) {
case Types.BINARY :
case Types.LONGVARBINARY :
case Types.LONGVARCHAR :
case Types.OTHER :
case Types.VARBINARY :
case Types.XML :
return Integer.MAX_VALUE; // max string length
case Types.CHAR :
case Types.VARCHAR :
return MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE;
case Types.BIGINT : // PowerBuilder barfs, wants 19
// ...not our problem, tho,
// according to JDBC
return 20; // precision + "-".length();
case Types.BOOLEAN :
return 5; // Math.max("true".length(),"false".length);
case Types.DATALINK :
return 20004; // same as precision
case Types.DECIMAL :
case Types.NUMERIC :
return 646456995; // precision + "-.".length()
case Types.DATE :
return 10; // same as precision
case Types.INTEGER :
return 11; // precision + "-".length();
case Types.FLOAT :
case Types.REAL :
case Types.DOUBLE :
return 23; // String.valueOf(-Double.MAX_VALUE).length();
case Types.TIME :
return 8; // same as precision
case Types.SMALLINT :
return 6; // precision + "-".length();
case Types.TIMESTAMP :
return 29; // same as precision
case Types.TINYINT :
return 4; // precision + "-".length();
default :
return 0; // unknown
}
}
public static boolean isSearchable(int type) {
switch (type) {
case Types.ARRAY :
case Types.BLOB :
case Types.CLOB :
case Types.JAVA_OBJECT :
case Types.STRUCT :
case Types.OTHER :
return false;
default :
return true;
}
}
public static Boolean isCaseSensitive(int type) {
switch (type) {
case Types.ARRAY :
case Types.BLOB :
case Types.CLOB :
case Types.DISTINCT :
case Types.JAVA_OBJECT :
case Types.NULL :
case Types.REF :
case Types.STRUCT :
return null;
case Types.CHAR :
case Types.VARCHAR :
case Types.DATALINK :
case Types.LONGVARCHAR :
case Types.OTHER :
case Types.XML :
return Boolean.TRUE;
case Types.VARCHAR_IGNORECASE :
default :
return Boolean.FALSE;
}
}
public static Boolean isUnsignedAttribute(int type) {
switch (type) {
case Types.BIGINT :
case Types.DECIMAL :
case Types.DOUBLE :
case Types.FLOAT :
case Types.INTEGER :
case Types.NUMERIC :
case Types.REAL :
case Types.SMALLINT :
case Types.TINYINT :
return Boolean.FALSE;
default :
return null;
}
}
public static int getPrecision(int type) {
switch (type) {
case Types.BINARY :
case Types.CHAR :
case Types.LONGVARBINARY :
case Types.LONGVARCHAR :
case Types.OTHER :
case Types.VARBINARY :
case Types.VARCHAR :
case Types.XML :
return Integer.MAX_VALUE;
case Types.BIGINT :
return 19;
case Types.BOOLEAN :
return 1;
case Types.DATALINK :
// from SQL CLI spec. TODO: Interpretation?
return 20004;
case Types.DECIMAL :
case Types.NUMERIC :
// Integer.MAX_VALUE bit 2's complement number:
// (Integer.MAX_VALUE-1) / ((ln(10)/ln(2)) bits per decimal digit)
// See: java.math.BigInteger
// - the other alternative is that we could report the numprecradix as 2 and
// report Integer.MAX_VALUE here
return 646456993;
case Types.DATE :
case Types.INTEGER :
return 10;
case Types.FLOAT :
case Types.REAL :
case Types.DOUBLE :
return 17;
case Types.TIME :
return 8;
case Types.SMALLINT :
return 5;
case Types.TIMESTAMP :
return 29;
case Types.TINYINT :
return 3;
default :
return 0;
}
}
public static String getColStClsName(int type) {
switch (type) {
case Types.BIGINT :
return "java.lang.Long";
case Types.BINARY :
case Types.LONGVARBINARY :
case Types.VARBINARY :
// but wrapped by org.hsqldb.Binary
return "[B";
case Types.OTHER :
// but wrapped by org.hsqldb.JavaObject
return "java.lang.Object";
case Types.BOOLEAN :
return "java.lang.Boolean";
case Types.CHAR :
case Types.LONGVARCHAR :
case Types.VARCHAR :
case Types.XML : //?
return "java.lang.String";
case Types.DATALINK :
return "java.net.URL";
case Types.DATE :
return DateClassName;
case Types.DECIMAL :
case Types.NUMERIC :
return DecimalClassName;
case Types.DOUBLE :
case Types.FLOAT :
case Types.REAL :
return "java.lang.Double";
case Types.INTEGER :
case Types.SMALLINT :
case Types.TINYINT :
return "java.lang.Integer";
case Types.TIME :
return TimeClassName;
case Types.TIMESTAMP :
return TimestampClassName;
default :
return null;
}
}
}
XML
.
*
* @since SQL 200n
*/
public static final int XML = 137;
/**
* The default HSQLODB type sub-identifier. This indicates that an
* HSQLDB type with this sub-type, if supported, is the very closest
* thing HSQLDB offerers to the JDBC/SQL200n type
*/
public static final int TYPE_SUB_DEFAULT = 1;
/**
* The IGNORECASE type sub-identifier. This indicates that an HSQLDB type
* with this sub-type, if supported, is the closest thing HSQLDB offerers
* to the JDBC/SQL200n type, except that case is ignored in comparisons
*/
public static final int TYPE_SUB_IGNORECASE = TYPE_SUB_DEFAULT << 2;
/**
* Every (type,type-sub) combination known in the HSQLDB context.
* Not every combination need be supported as a table or procedure
* column type -- such determinations are handled in DITypeInfo.
*/
static final int[][] ALL_TYPES = {
{
ARRAY, TYPE_SUB_DEFAULT
}, {
BIGINT, TYPE_SUB_DEFAULT
}, {
BINARY, TYPE_SUB_DEFAULT
}, {
BLOB, TYPE_SUB_DEFAULT
}, {
BOOLEAN, TYPE_SUB_DEFAULT
}, {
CHAR, TYPE_SUB_DEFAULT
}, {
CLOB, TYPE_SUB_DEFAULT
}, {
DATALINK, TYPE_SUB_DEFAULT
}, {
DATE, TYPE_SUB_DEFAULT
}, {
DECIMAL, TYPE_SUB_DEFAULT
}, {
DISTINCT, TYPE_SUB_DEFAULT
}, {
DOUBLE, TYPE_SUB_DEFAULT
}, {
FLOAT, TYPE_SUB_DEFAULT
}, {
INTEGER, TYPE_SUB_DEFAULT
}, {
JAVA_OBJECT, TYPE_SUB_DEFAULT
}, {
LONGVARBINARY, TYPE_SUB_DEFAULT
}, {
LONGVARCHAR, TYPE_SUB_DEFAULT
}, {
NULL, TYPE_SUB_DEFAULT
}, {
NUMERIC, TYPE_SUB_DEFAULT
}, {
OTHER, TYPE_SUB_DEFAULT
}, {
REAL, TYPE_SUB_DEFAULT
}, {
REF, TYPE_SUB_DEFAULT
}, {
SMALLINT, TYPE_SUB_DEFAULT
}, {
STRUCT, TYPE_SUB_DEFAULT
}, {
TIME, TYPE_SUB_DEFAULT
}, {
TIMESTAMP, TYPE_SUB_DEFAULT
}, {
TINYINT, TYPE_SUB_DEFAULT
}, {
VARBINARY, TYPE_SUB_DEFAULT
}, {
VARCHAR, TYPE_SUB_DEFAULT
}, {
VARCHAR, TYPE_SUB_IGNORECASE
}, {
XML, TYPE_SUB_DEFAULT
}
};
/*
SQL specifies predefined data types named by the following