0001: /* Copyright (c) 2001-2005, The HSQL Development Group
0002: * All rights reserved.
0003: *
0004: * Redistribution and use in source and binary forms, with or without
0005: * modification, are permitted provided that the following conditions are met:
0006: *
0007: * Redistributions of source code must retain the above copyright notice, this
0008: * list of conditions and the following disclaimer.
0009: *
0010: * Redistributions in binary form must reproduce the above copyright notice,
0011: * this list of conditions and the following disclaimer in the documentation
0012: * and/or other materials provided with the distribution.
0013: *
0014: * Neither the name of the HSQL Development Group nor the names of its
0015: * contributors may be used to endorse or promote products derived from this
0016: * software without specific prior written permission.
0017: *
0018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
0022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
0025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
0026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
0028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0029: */
0030:
0031: package org.hsqldb;
0032:
0033: import org.hsqldb.lib.IntKeyHashMap;
0034: import org.hsqldb.lib.IntValueHashMap;
0035: import org.hsqldb.lib.HashMap;
0036:
0037: /**
0038: * Defines the constants that are used to identify SQL types for HSQLDB JDBC
0039: * inteface type reporting. The actual type constant values are equivalent
0040: * to those defined in the latest java.sql.Types, where available,
0041: * or those defined by ansi/iso SQL 200n otherwise. A type sub-identifer
0042: * has been added to differentiate HSQLDB-specific type specializations.
0043: *
0044: * @author boucherb@users
0045: * @version 1.7.2
0046: * @since 1.7.2
0047: */
0048: public class Types {
0049:
0050: /**
0051: * Names of types.
0052: * Used for external, JDBC reporting
0053: * Used for library and user function arguments
0054: */
0055: public static final String DecimalClassName = "java.math.BigDecimal";
0056: public static final String DateClassName = "java.sql.Date";
0057: public static final String TimeClassName = "java.sql.Time";
0058: public static final String TimestampClassName = "java.sql.Timestamp";
0059:
0060: /**
0061: * The constant in the Java programming language, sometimes referred to
0062: * as a type code, that identifies the generic SQL type
0063: * <code>ARRAY</code>.
0064: *
0065: * @since JDK 1.2
0066: */
0067: public static final int ARRAY = 2003;
0068:
0069: /**
0070: * <P>The constant in the Java programming language, sometimes referred
0071: * to as a type code, that identifies the generic SQL type
0072: * <code>BIGINT</code>.
0073: */
0074: public static final int BIGINT = -5;
0075:
0076: /**
0077: * <P>The constant in the Java programming language, sometimes referred
0078: * to as a type code, that identifies the generic SQL type
0079: * <code>BINARY</code>.
0080: */
0081: public static final int BINARY = -2;
0082:
0083: /**
0084: * The constant in the Java programming language, sometimes referred to
0085: * as a type code, that identifies the generic SQL type
0086: * <code>BLOB</code>.
0087: *
0088: * @since JDK 1.2
0089: */
0090: public static final int BLOB = 2004;
0091:
0092: /**
0093: * The constant in the Java programming language, somtimes referred to
0094: * as a type code, that identifies the generic SQL type
0095: * <code>BOOLEAN</code>.
0096: *
0097: * @since JDK 1.4
0098: */
0099: public static final int BOOLEAN = 16;
0100:
0101: /**
0102: * <P>The constant in the Java programming language, sometimes referred
0103: * to as a type code, that identifies the generic SQL type
0104: * <code>CHAR</code>.
0105: */
0106: public static final int CHAR = 1;
0107:
0108: /**
0109: * The constant in the Java programming language, sometimes referred to
0110: * as a type code, that identifies the generic SQL type
0111: * <code>CLOB</code>
0112: *
0113: * @since JDK 1.2
0114: */
0115: public static final int CLOB = 2005;
0116:
0117: /**
0118: * The constant in the Java programming language, somtimes referred to
0119: * as a type code, that identifies the generic SQL type <code>DATALINK</code>.
0120: *
0121: * @since JDK 1.4
0122: */
0123: public static final int DATALINK = 70;
0124:
0125: /**
0126: * <P>The constant in the Java programming language, sometimes referred
0127: * to as a type code, that identifies the generic SQL type
0128: * <code>DATE</code>.
0129: */
0130: public static final int DATE = 91;
0131:
0132: /**
0133: * <P>The constant in the Java programming language, sometimes referred
0134: * to as a type code, that identifies the generic SQL type
0135: * <code>DECIMAL</code>.
0136: */
0137: public static final int DECIMAL = 3;
0138:
0139: /**
0140: * The constant in the Java programming language, sometimes referred to
0141: * as a type code, that identifies the generic SQL type
0142: * <code>DISTINCT</code>.
0143: *
0144: * @since JDK 1.2
0145: */
0146: public static final int DISTINCT = 2001;
0147:
0148: /**
0149: * <P>The constant in the Java programming language, sometimes referred
0150: * to as a type code, that identifies the generic SQL type
0151: * <code>DOUBLE</code>.
0152: */
0153: public static final int DOUBLE = 8;
0154:
0155: /**
0156: * <P>The constant in the Java programming language, sometimes referred
0157: * to as a type code, that identifies the generic SQL type
0158: * <code>FLOAT</code>.
0159: */
0160: public static final int FLOAT = 6;
0161:
0162: /**
0163: * <P>The constant in the Java programming language, sometimes referred
0164: * to as a type code, that identifies the generic SQL type
0165: * <code>INTEGER</code>.
0166: */
0167: public static final int INTEGER = 4;
0168:
0169: /**
0170: * The constant in the Java programming language, sometimes referred to
0171: * as a type code, that identifies the generic SQL type
0172: * <code>JAVA_OBJECT</code>.
0173: *
0174: * @since JDK 1.2
0175: */
0176: public static final int JAVA_OBJECT = 2000;
0177:
0178: /**
0179: * <P>The constant in the Java programming language, sometimes referred
0180: * to as a type code, that identifies the generic SQL type
0181: * <code>LONGVARBINARY</code>.
0182: */
0183: public static final int LONGVARBINARY = -4;
0184:
0185: /**
0186: * <P>The constant in the Java programming language, sometimes referred
0187: * to as a type code, that identifies the generic SQL type
0188: * <code>LONGVARCHAR</code>.
0189: */
0190: public static final int LONGVARCHAR = -1;
0191:
0192: /**
0193: * <P>The constant in the Java programming language, sometimes referred
0194: * to as a type code, that identifies the generic SQL type
0195: * <code>NULL</code>.
0196: */
0197: public static final int NULL = 0;
0198:
0199: /**
0200: * <P>The constant in the Java programming language, sometimes referred
0201: * to as a type code, that identifies the generic SQL type
0202: * <code>NUMERIC</code>.
0203: */
0204: public static final int NUMERIC = 2;
0205:
0206: /**
0207: * The constant in the Java programming language that indicates
0208: * that the SQL type is database-specific and
0209: * gets mapped to a Java object that can be accessed via
0210: * the methods <code>getObject</code> and <code>setObject</code>.
0211: */
0212: public static final int OTHER = 1111;
0213:
0214: /**
0215: * <P>The constant in the Java programming language, sometimes referred
0216: * to as a type code, that identifies the generic SQL type
0217: * <code>REAL</code>.
0218: */
0219: public static final int REAL = 7;
0220:
0221: /**
0222: * The constant in the Java programming language, sometimes referred to
0223: * as a type code, that identifies the generic SQL type
0224: * <code>REF</code>.
0225: *
0226: * @since JDK 1.2
0227: */
0228: public static final int REF = 2006;
0229:
0230: /**
0231: * <P>The constant in the Java programming language, sometimes referred
0232: * to as a type code, that identifies the generic SQL type
0233: * <code>SMALLINT</code>.
0234: */
0235: public static final int SMALLINT = 5;
0236:
0237: /**
0238: * The constant in the Java programming language, sometimes referred to
0239: * as a type code, that identifies the generic SQL type
0240: * <code>STRUCT</code>.
0241: *
0242: * @since JDK 1.2
0243: */
0244: public static final int STRUCT = 2002;
0245:
0246: /**
0247: * <P>The constant in the Java programming language, sometimes referred
0248: * to as a type code, that identifies the generic SQL type
0249: * <code>TIME</code>.
0250: */
0251: public static final int TIME = 92;
0252:
0253: /**
0254: * <P>The constant in the Java programming language, sometimes referred
0255: * to as a type code, that identifies the generic SQL type
0256: * <code>TIMESTAMP</code>.
0257: */
0258: public static final int TIMESTAMP = 93;
0259:
0260: /**
0261: * <P>The constant in the Java programming language, sometimes referred
0262: * to as a type code, that identifies the generic SQL type
0263: * <code>TINYINT</code>.
0264: */
0265: public static final int TINYINT = -6;
0266:
0267: /**
0268: * <P>The constant in the Java programming language, sometimes referred
0269: * to as a type code, that identifies the generic SQL type
0270: * <code>VARBINARY</code>.
0271: */
0272: public static final int VARBINARY = -3;
0273:
0274: /**
0275: * <P>The constant in the Java programming language, sometimes referred
0276: * to as a type code, that identifies the generic SQL type
0277: * <code>VARCHAR</code>.
0278: */
0279: public static final int VARCHAR = 12;
0280:
0281: /**
0282: * <P>The constant in the Java programming language, sometimes referred
0283: * to as a type code, that identifies the recent SQL 200n SQL type
0284: * <code>XML</code>.
0285: *
0286: * @since SQL 200n
0287: */
0288: public static final int XML = 137;
0289:
0290: /**
0291: * The default HSQLODB type sub-identifier. This indicates that an
0292: * HSQLDB type with this sub-type, if supported, is the very closest
0293: * thing HSQLDB offerers to the JDBC/SQL200n type
0294: */
0295: public static final int TYPE_SUB_DEFAULT = 1;
0296:
0297: /**
0298: * The IGNORECASE type sub-identifier. This indicates that an HSQLDB type
0299: * with this sub-type, if supported, is the closest thing HSQLDB offerers
0300: * to the JDBC/SQL200n type, except that case is ignored in comparisons
0301: */
0302: public static final int TYPE_SUB_IGNORECASE = TYPE_SUB_DEFAULT << 2;
0303:
0304: /**
0305: * Every (type,type-sub) combination known in the HSQLDB context.
0306: * Not every combination need be supported as a table or procedure
0307: * column type -- such determinations are handled in DITypeInfo.
0308: */
0309: static final int[][] ALL_TYPES = { { ARRAY, TYPE_SUB_DEFAULT },
0310: { BIGINT, TYPE_SUB_DEFAULT }, { BINARY, TYPE_SUB_DEFAULT },
0311: { BLOB, TYPE_SUB_DEFAULT }, { BOOLEAN, TYPE_SUB_DEFAULT },
0312: { CHAR, TYPE_SUB_DEFAULT }, { CLOB, TYPE_SUB_DEFAULT },
0313: { DATALINK, TYPE_SUB_DEFAULT }, { DATE, TYPE_SUB_DEFAULT },
0314: { DECIMAL, TYPE_SUB_DEFAULT },
0315: { DISTINCT, TYPE_SUB_DEFAULT },
0316: { DOUBLE, TYPE_SUB_DEFAULT }, { FLOAT, TYPE_SUB_DEFAULT },
0317: { INTEGER, TYPE_SUB_DEFAULT },
0318: { JAVA_OBJECT, TYPE_SUB_DEFAULT },
0319: { LONGVARBINARY, TYPE_SUB_DEFAULT },
0320: { LONGVARCHAR, TYPE_SUB_DEFAULT },
0321: { NULL, TYPE_SUB_DEFAULT }, { NUMERIC, TYPE_SUB_DEFAULT },
0322: { OTHER, TYPE_SUB_DEFAULT }, { REAL, TYPE_SUB_DEFAULT },
0323: { REF, TYPE_SUB_DEFAULT }, { SMALLINT, TYPE_SUB_DEFAULT },
0324: { STRUCT, TYPE_SUB_DEFAULT }, { TIME, TYPE_SUB_DEFAULT },
0325: { TIMESTAMP, TYPE_SUB_DEFAULT },
0326: { TINYINT, TYPE_SUB_DEFAULT },
0327: { VARBINARY, TYPE_SUB_DEFAULT },
0328: { VARCHAR, TYPE_SUB_DEFAULT },
0329: { VARCHAR, TYPE_SUB_IGNORECASE }, { XML, TYPE_SUB_DEFAULT } };
0330: /*
0331: SQL specifies predefined data types named by the following <key word>s:
0332: CHARACTER, CHARACTER VARYING, CHARACTER LARGE OBJECT, BINARY LARGE OBJECT,
0333: NUMERIC, DECIMAL, SMALLINT, INTEGER, BIGINT, FLOAT, REAL, DOUBLE PRECISION,
0334: BOOLEAN, DATE, TIME, TIMESTAMP, and INTERVAL.
0335: SQL 200n adds DATALINK in Part 9: Management of External Data (SQL/MED)
0336: and adds XML in Part 14: XML-Related Specifications (SQL/XML)
0337: */
0338:
0339: // CLI type list from Table 37
0340: static final int SQL_CHARACTER = 1;
0341: static final int SQL_CHAR = 1;
0342: static final int SQL_NUMERIC = 2;
0343: static final int SQL_DECIMAL = 3;
0344: static final int SQL_DEC = 3;
0345: static final int SQL_INTEGER = 4;
0346: static final int SQL_INT = 4;
0347: static final int SQL_SMALLINT = 5;
0348: static final int SQL_FLOAT = 6;
0349: static final int SQL_REAL = 7;
0350: static final int SQL_DOUBLE = 8;
0351: static final int SQL_CHARACTER_VARYING = 12;
0352: static final int SQL_CHAR_VARYING = 12;
0353: static final int SQL_VARCHAR = 12;
0354: static final int SQL_BOOLEAN = 16;
0355: static final int SQL_USER_DEFINED_TYPE = 17;
0356: static final int SQL_ROW = 19;
0357: static final int SQL_REF = 20;
0358: static final int SQL_BIGINT = 25;
0359: static final int SQL_BINARY_LARGE_OBJECT = 30;
0360: static final int SQL_BLOB = 30;
0361: static final int SQL_CHARACTER_LARGE_OBJECT = 40;
0362: static final int SQL_CLOB = 40;
0363: static final int SQL_ARRAY = 50; // not predefined
0364: static final int SQL_MULTISET = 55; //
0365: static final int SQL_DATE = 91;
0366: static final int SQL_TIME = 92;
0367: static final int SQL_TIMESTAMP = 93; //
0368: static final int SQL_TIME_WITH_TIME_ZONE = 94;
0369: static final int SQL_TIMESTAMP_WITH_TIME_ZONE = 95; //
0370: static final int SQL_INTERVAL_YEAR = 101; //
0371: static final int SQL_INTERVAL_MONTH = 102;
0372: static final int SQL_INTERVAL_DAY = 103;
0373: static final int SQL_INTERVAL_HOUR = 104;
0374: static final int SQL_INTERVAL_MINUTE = 105;
0375: static final int SQL_INTERVAL_SECOND = 106;
0376: static final int SQL_INTERVAL_YEAR_TO_MONTH = 107;
0377: static final int SQL_INTERVAL_DAY_TO_HOUR = 108;
0378: static final int SQL_INTERVAL_DAY_TO_MINUTE = 109;
0379: static final int SQL_INTERVAL_DAY_TO_SECOND = 110;
0380: static final int SQL_INTERVAL_HOUR_TO_MINUTE = 111;
0381: static final int SQL_INTERVAL_HOUR_TO_SECOND = 112;
0382: static final int SQL_INTERVAL_MINUTE_TO_SECOND = 113;
0383:
0384: // These values are not in table 37 of the SQL CLI 200n FCD, but some
0385: // are found in tables 6-9 and some are found in Annex A1:
0386: // c Header File SQLCLI.H and/or addendums in other documents,
0387: // such as:
0388: // SQL 200n Part 9: Management of External Data (SQL/MED) : DATALINK
0389: // SQL 200n Part 14: XML-Related Specifications (SQL/XML) : XML
0390: static final int SQL_BIT_VARYING = 15; // is in SQL99 but removed from 200n
0391: static final int SQL_DATALINK = 70;
0392: static final int SQL_UDT = 17;
0393: static final int SQL_UDT_LOCATOR = 18;
0394: static final int SQL_BLOB_LOCATOR = 31;
0395: static final int SQL_CLOB_LOCATOR = 41;
0396: static final int SQL_ARRAY_LOCATOR = 51;
0397: static final int SQL_MULTISET_LOCATOR = 56;
0398: static final int SQL_ALL_TYPES = 0;
0399: static final int SQL_DATETIME = 9; // collective name
0400: static final int SQL_INTERVAL = 10; // collective name
0401: static final int SQL_XML = 137;
0402:
0403: // SQL_UDT subcodes
0404: static final int SQL_DISTINCT = 1;
0405: static final int SQL_SCTRUCTURED = 2;
0406:
0407: // non-standard type not in JDBC or SQL CLI
0408: public static final int VARCHAR_IGNORECASE = 100;
0409:
0410: // lookup for types
0411: // boucherb@users - access changed for metadata 1.7.2
0412: static IntValueHashMap typeAliases;
0413: static IntKeyHashMap typeNames;
0414: static HashMap javaTypeNames;
0415:
0416: // boucherb@users - We can't handle method invocations in
0417: // Function.java or user-defined methods whose parameters
0418: // number class is
0419: // narrower than the corresponding internal
0420: // wrapper
0421: private static org.hsqldb.lib.HashSet illegalParameterClasses;
0422:
0423: static {
0424: typeAliases = new IntValueHashMap(50);
0425:
0426: typeAliases.put("INTEGER", Types.INTEGER);
0427: typeAliases.put("INT", Types.INTEGER);
0428: typeAliases.put("int", Types.INTEGER);
0429: typeAliases.put("java.lang.Integer", Types.INTEGER);
0430: typeAliases.put("IDENTITY", Types.INTEGER);
0431: typeAliases.put("DOUBLE", Types.DOUBLE);
0432: typeAliases.put("double", Types.DOUBLE);
0433: typeAliases.put("java.lang.Double", Types.DOUBLE);
0434: typeAliases.put("FLOAT", Types.FLOAT);
0435: typeAliases.put("REAL", Types.REAL);
0436: typeAliases.put("VARCHAR", Types.VARCHAR);
0437: typeAliases.put("java.lang.String", Types.VARCHAR);
0438: typeAliases.put("CHAR", Types.CHAR);
0439: typeAliases.put("CHARACTER", Types.CHAR);
0440: typeAliases.put("LONGVARCHAR", Types.LONGVARCHAR);
0441: typeAliases.put("VARCHAR_IGNORECASE", VARCHAR_IGNORECASE);
0442: typeAliases.put("DATE", Types.DATE);
0443: typeAliases.put(DateClassName, Types.DATE);
0444: typeAliases.put("TIME", Types.TIME);
0445: typeAliases.put(TimeClassName, Types.TIME);
0446: typeAliases.put("TIMESTAMP", Types.TIMESTAMP);
0447: typeAliases.put(TimestampClassName, Types.TIMESTAMP);
0448: typeAliases.put("DATETIME", Types.TIMESTAMP);
0449: typeAliases.put("DECIMAL", Types.DECIMAL);
0450: typeAliases.put(DecimalClassName, Types.DECIMAL);
0451: typeAliases.put("NUMERIC", Types.NUMERIC);
0452: typeAliases.put("BIT", Types.BOOLEAN);
0453: typeAliases.put("BOOLEAN", Types.BOOLEAN);
0454: typeAliases.put("boolean", Types.BOOLEAN);
0455: typeAliases.put("java.lang.Boolean", Types.BOOLEAN);
0456: typeAliases.put("TINYINT", Types.TINYINT);
0457: typeAliases.put("byte", Types.TINYINT);
0458: typeAliases.put("java.lang.Byte", Types.TINYINT);
0459: typeAliases.put("SMALLINT", Types.SMALLINT);
0460: typeAliases.put("short", Types.SMALLINT);
0461: typeAliases.put("java.lang.Short", Types.SMALLINT);
0462: typeAliases.put("BIGINT", Types.BIGINT);
0463: typeAliases.put("long", Types.BIGINT);
0464: typeAliases.put("java.lang.Long", Types.BIGINT);
0465: typeAliases.put("BINARY", Types.BINARY);
0466: typeAliases.put("[B", Types.BINARY);
0467: typeAliases.put("VARBINARY", Types.VARBINARY);
0468: typeAliases.put("LONGVARBINARY", Types.LONGVARBINARY);
0469: typeAliases.put("OTHER", Types.OTHER);
0470: typeAliases.put("OBJECT", Types.OTHER);
0471: typeAliases.put("java.lang.Object", Types.OTHER);
0472: typeAliases.put("NULL", Types.NULL);
0473: typeAliases.put("void", Types.NULL);
0474: typeAliases.put("java.lang.Void", Types.NULL);
0475:
0476: //
0477: typeNames = new IntKeyHashMap();
0478:
0479: typeNames.put(Types.NULL, "NULL");
0480: typeNames.put(Types.INTEGER, "INTEGER");
0481: typeNames.put(Types.DOUBLE, "DOUBLE");
0482: typeNames.put(VARCHAR_IGNORECASE, "VARCHAR_IGNORECASE");
0483: typeNames.put(Types.VARCHAR, "VARCHAR");
0484: typeNames.put(Types.CHAR, "CHAR");
0485: typeNames.put(Types.LONGVARCHAR, "LONGVARCHAR");
0486: typeNames.put(Types.DATE, "DATE");
0487: typeNames.put(Types.TIME, "TIME");
0488: typeNames.put(Types.DECIMAL, "DECIMAL");
0489: typeNames.put(Types.BOOLEAN, "BOOLEAN");
0490: typeNames.put(Types.TINYINT, "TINYINT");
0491: typeNames.put(Types.SMALLINT, "SMALLINT");
0492: typeNames.put(Types.BIGINT, "BIGINT");
0493: typeNames.put(Types.REAL, "REAL");
0494: typeNames.put(Types.FLOAT, "FLOAT");
0495: typeNames.put(Types.NUMERIC, "NUMERIC");
0496: typeNames.put(Types.TIMESTAMP, "TIMESTAMP");
0497: typeNames.put(Types.BINARY, "BINARY");
0498: typeNames.put(Types.VARBINARY, "VARBINARY");
0499: typeNames.put(Types.LONGVARBINARY, "LONGVARBINARY");
0500: typeNames.put(Types.OTHER, "OBJECT");
0501:
0502: //
0503: illegalParameterClasses = new org.hsqldb.lib.HashSet();
0504:
0505: illegalParameterClasses.add(Byte.TYPE);
0506: illegalParameterClasses.add(Short.TYPE);
0507: illegalParameterClasses.add(Float.TYPE);
0508: illegalParameterClasses.add(Byte.class);
0509: illegalParameterClasses.add(Short.class);
0510: illegalParameterClasses.add(Float.class);
0511:
0512: //
0513: javaTypeNames = new HashMap();
0514:
0515: javaTypeNames.put(DateClassName, "java.sql.Date");
0516: javaTypeNames.put(TimeClassName, "java.sql.Time");
0517: javaTypeNames.put(TimestampClassName, "java.sql.Timestamp");
0518: javaTypeNames.put(DecimalClassName, "java.math.BigDecimal");
0519: javaTypeNames.put("byte", "java.lang.Integer");
0520: javaTypeNames.put("java.lang.Byte", "java.lang.Integer");
0521: javaTypeNames.put("short", "java.lang.Integer");
0522: javaTypeNames.put("java.lang.Short", "java.lang.Integer");
0523: javaTypeNames.put("int", "java.lang.Integer");
0524: javaTypeNames.put("java.lang.Integer", "java.lang.Integer");
0525: javaTypeNames.put("long", "java.lang.Long");
0526: javaTypeNames.put("java.lang.Long", "java.lang.Long");
0527: javaTypeNames.put("double", "java.lang.Double");
0528: javaTypeNames.put("java.lang.Double", "java.lang.Double");
0529: javaTypeNames.put("boolean", "java.lang.Boolean");
0530: javaTypeNames.put("java.lang.Boolean", "java.lang.Boolean");
0531: javaTypeNames.put("java.lang.String", "java.lang.String");
0532: javaTypeNames.put("void", "java.lang.Void");
0533: javaTypeNames.put("[B", "[B");
0534: }
0535:
0536: /**
0537: * Translates a type name returned from a method into the name of type
0538: * returned in a ResultSet
0539: */
0540: static String getFunctionReturnClassName(String methodReturnType) {
0541:
0542: String name = (String) javaTypeNames.get(methodReturnType);
0543:
0544: return name == null ? methodReturnType : name;
0545: }
0546:
0547: /**
0548: * `
0549: *
0550: * @param type string
0551: * @return java.sql.Types int value
0552: * @throws HsqlException
0553: */
0554: static int getTypeNr(String type) throws HsqlException {
0555:
0556: int i = typeAliases.get(type, Integer.MIN_VALUE);
0557:
0558: Trace
0559: .check(i != Integer.MIN_VALUE, Trace.WRONG_DATA_TYPE,
0560: type);
0561:
0562: return i;
0563: }
0564:
0565: /**
0566: * Returns SQL type string for a java.sql.Types int value
0567: */
0568: public static String getTypeString(int type) {
0569: return (String) typeNames.get(type);
0570: }
0571:
0572: /**
0573: * Returns SQL type string for a java.sql.Types int value
0574: */
0575: public static String getTypeString(int type, int precision,
0576: int scale) {
0577:
0578: String s = (String) typeNames.get(type);
0579:
0580: if (precision != 0 && acceptsPrecisionCreateParam(type)) {
0581: StringBuffer sb = new StringBuffer(s);
0582:
0583: sb.append(Token.T_OPENBRACKET);
0584: sb.append(precision);
0585:
0586: if (scale != 0 && acceptsScaleCreateParam(type)) {
0587: sb.append(Token.T_COMMA);
0588: sb.append(scale);
0589: }
0590:
0591: sb.append(Token.T_CLOSEBRACKET);
0592:
0593: return sb.toString();
0594: }
0595:
0596: return s;
0597: }
0598:
0599: /**
0600: * Retieves the type number corresponding to the class
0601: * of an IN, IN OUT or OUT parameter. <p>
0602: *
0603: * This method extends getTypeNr to return OTHER for
0604: * primitive arrays, classes that directly implement
0605: * java.io.Serializable and non-primitive arrays whose
0606: * base component implements java.io.Serializable,
0607: * allowing, for instance, arguments and return types of
0608: * primitive arrays, Serializable objects and arrays,
0609: * of Serializable objects. Direct primitive types
0610: * other than those mapping directly to the internal
0611: * wrapper form are not yet handled. That is, HSQLDB
0612: * cannot yet properly deal with CALLs involving methods
0613: * with primitive byte, short, float or their
0614: * corresponding wrappers, due to the way internal
0615: * conversion works and lack of detection and narrowing
0616: * code in Function to allow this. In other words,
0617: * passing in or retrieving any of the mentioned types
0618: * always causes conversion to a wider internal wrapper
0619: * which is genrally incompatible under reflective
0620: * invocation, resulting in an IllegalArgumentException.
0621: *
0622: * @param c a Class instance
0623: * @return java.sql.Types int value
0624: * @throws HsqlException
0625: */
0626: static int getParameterTypeNr(Class c) throws HsqlException {
0627:
0628: String name;
0629: int type;
0630:
0631: if (c == null) {
0632: Trace.doAssert(false, "c is null");
0633: }
0634:
0635: if (Void.TYPE.equals(c)) {
0636: return Types.NULL;
0637: }
0638:
0639: if (illegalParameterClasses.contains(c)) {
0640: throw Trace.error(Trace.WRONG_DATA_TYPE,
0641: Trace.UNSUPPORTED_PARAM_CLASS, c.getName());
0642: }
0643:
0644: name = c.getName();
0645: type = typeAliases.get(name, Integer.MIN_VALUE);
0646:
0647: if (type == Integer.MIN_VALUE) {
0648:
0649: // ensure all nested types are serializable
0650: // byte[] is already covered as BINARY in typeAliases
0651: if (c.isArray()) {
0652: while (c.isArray()) {
0653: c = c.getComponentType();
0654: }
0655:
0656: if (c.isPrimitive()
0657: || java.io.Serializable.class
0658: .isAssignableFrom(c)) {
0659: type = OTHER;
0660: }
0661: } else if (java.io.Serializable.class.isAssignableFrom(c)) {
0662: type = OTHER;
0663: }
0664: }
0665:
0666: Trace.check(type != Integer.MIN_VALUE, Trace.WRONG_DATA_TYPE,
0667: name);
0668:
0669: return type;
0670: }
0671:
0672: /*
0673: static boolean areSimilar(int t1, int t2) {
0674:
0675: if (t1 == t2) {
0676: return true;
0677: }
0678:
0679: if (isNumberType(t1)) {
0680: return isNumberType(t2);
0681: }
0682:
0683: if (isCharacterType(t1)) {
0684: return isCharacterType(t2);
0685: }
0686:
0687: if (isBinaryType(t1)) {
0688: return isBinaryType(t2);
0689: }
0690:
0691: return false;
0692: }
0693:
0694: static boolean haveSameInternalRepresentation(int t1, int t2) {
0695:
0696: if (t1 == t2) {
0697: return true;
0698: }
0699:
0700: if (isCharacterType(t1)) {
0701: return isCharacterType(t2);
0702: }
0703:
0704: if (isBinaryType(t1)) {
0705: return isBinaryType(t2);
0706: }
0707:
0708: switch (t1) {
0709:
0710: case TINYINT :
0711: case SMALLINT :
0712: case INTEGER : {
0713: switch (t2) {
0714:
0715: case TINYINT :
0716: case SMALLINT :
0717: case INTEGER : {
0718: return true;
0719: }
0720: default : {
0721: return false;
0722: }
0723: }
0724: }
0725: case FLOAT :
0726: case REAL :
0727: case DOUBLE : {
0728: switch (t2) {
0729:
0730: case FLOAT :
0731: case REAL :
0732: case DOUBLE : {
0733: return true;
0734: }
0735: default : {
0736: return false;
0737: }
0738: }
0739: }
0740: case DECIMAL :
0741: case NUMERIC : {
0742: switch (t2) {
0743:
0744: case DECIMAL :
0745: case NUMERIC : {
0746: return true;
0747: }
0748: default : {
0749: return false;
0750: }
0751: }
0752: }
0753: default : {
0754: return false;
0755: }
0756: }
0757: }
0758:
0759: static boolean isExactNumberType(int type) {
0760:
0761: switch (type) {
0762:
0763: case BIGINT :
0764: case DECIMAL :
0765: case INTEGER :
0766: case NUMERIC :
0767: case SMALLINT :
0768: case TINYINT :
0769: return true;
0770:
0771: default :
0772: return false;
0773: }
0774: }
0775:
0776: static boolean isStrictlyIntegralNumberType(int type) {
0777:
0778: switch (type) {
0779:
0780: case BIGINT :
0781: case INTEGER :
0782: case SMALLINT :
0783: case TINYINT :
0784: return true;
0785:
0786: default :
0787: return false;
0788: }
0789: }
0790:
0791: static boolean isApproximateNumberType(int type) {
0792:
0793: switch (type) {
0794:
0795: case DOUBLE :
0796: case FLOAT :
0797: case REAL :
0798: return true;
0799:
0800: default :
0801: return false;
0802: }
0803: }
0804:
0805: public static boolean isBinaryType(int type) {
0806:
0807: switch (type) {
0808:
0809: case BINARY :
0810:
0811: case BLOB :
0812: case LONGVARBINARY :
0813: case VARBINARY :
0814: return true;
0815:
0816: default :
0817: return false;
0818: }
0819: }
0820:
0821: */
0822: static boolean isDatetimeType(int type) {
0823:
0824: switch (type) {
0825:
0826: case DATE:
0827: case TIME:
0828: case TIMESTAMP:
0829: return true;
0830:
0831: default:
0832: return false;
0833: }
0834: }
0835:
0836: /**
0837: * Types that accept precition params in column definition or casts.
0838: * We ignore the parameter in many cases but accept it for compatibility
0839: * with other engines. CHAR, VARCHAR and VARCHAR_IGNORECASE params
0840: * are used when the sql.enforce_strict_types is true.
0841: *
0842: */
0843: public static boolean acceptsPrecisionCreateParam(int type) {
0844:
0845: switch (type) {
0846:
0847: case BINARY:
0848: case BLOB:
0849: case CHAR:
0850: case CLOB:
0851:
0852: // case LONGVARBINARY :
0853: // case LONGVARCHAR :
0854: case VARBINARY:
0855: case VARCHAR:
0856: case VARCHAR_IGNORECASE:
0857: case DECIMAL:
0858: case NUMERIC:
0859: case FLOAT:
0860: case TIMESTAMP:
0861: case TIME:
0862: return true;
0863:
0864: default:
0865: return false;
0866: }
0867: }
0868:
0869: public static int numericPrecisionCreateParamRadix(int type) {
0870:
0871: switch (type) {
0872:
0873: case Types.DECIMAL:
0874: case Types.NUMERIC:
0875: return 10;
0876:
0877: case FLOAT:
0878: return 2;
0879:
0880: default:
0881:
0882: // to mean NOT APPLICABLE (i.e. NULL)
0883: return 0;
0884: }
0885: }
0886:
0887: public static boolean acceptsScaleCreateParam(int type) {
0888:
0889: switch (type) {
0890:
0891: case Types.DECIMAL:
0892: case Types.NUMERIC:
0893: return true;
0894:
0895: default:
0896: return false;
0897: }
0898: }
0899:
0900: public static boolean isNumberType(int type) {
0901:
0902: switch (type) {
0903:
0904: case BIGINT:
0905: case DECIMAL:
0906: case DOUBLE:
0907: case FLOAT:
0908: case INTEGER:
0909: case NUMERIC:
0910: case REAL:
0911: case SMALLINT:
0912: case TINYINT:
0913: return true;
0914:
0915: default:
0916: return false;
0917: }
0918: }
0919:
0920: public static boolean isCharacterType(int type) {
0921:
0922: switch (type) {
0923:
0924: case CHAR:
0925: case CLOB:
0926: case LONGVARCHAR:
0927: case VARCHAR:
0928: case VARCHAR_IGNORECASE:
0929: return true;
0930:
0931: default:
0932: return false;
0933: }
0934: }
0935:
0936: public static String getTypeName(int type) {
0937:
0938: switch (type) {
0939:
0940: case Types.ARRAY:
0941: return "ARRAY";
0942:
0943: case Types.BIGINT:
0944: return "BIGINT";
0945:
0946: case Types.BINARY:
0947: return "BINARY";
0948:
0949: case Types.BLOB:
0950: return "BLOB";
0951:
0952: case Types.BOOLEAN:
0953: return "BOOLEAN";
0954:
0955: case Types.CHAR:
0956: return "CHAR";
0957:
0958: case Types.CLOB:
0959: return "CLOB";
0960:
0961: case Types.DATALINK:
0962: return "DATALINK";
0963:
0964: case Types.DATE:
0965: return "DATE";
0966:
0967: case Types.DECIMAL:
0968: return "DECIMAL";
0969:
0970: case Types.DISTINCT:
0971: return "DISTINCT";
0972:
0973: case Types.DOUBLE:
0974: return "DOUBLE";
0975:
0976: case Types.FLOAT:
0977: return "FLOAT";
0978:
0979: case Types.INTEGER:
0980: return "INTEGER";
0981:
0982: case Types.JAVA_OBJECT:
0983: return "JAVA_OBJECT";
0984:
0985: case Types.LONGVARBINARY:
0986: return "LONGVARBINARY";
0987:
0988: case Types.LONGVARCHAR:
0989: return "LONGVARCHAR";
0990:
0991: case Types.NULL:
0992: return "NULL";
0993:
0994: case Types.NUMERIC:
0995: return "NUMERIC";
0996:
0997: case Types.OTHER:
0998: return "OTHER";
0999:
1000: case Types.REAL:
1001: return "REAL";
1002:
1003: case Types.REF:
1004: return "REF";
1005:
1006: case Types.SMALLINT:
1007: return "SMALLINT";
1008:
1009: case Types.STRUCT:
1010: return "STRUCT";
1011:
1012: case Types.TIME:
1013: return "TIME";
1014:
1015: case Types.TIMESTAMP:
1016: return "TIMESTAMP";
1017:
1018: case Types.TINYINT:
1019: return "TINYINT";
1020:
1021: case Types.VARBINARY:
1022: return "VARBINARY";
1023:
1024: case Types.VARCHAR:
1025: return "VARCHAR";
1026:
1027: case Types.VARCHAR_IGNORECASE:
1028: return "VARCHAR_IGNORECASE";
1029:
1030: case Types.XML:
1031: return "XML";
1032:
1033: default:
1034: return null;
1035: }
1036: }
1037:
1038: /**
1039: * A reasonable/customizable number to avoid the shortcomings/defects
1040: * associated with doing a dynamic scan of results to determine
1041: * the value. In practice, it turns out that single query yielding
1042: * widely varying values for display size of CHAR and VARCHAR columns
1043: * on repeated execution results in patently poor usability, as some fairly
1044: * high-profile, otherwise "enterprise-quality" RAD tools depend on
1045: * on the first value returned to lay out forms and limit the size of
1046: * single line edit controls, set corresponding local datastore storage
1047: * sizes, etc. In practice, It also turns out that many tools (due to
1048: * the original lack of PreparedStatement.getMetaData() in JDK 1.1) emulate
1049: * a SQL_DESCRIBE by executing a query hopefully guaranteed to return no
1050: * or very few rows for example: select ... from ... where 1=0.
1051: * Using the dynamic scan of 1.7.2 RC5 and previous, therefore, the
1052: * minimum display size value (1) was often being generated during
1053: * a tool's describe phase. Upon subsequent "real" retrievals, some
1054: * tools complain that CHAR and VARCHAR result values exceeded the
1055: * originally reported display size and refused to fetch further values.
1056: */
1057: public static final int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE = MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE();
1058:
1059: // So that the variable can be both public static final and
1060: // customizable through system properties if required.
1061: //
1062: // 32766 (0x7ffe) seems to be a magic number over which several
1063: // rather high-profile RAD tools start to have problems
1064: // regarding layout and allocation stress. It is gently
1065: // recommended that LONGVARCHAR be used for larger values in RAD
1066: // tool layout & presentation use cases until such time as we provide
1067: // true BLOB support (at which point, LONGVARCHAR will most likely become
1068: // an alias for CLOB).
1069: //
1070: // Most GUI tools seem to handle LONGVARCHAR gracefully by:
1071: //
1072: // 1.) refusing to directly display such columns in graphical query results
1073: // 2.) providing other means to retrieve and display such values
1074: private static int MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE() {
1075:
1076: try {
1077: return Integer.getInteger(
1078: "hsqldb.max_char_or_varchar_display_size", 32766)
1079: .intValue();
1080: } catch (SecurityException e) {
1081: return 32766;
1082: }
1083: }
1084:
1085: public static int getMaxDisplaySize(int type) {
1086:
1087: switch (type) {
1088:
1089: case Types.BINARY:
1090: case Types.LONGVARBINARY:
1091: case Types.LONGVARCHAR:
1092: case Types.OTHER:
1093: case Types.VARBINARY:
1094: case Types.XML:
1095: return Integer.MAX_VALUE; // max string length
1096:
1097: case Types.CHAR:
1098: case Types.VARCHAR:
1099: return MAX_CHAR_OR_VARCHAR_DISPLAY_SIZE;
1100:
1101: case Types.BIGINT: // PowerBuilder barfs, wants 19
1102:
1103: // ...not our problem, tho,
1104: // according to JDBC
1105: return 20; // precision + "-".length();
1106:
1107: case Types.BOOLEAN:
1108: return 5; // Math.max("true".length(),"false".length);
1109:
1110: case Types.DATALINK:
1111: return 20004; // same as precision
1112:
1113: case Types.DECIMAL:
1114: case Types.NUMERIC:
1115: return 646456995; // precision + "-.".length()
1116:
1117: case Types.DATE:
1118: return 10; // same as precision
1119:
1120: case Types.INTEGER:
1121: return 11; // precision + "-".length();
1122:
1123: case Types.FLOAT:
1124: case Types.REAL:
1125: case Types.DOUBLE:
1126: return 23; // String.valueOf(-Double.MAX_VALUE).length();
1127:
1128: case Types.TIME:
1129: return 8; // same as precision
1130:
1131: case Types.SMALLINT:
1132: return 6; // precision + "-".length();
1133:
1134: case Types.TIMESTAMP:
1135: return 29; // same as precision
1136:
1137: case Types.TINYINT:
1138: return 4; // precision + "-".length();
1139:
1140: default:
1141: return 0; // unknown
1142: }
1143: }
1144:
1145: public static boolean isSearchable(int type) {
1146:
1147: switch (type) {
1148:
1149: case Types.ARRAY:
1150: case Types.BLOB:
1151: case Types.CLOB:
1152: case Types.JAVA_OBJECT:
1153: case Types.STRUCT:
1154: case Types.OTHER:
1155: return false;
1156:
1157: default:
1158: return true;
1159: }
1160: }
1161:
1162: public static Boolean isCaseSensitive(int type) {
1163:
1164: switch (type) {
1165:
1166: case Types.ARRAY:
1167: case Types.BLOB:
1168: case Types.CLOB:
1169: case Types.DISTINCT:
1170: case Types.JAVA_OBJECT:
1171: case Types.NULL:
1172: case Types.REF:
1173: case Types.STRUCT:
1174: return null;
1175:
1176: case Types.CHAR:
1177: case Types.DATALINK:
1178: case Types.LONGVARCHAR:
1179: case Types.OTHER:
1180: case Types.XML:
1181: return Boolean.TRUE;
1182:
1183: case Types.VARCHAR_IGNORECASE:
1184: default:
1185: return Boolean.FALSE;
1186: }
1187: }
1188:
1189: public static Boolean isUnsignedAttribute(int type) {
1190:
1191: switch (type) {
1192:
1193: case Types.BIGINT:
1194: case Types.DECIMAL:
1195: case Types.DOUBLE:
1196: case Types.FLOAT:
1197: case Types.INTEGER:
1198: case Types.NUMERIC:
1199: case Types.REAL:
1200: case Types.SMALLINT:
1201: case Types.TINYINT:
1202: return Boolean.FALSE;
1203:
1204: default:
1205: return null;
1206: }
1207: }
1208:
1209: public static int getPrecision(int type) {
1210:
1211: switch (type) {
1212:
1213: case Types.BINARY:
1214: case Types.CHAR:
1215: case Types.LONGVARBINARY:
1216: case Types.LONGVARCHAR:
1217: case Types.OTHER:
1218: case Types.VARBINARY:
1219: case Types.VARCHAR:
1220: case Types.XML:
1221: return Integer.MAX_VALUE;
1222:
1223: case Types.BIGINT:
1224: return 19;
1225:
1226: case Types.BOOLEAN:
1227: return 1;
1228:
1229: case Types.DATALINK:
1230:
1231: // from SQL CLI spec. TODO: Interpretation?
1232: return 20004;
1233:
1234: case Types.DECIMAL:
1235: case Types.NUMERIC:
1236:
1237: // Integer.MAX_VALUE bit 2's complement number:
1238: // (Integer.MAX_VALUE-1) / ((ln(10)/ln(2)) bits per decimal digit)
1239: // See: java.math.BigInteger
1240: // - the other alternative is that we could report the numprecradix as 2 and
1241: // report Integer.MAX_VALUE here
1242: return 646456993;
1243:
1244: case Types.DATE:
1245: case Types.INTEGER:
1246: return 10;
1247:
1248: case Types.FLOAT:
1249: case Types.REAL:
1250: case Types.DOUBLE:
1251: return 17;
1252:
1253: case Types.TIME:
1254: return 8;
1255:
1256: case Types.SMALLINT:
1257: return 5;
1258:
1259: case Types.TIMESTAMP:
1260: return 29;
1261:
1262: case Types.TINYINT:
1263: return 3;
1264:
1265: default:
1266: return 0;
1267: }
1268: }
1269:
1270: public static String getColStClsName(int type) {
1271:
1272: switch (type) {
1273:
1274: case Types.BIGINT:
1275: return "java.lang.Long";
1276:
1277: case Types.BINARY:
1278: case Types.LONGVARBINARY:
1279: case Types.VARBINARY:
1280:
1281: // but wrapped by org.hsqldb.Binary
1282: return "[B";
1283:
1284: case Types.OTHER:
1285:
1286: // but wrapped by org.hsqldb.JavaObject
1287: return "java.lang.Object";
1288:
1289: case Types.BOOLEAN:
1290: return "java.lang.Boolean";
1291:
1292: case Types.CHAR:
1293: case Types.LONGVARCHAR:
1294: case Types.VARCHAR:
1295: case Types.XML: //?
1296: return "java.lang.String";
1297:
1298: case Types.DATALINK:
1299: return "java.net.URL";
1300:
1301: case Types.DATE:
1302: return DateClassName;
1303:
1304: case Types.DECIMAL:
1305: case Types.NUMERIC:
1306: return DecimalClassName;
1307:
1308: case Types.DOUBLE:
1309: case Types.FLOAT:
1310: case Types.REAL:
1311: return "java.lang.Double";
1312:
1313: case Types.INTEGER:
1314: case Types.SMALLINT:
1315: case Types.TINYINT:
1316: return "java.lang.Integer";
1317:
1318: case Types.TIME:
1319: return TimeClassName;
1320:
1321: case Types.TIMESTAMP:
1322: return TimestampClassName;
1323:
1324: default:
1325: return null;
1326: }
1327: }
1328: }
|