KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > types > TypeId


1 /*
2
3    Derby - Class org.apache.derby.iapi.types.TypeId
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.types;
23
24 import org.apache.derby.iapi.services.io.Formatable;
25 import org.apache.derby.iapi.services.io.StoredFormatIds;
26 import org.apache.derby.iapi.services.monitor.Monitor;
27 import org.apache.derby.iapi.services.loader.ClassFactory;
28
29 import org.apache.derby.iapi.error.StandardException;
30
31 import org.apache.derby.catalog.types.BaseTypeIdImpl;
32 import org.apache.derby.catalog.types.DecimalTypeIdImpl;
33 import org.apache.derby.catalog.types.UserDefinedTypeIdImpl;
34
35 import org.apache.derby.iapi.reference.Limits;
36
37 import java.io.ObjectOutput JavaDoc;
38 import java.io.ObjectInput JavaDoc;
39 import java.io.IOException JavaDoc;
40 import org.apache.derby.iapi.services.sanity.SanityManager;
41
42 import org.apache.derby.iapi.types.*;
43 import org.apache.derby.iapi.types.*;
44
45 import org.apache.derby.iapi.reference.JDBC20Translation;
46 import org.apache.derby.iapi.reference.JDBC30Translation;
47
48 import java.sql.Types JavaDoc;
49
50 /**
51  * The TypeId interface provides methods to get information about datatype ids.
52  
53    <P>
54  * The equals(Object) method can be used to determine if two typeIds are for the same type,
55  * which defines type id equality.
56
57  *
58  * @author Jeff Lichtman
59  */

60
61 public final class TypeId implements Formatable
62 {
63         /**
64          * Various fixed numbers related to datatypes.
65          */

66         public static final int LONGINT_PRECISION = 19;
67         public static final int LONGINT_SCALE = 0;
68         public static final int LONGINT_MAXWIDTH = 8;
69
70         public static final int INT_PRECISION = 10;
71         public static final int INT_SCALE = 0;
72         public static final int INT_MAXWIDTH = 4;
73
74         public static final int SMALLINT_PRECISION = 5;
75         public static final int SMALLINT_SCALE = 0;
76         public static final int SMALLINT_MAXWIDTH = 2;
77
78         public static final int TINYINT_PRECISION = 3;
79         public static final int TINYINT_SCALE = 0;
80         public static final int TINYINT_MAXWIDTH = 1;
81
82     // precision in number of bits
83
public static final int DOUBLE_PRECISION = 52;
84     // the ResultSetMetaData needs to have the precision for numeric data
85
// in decimal digits, rather than number of bits, so need a separate constant.
86
public static final int DOUBLE_PRECISION_IN_DIGITS = 15;
87         public static final int DOUBLE_SCALE = 0;
88         public static final int DOUBLE_MAXWIDTH = 8;
89
90     // precision in number of bits
91
public static final int REAL_PRECISION = 23;
92     // the ResultSetMetaData needs to have the precision for numeric data
93
// in decimal digits, rather than number of bits, so need a separate constant.
94
public static final int REAL_PRECISION_IN_DIGITS = 7;
95         public static final int REAL_SCALE = 0;
96         public static final int REAL_MAXWIDTH = 4;
97
98         public static final int DECIMAL_PRECISION = Limits.DB2_MAX_DECIMAL_PRECISION_SCALE;
99         public static final int DECIMAL_SCALE = Limits.DB2_MAX_DECIMAL_PRECISION_SCALE;
100         public static final int DECIMAL_MAXWIDTH = Limits.DB2_MAX_DECIMAL_PRECISION_SCALE;
101
102         public static final int BOOLEAN_MAXWIDTH = 1;
103
104         public static final int CHAR_MAXWIDTH = Limits.DB2_CHAR_MAXWIDTH;
105         public static final int VARCHAR_MAXWIDTH = Limits.DB2_VARCHAR_MAXWIDTH;
106         public static final int LONGVARCHAR_MAXWIDTH = Limits.DB2_LONGVARCHAR_MAXWIDTH;
107         public static final int NATIONAL_CHAR_MAXWIDTH = Integer.MAX_VALUE;
108         public static final int NATIONAL_VARCHAR_MAXWIDTH = Integer.MAX_VALUE;
109         public static final int NATIONAL_LONGVARCHAR_MAXWIDTH = Limits.DB2_LONGVARCHAR_MAXWIDTH;
110         public static final int BIT_MAXWIDTH = Limits.DB2_CHAR_MAXWIDTH;
111         public static final int VARBIT_MAXWIDTH = Limits.DB2_VARCHAR_MAXWIDTH;
112         public static final int LONGVARBIT_MAXWIDTH = Limits.DB2_LONGVARCHAR_MAXWIDTH;
113
114         // not supposed to be limited! 4096G should be ok(?), if Cloudscape can handle...
115
public static final int BLOB_MAXWIDTH = Integer.MAX_VALUE; // to change long
116
public static final int CLOB_MAXWIDTH = Integer.MAX_VALUE; // to change long
117
public static final int NCLOB_MAXWIDTH = Integer.MAX_VALUE; // to change long
118
public static final int XML_MAXWIDTH = Integer.MAX_VALUE;
119
120         // Max width for datetime values is the length of the
121
// string returned from a call to "toString()" on the
122
// java.sql.Date, java.sql.Time, and java.sql.Timestamp
123
// classes (the result of toString() on those classes
124
// is defined by the JDBC API). This value is also
125
// used as the "precision" for those types.
126
public static final int DATE_MAXWIDTH = 10; // yyyy-mm-dd
127
public static final int TIME_MAXWIDTH = 8; // hh:mm:ss
128
public static final int TIMESTAMP_MAXWIDTH = 26; // yyyy-mm-dd hh:mm:ss.ffffff
129

130         // Scale DOES exist for time values. For a TIMESTAMP value,
131
// it's 6 ('ffffff'); for a TIME value, it's 0 (because there
132
// are no fractional seconds). Note that date values do
133
// not have a scale.
134
public static final int TIME_SCALE = 0;
135         public static final int TIMESTAMP_SCALE = 6;
136
137         /* These define all the type names for SQL92 and JDBC
138          * NOTE: boolean is SQL3
139          */

140           //public static final String BIT_NAME = "BIT";
141
//public static final String VARBIT_NAME = "BIT VARYING";
142
//public static final String LONGVARBIT_NAME = "LONG BIT VARYING";
143

144         public static final String JavaDoc BIT_NAME = "CHAR () FOR BIT DATA";
145         public static final String JavaDoc VARBIT_NAME = "VARCHAR () FOR BIT DATA";
146         public static final String JavaDoc LONGVARBIT_NAME = "LONG VARCHAR FOR BIT DATA";
147         public static final String JavaDoc TINYINT_NAME = "TINYINT";
148         public static final String JavaDoc SMALLINT_NAME = "SMALLINT";
149         public static final String JavaDoc INTEGER_NAME = "INTEGER";
150         public static final String JavaDoc LONGINT_NAME = "BIGINT";
151         public static final String JavaDoc FLOAT_NAME = "FLOAT";
152         public static final String JavaDoc REAL_NAME = "REAL";
153         public static final String JavaDoc DOUBLE_NAME = "DOUBLE";
154         public static final String JavaDoc NUMERIC_NAME = "NUMERIC";
155         public static final String JavaDoc DECIMAL_NAME = "DECIMAL";
156         public static final String JavaDoc CHAR_NAME = "CHAR";
157         public static final String JavaDoc VARCHAR_NAME = "VARCHAR";
158         public static final String JavaDoc LONGVARCHAR_NAME = "LONG VARCHAR";
159         public static final String JavaDoc DATE_NAME = "DATE";
160         public static final String JavaDoc TIME_NAME = "TIME";
161         public static final String JavaDoc TIMESTAMP_NAME = "TIMESTAMP";
162         public static final String JavaDoc BINARY_NAME = "BINARY";
163         public static final String JavaDoc VARBINARY_NAME = "VARBINARY";
164         public static final String JavaDoc LONGVARBINARY_NAME = "LONGVARBINARY";
165         public static final String JavaDoc BOOLEAN_NAME = "BOOLEAN";
166         public static final String JavaDoc REF_NAME = "REF";
167         public static final String JavaDoc NATIONAL_CHAR_NAME = "NATIONAL CHAR";
168         public static final String JavaDoc NATIONAL_VARCHAR_NAME = "NATIONAL CHAR VARYING";
169         public static final String JavaDoc NATIONAL_LONGVARCHAR_NAME = "LONG NVARCHAR";
170         public static final String JavaDoc BLOB_NAME = "BLOB";
171         public static final String JavaDoc CLOB_NAME = "CLOB";
172         public static final String JavaDoc NCLOB_NAME = "NCLOB";
173
174         // Following use of "XML" is per SQL/XML (2003) spec,
175
// section "10.2 Type name determination".
176
public static final String JavaDoc XML_NAME = "XML";
177         
178         // ARRAY and STRUCT are JDBC 2.0 data types that are not
179
// supported by Derby.
180
public static final String JavaDoc ARRAY_NAME = "ARRAY";
181         public static final String JavaDoc STRUCT_NAME = "STRUCT";
182
183         // DATALINK is a JDBC 3.0 data type. Not supported by Derby.
184
public static final String JavaDoc DATALINK_NAME = "DATALINK";
185
186         // ROWID and SQLXML are new types in JDBC 4.0. Not supported
187
// by Derby.
188
public static final String JavaDoc ROWID_NAME = "ROWID";
189         public static final String JavaDoc SQLXML_NAME = "SQLXML";
190
191         /**
192          * The following constants define the type precedence hierarchy.
193          */

194         public static final int USER_PRECEDENCE = 1000;
195
196         public static final int XML_PRECEDENCE = 180;
197         public static final int BLOB_PRECEDENCE = 170;
198         public static final int LONGVARBIT_PRECEDENCE = 160;
199         public static final int VARBIT_PRECEDENCE = 150;
200         public static final int BIT_PRECEDENCE = 140;
201         public static final int BOOLEAN_PRECEDENCE = 130;
202         public static final int TIME_PRECEDENCE = 120;
203         public static final int TIMESTAMP_PRECEDENCE = 110;
204         public static final int DATE_PRECEDENCE = 100;
205         public static final int DOUBLE_PRECEDENCE = 90;
206         public static final int REAL_PRECEDENCE = 80;
207         public static final int DECIMAL_PRECEDENCE = 70;
208         public static final int NUMERIC_PRECEDENCE = 69;
209         public static final int LONGINT_PRECEDENCE = 60;
210         public static final int INT_PRECEDENCE = 50;
211         public static final int SMALLINT_PRECEDENCE = 40;
212         public static final int TINYINT_PRECEDENCE = 30;
213         public static final int REF_PRECEDENCE = 25;
214         public static final int NATIONAL_LONGVARCHAR_PRECEDENCE = 18;
215         public static final int NATIONAL_VARCHAR_PRECEDENCE = 17;
216         public static final int NATIONAL_CHAR_PRECEDENCE = 16;
217         public static final int CLOB_PRECEDENCE = 14;
218         public static final int NCLOB_PRECEDENCE = 13;
219         public static final int LONGVARCHAR_PRECEDENCE = 12;
220         public static final int VARCHAR_PRECEDENCE = 10;
221         public static final int CHAR_PRECEDENCE = 0;
222
223         /*
224         ** Static runtime fields for typeIds
225         ** These are put here because the system needs them init time.
226         */

227         public static final TypeId BOOLEAN_ID = new TypeId(StoredFormatIds.BOOLEAN_TYPE_ID,
228                                                                                                                         new BaseTypeIdImpl(StoredFormatIds.BOOLEAN_TYPE_ID_IMPL));
229         public static final TypeId INTEGER_ID = new TypeId(StoredFormatIds.INT_TYPE_ID,
230                                                                                                                         new BaseTypeIdImpl(StoredFormatIds.INT_TYPE_ID_IMPL));
231         public static final TypeId CHAR_ID = new TypeId(StoredFormatIds.CHAR_TYPE_ID,
232                                                                                                                  new BaseTypeIdImpl(StoredFormatIds.CHAR_TYPE_ID_IMPL));
233         /*
234         ** Others are created on demand by the getBuiltInTypeId(int),
235         ** if they are built-in (i.e.? Part of JDBC .Types),
236         ** or by getBuiltInTypeId(string) if they are NATIONAL types or REF_NAME type.
237         */

238
239         private static TypeId TINYINT_ID;
240         private static TypeId SMALLINT_ID;
241         private static TypeId LONGINT_ID;
242         private static TypeId REAL_ID;
243         private static TypeId DOUBLE_ID;
244         private static TypeId DECIMAL_ID;
245         private static TypeId NUMERIC_ID;
246         private static TypeId VARCHAR_ID;
247         private static TypeId NATIONAL_CHAR_ID;
248         private static TypeId NATIONAL_LONGVARCHAR_ID;
249         private static TypeId NATIONAL_VARCHAR_ID;
250         private static TypeId DATE_ID;
251         private static TypeId TIME_ID;
252         private static TypeId TIMESTAMP_ID;
253         private static TypeId BIT_ID;
254         private static TypeId VARBIT_ID;
255         private static TypeId REF_ID;
256         private static TypeId LONGVARCHAR_ID;
257         private static TypeId LONGVARBIT_ID;
258
259         private static TypeId BLOB_ID;
260         private static TypeId CLOB_ID;
261         private static TypeId NCLOB_ID;
262         private static TypeId XML_ID;
263
264         /**
265          * Implementation of DECIMAL datatype for generating holders through getNull.
266          * Set by the booted DataValueFactory implementation.
267          */

268         static DataValueDescriptor decimalImplementation;
269
270         /*
271         ** Static methods to obtain TypeIds
272         */

273         /**
274          * Get a TypeId of the given JDBC type. This factory method is
275          * intended to be used for built-in types. For user-defined types,
276          * we will need a factory method that takes a Java type name.
277          *
278          * @param JDBCTypeId The JDBC Id of the type, as listed in
279          * java.sql.Types
280          *
281          * @return The appropriate TypeId, or null if there is no such
282          * TypeId.
283          */

284
285         public static TypeId getBuiltInTypeId(int JDBCTypeId)
286         {
287                 TypeId ret = null;
288
289                 switch (JDBCTypeId)
290                 {
291                   case Types.TINYINT:
292                           ret = TINYINT_ID;
293                           if (ret == null)
294                                   ret = TINYINT_ID = new TypeId(StoredFormatIds.TINYINT_TYPE_ID,
295                                                                         new BaseTypeIdImpl(StoredFormatIds.TINYINT_TYPE_ID_IMPL));
296                           break;
297
298                   case Types.SMALLINT:
299                           ret = SMALLINT_ID;
300                           if (ret == null)
301                                   ret = SMALLINT_ID = new TypeId(StoredFormatIds.SMALLINT_TYPE_ID,
302                                                                         new BaseTypeIdImpl(StoredFormatIds.SMALLINT_TYPE_ID_IMPL));
303                           break;
304
305                   case Types.INTEGER:
306                           return INTEGER_ID;
307
308                   case Types.BIGINT:
309                           ret = LONGINT_ID;
310                           if (ret == null)
311                                   ret = LONGINT_ID = new TypeId(StoredFormatIds.LONGINT_TYPE_ID,
312                                                                         new BaseTypeIdImpl(StoredFormatIds.LONGINT_TYPE_ID_IMPL));
313                           break;
314
315                   case Types.REAL:
316                           ret = REAL_ID;
317                           if (ret == null)
318                                   ret = REAL_ID = new TypeId(StoredFormatIds.REAL_TYPE_ID,
319                                                                         new BaseTypeIdImpl(StoredFormatIds.REAL_TYPE_ID_IMPL));
320                           break;
321
322                   case Types.FLOAT:
323                   case Types.DOUBLE:
324                           ret = DOUBLE_ID;
325                           if (ret == null)
326                                   ret = DOUBLE_ID = new TypeId(StoredFormatIds.DOUBLE_TYPE_ID,
327                                                                         new BaseTypeIdImpl(StoredFormatIds.DOUBLE_TYPE_ID_IMPL));
328                           break;
329
330                   case Types.DECIMAL:
331                           ret = DECIMAL_ID;
332                           if (ret == null)
333                                   ret = DECIMAL_ID = new TypeId(StoredFormatIds.DECIMAL_TYPE_ID,
334                                                                         new DecimalTypeIdImpl());
335                           break;
336
337                   case Types.NUMERIC:
338                           ret = NUMERIC_ID;
339                           if (ret == null) {
340                                   DecimalTypeIdImpl numericTypeIdImpl = new DecimalTypeIdImpl();
341                                   numericTypeIdImpl.setNumericType();
342                                   ret = NUMERIC_ID = new TypeId(StoredFormatIds.DECIMAL_TYPE_ID, numericTypeIdImpl);
343                           }
344                           break;
345
346                   case Types.CHAR:
347                           return CHAR_ID;
348
349                   case Types.VARCHAR:
350                           ret = VARCHAR_ID;
351                           if (ret == null)
352                                   ret = VARCHAR_ID = new TypeId(StoredFormatIds.VARCHAR_TYPE_ID,
353                                                                         new BaseTypeIdImpl(StoredFormatIds.VARCHAR_TYPE_ID_IMPL));
354                           break;
355
356                   case Types.DATE:
357                           ret = DATE_ID;
358                           if (ret == null)
359                                   ret = DATE_ID = new TypeId(StoredFormatIds.DATE_TYPE_ID,
360                                                                         new BaseTypeIdImpl(StoredFormatIds.DATE_TYPE_ID_IMPL));
361                           break;
362
363                   case Types.TIME:
364                           ret = TIME_ID;
365                           if (ret == null)
366                                   ret = TIME_ID = new TypeId(StoredFormatIds.TIME_TYPE_ID,
367                                                                         new BaseTypeIdImpl(StoredFormatIds.TIME_TYPE_ID_IMPL));
368                           break;
369
370                   case Types.TIMESTAMP:
371                           ret = TIMESTAMP_ID;
372                           if (ret == null)
373                                   ret = TIMESTAMP_ID = new TypeId(StoredFormatIds.TIMESTAMP_TYPE_ID,
374                                                                         new BaseTypeIdImpl(StoredFormatIds.TIMESTAMP_TYPE_ID_IMPL));
375                           break;
376                   case Types.BIT:
377                   case JDBC30Translation.SQL_TYPES_BOOLEAN:
378                           return BOOLEAN_ID;
379
380                   case Types.BINARY:
381                           ret = BIT_ID;
382                           if (ret == null)
383                                   ret = BIT_ID = new TypeId(StoredFormatIds.BIT_TYPE_ID,
384                                                                         new BaseTypeIdImpl(StoredFormatIds.BIT_TYPE_ID_IMPL));
385                           break;
386
387                   case Types.VARBINARY:
388                           ret = VARBIT_ID;
389                           if (ret == null)
390                                   ret = VARBIT_ID = new TypeId(StoredFormatIds.VARBIT_TYPE_ID,
391                                                                         new BaseTypeIdImpl(StoredFormatIds.VARBIT_TYPE_ID_IMPL));
392                           break;
393
394                   case Types.LONGVARBINARY:
395                           ret = LONGVARBIT_ID;
396                           if (ret == null)
397                                   ret = LONGVARBIT_ID = new TypeId(StoredFormatIds.LONGVARBIT_TYPE_ID,
398                                                                         new BaseTypeIdImpl(StoredFormatIds.LONGVARBIT_TYPE_ID_IMPL));
399                           break;
400
401                   case Types.LONGVARCHAR:
402                       ret = LONGVARCHAR_ID;
403                       if (ret == null)
404                           ret = LONGVARCHAR_ID = new TypeId(StoredFormatIds.LONGVARCHAR_TYPE_ID,
405                                                             new BaseTypeIdImpl(StoredFormatIds.LONGVARCHAR_TYPE_ID_IMPL));
406                       break;
407
408                   case JDBC20Translation.SQL_TYPES_BLOB:
409                       ret = BLOB_ID;
410                       if (ret == null)
411                           ret = BLOB_ID = new TypeId(StoredFormatIds.BLOB_TYPE_ID,
412                                                      new BaseTypeIdImpl(StoredFormatIds.BLOB_TYPE_ID_IMPL));
413                       break;
414                                                 
415                   case JDBC20Translation.SQL_TYPES_CLOB:
416                       ret = CLOB_ID;
417                       if (ret == null)
418                           ret = CLOB_ID = new TypeId(StoredFormatIds.CLOB_TYPE_ID,
419                                                      new BaseTypeIdImpl(StoredFormatIds.CLOB_TYPE_ID_IMPL));
420                       break;
421
422                   // XML is not a JDBC type, so we have to check for our
423
// internal XML type.
424
case StoredFormatIds.XML_TYPE_ID:
425                       ret = XML_ID;
426                       if (ret == null)
427                           ret = XML_ID = new TypeId(StoredFormatIds.XML_TYPE_ID,
428                                                      new BaseTypeIdImpl(StoredFormatIds.XML_TYPE_ID_IMPL));
429                       break;
430                 }
431                 return ret;
432         }
433
434         public static TypeId getUserDefinedTypeId(String JavaDoc className, boolean delimitedIdentifier)
435         {
436                 return new TypeId(StoredFormatIds.USERDEFINED_TYPE_ID_V3,
437                                         new UserDefinedTypeIdImpl(className), delimitedIdentifier
438                                         );
439         }
440
441         /**
442          * Get a TypeId for the class that corresponds to the given
443          * Java type name.
444          *
445          * @param javaTypeName The name of the Java type
446          *
447          * @return A TypeId for the SQL type that corresponds to
448          * the Java type, null if there is no corresponding type.
449          */

450         public static TypeId getSQLTypeForJavaType(String JavaDoc javaTypeName)
451         {
452                 if (javaTypeName.equals("java.lang.Boolean") ||
453                         javaTypeName.equals("boolean"))
454                 {
455                         return TypeId.BOOLEAN_ID;
456                 }
457                 else if (javaTypeName.equals("byte[]"))
458                 {
459                         return getBuiltInTypeId(Types.VARBINARY);
460                 }
461                 else if (javaTypeName.equals("java.lang.String"))
462                 {
463                         return getBuiltInTypeId(Types.VARCHAR);
464                 }
465                 else if (javaTypeName.equals("java.lang.Integer") ||
466                                 javaTypeName.equals("int"))
467                 {
468                         return TypeId.INTEGER_ID;
469                 }
470                 else if (javaTypeName.equals("byte"))
471                 {
472                         return getBuiltInTypeId(Types.TINYINT);
473                 }
474                 else if (javaTypeName.equals("short"))
475                 {
476                         return getBuiltInTypeId(Types.SMALLINT);
477                 }
478                 else if (javaTypeName.equals("java.lang.Long") ||
479                                 javaTypeName.equals("long"))
480                 {
481                         return getBuiltInTypeId(Types.BIGINT);
482                 }
483                 else if (javaTypeName.equals("java.lang.Float") ||
484                                 javaTypeName.equals("float"))
485                 {
486                         return getBuiltInTypeId(Types.REAL);
487                 }
488                 else if (javaTypeName.equals("java.lang.Double") ||
489                                 javaTypeName.equals("double"))
490                 {
491                         return getBuiltInTypeId(Types.DOUBLE);
492                 }
493                 else if (javaTypeName.equals("java.math.BigDecimal"))
494                 {
495                         return getBuiltInTypeId(Types.DECIMAL);
496                 }
497                 else if (javaTypeName.equals("java.sql.Date"))
498                 {
499                         return getBuiltInTypeId(Types.DATE);
500                 }
501                 else if (javaTypeName.equals("java.sql.Time"))
502                 {
503                         return getBuiltInTypeId(Types.TIME);
504                 }
505                 else if (javaTypeName.equals("java.sql.Timestamp"))
506                 {
507                         return getBuiltInTypeId(Types.TIMESTAMP);
508                 }
509                 else if (javaTypeName.equals("java.sql.Blob"))
510                 {
511                         return getBuiltInTypeId(JDBC20Translation.SQL_TYPES_BLOB);
512                 }
513                 else if (javaTypeName.equals("java.sql.Clob"))
514                 {
515                         return getBuiltInTypeId(JDBC20Translation.SQL_TYPES_CLOB);
516                 }
517                 else if (javaTypeName.equals("org.apache.derby.iapi.types.XML"))
518                 {
519                         return getBuiltInTypeId(StoredFormatIds.XML_TYPE_ID);
520                 }
521                 else
522                 {
523                         /*
524                         ** If it's a Java primitive type, return null to indicate that
525                         ** there is no corresponding SQL type (all the Java primitive
526                         ** types that have corresponding SQL types are handled above).
527                         **
528                         ** There is only one primitive type not mentioned above, char.
529                         */

530                         if (javaTypeName.equals("char"))
531                         {
532                                 return null;
533                         }
534
535                         /*
536                         ** It's a non-primitive type (a class) that does not correspond
537                         ** to a SQL built-in type, so treat it as a user-defined type.
538                         */

539                         return TypeId.getUserDefinedTypeId(javaTypeName, false);
540                 }
541         }
542
543         public static TypeId getBuiltInTypeId(String JavaDoc SQLTypeName) {
544
545                 if (SQLTypeName.equals(TypeId.BOOLEAN_NAME)) {
546                         return TypeId.BOOLEAN_ID;
547                 }
548                 if (SQLTypeName.equals(TypeId.CHAR_NAME)) {
549                         return TypeId.CHAR_ID;
550                 }
551                 if (SQLTypeName.equals(TypeId.DATE_NAME)) {
552                         return getBuiltInTypeId(Types.DATE);
553                 }
554                 if (SQLTypeName.equals(TypeId.DOUBLE_NAME)) {
555                         return getBuiltInTypeId(Types.DOUBLE);
556                 }
557                 if (SQLTypeName.equals(TypeId.FLOAT_NAME)) {
558                         return getBuiltInTypeId(Types.DOUBLE);
559                 }
560                 if (SQLTypeName.equals(TypeId.INTEGER_NAME)) {
561                         return TypeId.INTEGER_ID;
562                 }
563                 if (SQLTypeName.equals(TypeId.LONGINT_NAME)) {
564                         return getBuiltInTypeId(Types.BIGINT);
565                 }
566                 if (SQLTypeName.equals(TypeId.REAL_NAME)) {
567                         return getBuiltInTypeId(Types.REAL);
568                 }
569                 if (SQLTypeName.equals(TypeId.SMALLINT_NAME)) {
570                         return getBuiltInTypeId(Types.SMALLINT);
571                 }
572                 if (SQLTypeName.equals(TypeId.TIME_NAME)) {
573                         return getBuiltInTypeId(Types.TIME);
574                 }
575                 if (SQLTypeName.equals(TypeId.TIMESTAMP_NAME)) {
576                         return getBuiltInTypeId(Types.TIMESTAMP);
577                 }
578                 if (SQLTypeName.equals(TypeId.VARCHAR_NAME)) {
579                         return getBuiltInTypeId(Types.VARCHAR);
580                 }
581                 if (SQLTypeName.equals(TypeId.BIT_NAME)) {
582                         return getBuiltInTypeId(Types.BINARY);
583                 }
584                 if (SQLTypeName.equals(TypeId.VARBIT_NAME)) {
585                         return getBuiltInTypeId(Types.VARBINARY);
586                 }
587                 if (SQLTypeName.equals(TypeId.TINYINT_NAME)) {
588                         return getBuiltInTypeId(Types.TINYINT);
589                 }
590                 if (SQLTypeName.equals(TypeId.DECIMAL_NAME)) {
591                         return getBuiltInTypeId(Types.DECIMAL);
592                 }
593                 if (SQLTypeName.equals(TypeId.NUMERIC_NAME)) {
594                         return getBuiltInTypeId(Types.NUMERIC);
595                 }
596                 if (SQLTypeName.equals(TypeId.LONGVARCHAR_NAME)) {
597                         return getBuiltInTypeId(Types.LONGVARCHAR);
598                 }
599                 if (SQLTypeName.equals(TypeId.LONGVARBIT_NAME)) {
600                         return getBuiltInTypeId(Types.LONGVARBINARY);
601                 }
602                 if (SQLTypeName.equals(TypeId.BLOB_NAME)) {
603                         return getBuiltInTypeId(JDBC20Translation.SQL_TYPES_BLOB);
604                 }
605                 if (SQLTypeName.equals(TypeId.CLOB_NAME)) {
606                         return getBuiltInTypeId(JDBC20Translation.SQL_TYPES_CLOB);
607                 }
608                 if (SQLTypeName.equals(TypeId.XML_NAME)) {
609                         return getBuiltInTypeId(StoredFormatIds.XML_TYPE_ID);
610                 }
611
612                 TypeId ret = null;
613
614                 // Types defined below here are SQL types and non-JDBC types that are supported by Cloudscape
615
if (SQLTypeName.equals(TypeId.NCLOB_NAME)) {
616                         ret = NCLOB_ID;
617                         if (ret == null)
618                                 ret = NCLOB_ID = new TypeId(StoredFormatIds.NCLOB_TYPE_ID,
619                                                             new BaseTypeIdImpl(StoredFormatIds.NCLOB_TYPE_ID_IMPL));
620                 } else if (SQLTypeName.equals(TypeId.NATIONAL_CHAR_NAME)) {
621                         ret = NATIONAL_CHAR_ID;
622                         if (ret == null)
623                                 ret = NATIONAL_CHAR_ID = new TypeId(StoredFormatIds.NATIONAL_CHAR_TYPE_ID,
624                                                                     new BaseTypeIdImpl(StoredFormatIds.NATIONAL_CHAR_TYPE_ID_IMPL));
625
626                 } else if (SQLTypeName.equals(TypeId.NATIONAL_LONGVARCHAR_NAME)) {
627                         ret = NATIONAL_LONGVARCHAR_ID;
628                         if (ret == null)
629                                 ret = NATIONAL_LONGVARCHAR_ID = new TypeId(StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID,
630                                                                         new BaseTypeIdImpl(StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID_IMPL));
631
632                 } else if (SQLTypeName.equals(TypeId.NATIONAL_VARCHAR_NAME)) {
633                         ret = NATIONAL_VARCHAR_ID;
634                         if (ret == null)
635                                 ret = NATIONAL_VARCHAR_ID = new TypeId(StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID,
636                                                                         new BaseTypeIdImpl(StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID_IMPL));
637
638                 } else if (SQLTypeName.equals(TypeId.REF_NAME)) {
639                         ret = REF_ID;
640                         if (ret == null)
641                                 ret = REF_ID = new TypeId(StoredFormatIds.REF_TYPE_ID,
642                                                                         new BaseTypeIdImpl(StoredFormatIds.REF_TYPE_ID_IMPL));
643                 }
644                 return ret;
645         }
646
647         /*
648         ** Instance fields and methods
649         */

650
651         private BaseTypeIdImpl baseTypeId;
652         private int formatId;
653
654         /* Set in setTypeIdSpecificInstanceVariables() as needed */
655         private boolean classNameWasDelimitedIdentifier;
656         private boolean isBitTypeId;
657         private boolean isLOBTypeId;
658         private boolean isBooleanTypeId;
659         private boolean isConcatableTypeId;
660         private boolean isDecimalTypeId;
661         private boolean isLongConcatableTypeId;
662         private boolean isNumericTypeId;
663         private boolean isRefTypeId;
664         private boolean isStringTypeId;
665         private boolean isFloatingPointTypeId;
666         private boolean isRealTypeId;
667         private boolean isDateTimeTimeStampTypeId;
668         private boolean isUserDefinedTypeId;
669         private int maxPrecision;
670         private int maxScale;
671         private int typePrecedence;
672         private String JavaDoc javaTypeName;
673         private int maxMaxWidth;
674
675         /**
676          * 1 argmument constructor. Needed for Formatable interface to work.
677          *
678          * @param formatId Format id of specific type id.
679          */

680
681         public TypeId(int formatId)
682         {
683                 this.formatId = formatId;
684                 setTypeIdSpecificInstanceVariables();
685         }
686
687         /**
688          * Constructor for a TypeId
689          *
690          * @param formatId Format id of specific type id.
691          * @param baseTypeId The Base type id
692          */

693         public TypeId(int formatId, BaseTypeIdImpl baseTypeId)
694         {
695                 this.formatId = formatId;
696                 this.baseTypeId = baseTypeId;
697                 setTypeIdSpecificInstanceVariables();
698         }
699         /**
700          * Constructor for a TypeId for user defined types
701          *
702          * @param formatId Format id of specific type id.
703          * @param baseTypeId The Base type id
704          * @param classNameWasDelimitedIdentifier Whether or not the class name
705          * was a delimited identifier
706          */

707         public TypeId(int formatId, BaseTypeIdImpl baseTypeId,
708                                                  boolean classNameWasDelimitedIdentifier)
709         {
710                 this.formatId = formatId;
711                 this.baseTypeId = baseTypeId;
712                 this.classNameWasDelimitedIdentifier = classNameWasDelimitedIdentifier;
713                 setTypeIdSpecificInstanceVariables();
714         }
715
716         /**
717          * we want equals to say if these are the same type id or not.
718          */

719         public boolean equals(Object JavaDoc that)
720         {
721                 if (that instanceof TypeId)
722                         return this.getSQLTypeName().equals(((TypeId)that).getSQLTypeName());
723                 else
724                         return false;
725         }
726
727         /*
728           Hashcode which works with equals.
729           */

730         public int hashCode()
731         {
732                 return this.getSQLTypeName().hashCode();
733         }
734
735
736         private void setTypeIdSpecificInstanceVariables()
737         {
738                 switch (formatId)
739                 {
740                         case StoredFormatIds.BIT_TYPE_ID:
741                                 typePrecedence = BIT_PRECEDENCE;
742                                 javaTypeName = "byte[]";
743                                 maxMaxWidth = TypeId.BIT_MAXWIDTH;
744                                 isBitTypeId = true;
745                                 isConcatableTypeId = true;
746                                 break;
747
748                         case StoredFormatIds.BOOLEAN_TYPE_ID:
749                                 typePrecedence = BOOLEAN_PRECEDENCE;
750                                 javaTypeName = "java.lang.Boolean";
751                                 maxMaxWidth = TypeId.BOOLEAN_MAXWIDTH;
752                                 isBooleanTypeId = true;
753                                 break;
754
755                         case StoredFormatIds.CHAR_TYPE_ID:
756                                 typePrecedence = CHAR_PRECEDENCE;
757                                 javaTypeName = "java.lang.String";
758                                 maxMaxWidth = TypeId.CHAR_MAXWIDTH;
759                                 isStringTypeId = true;
760                                 isConcatableTypeId = true;
761                                 break;
762
763                         case StoredFormatIds.DATE_TYPE_ID:
764                                 typePrecedence = DATE_PRECEDENCE;
765                                 javaTypeName = "java.sql.Date";
766                                 maxMaxWidth = TypeId.DATE_MAXWIDTH;
767                                 maxPrecision = TypeId.DATE_MAXWIDTH;
768                                 isDateTimeTimeStampTypeId = true;
769                                 break;
770
771                         case StoredFormatIds.DECIMAL_TYPE_ID:
772                                 maxPrecision = TypeId.DECIMAL_PRECISION;
773                                 maxScale = TypeId.DECIMAL_SCALE;
774                                 typePrecedence = DECIMAL_PRECEDENCE;
775                                 javaTypeName = "java.math.BigDecimal";
776                                 maxMaxWidth = TypeId.DECIMAL_MAXWIDTH;
777                                 isDecimalTypeId = true;
778                                 isNumericTypeId = true;
779                                 break;
780
781                         case StoredFormatIds.DOUBLE_TYPE_ID:
782                                 maxPrecision = TypeId.DOUBLE_PRECISION;
783                                 maxScale = TypeId.DOUBLE_SCALE;
784                                 typePrecedence = DOUBLE_PRECEDENCE;
785                                 javaTypeName = "java.lang.Double";
786                                 maxMaxWidth = TypeId.DOUBLE_MAXWIDTH;
787                                 isNumericTypeId = true;
788                                 isFloatingPointTypeId = true;
789                                 break;
790
791                         case StoredFormatIds.INT_TYPE_ID:
792                                 maxPrecision = TypeId.INT_PRECISION;
793                                 maxScale = TypeId.INT_SCALE;
794                                 typePrecedence = INT_PRECEDENCE;
795                                 javaTypeName = "java.lang.Integer";
796                                 maxMaxWidth = TypeId.INT_MAXWIDTH;
797                                 isNumericTypeId = true;
798                                 break;
799
800                         case StoredFormatIds.LONGINT_TYPE_ID:
801                                 maxPrecision = TypeId.LONGINT_PRECISION;
802                                 maxScale = TypeId.LONGINT_SCALE;
803                                 typePrecedence = LONGINT_PRECEDENCE;
804                                 javaTypeName = "java.lang.Long";
805                                 maxMaxWidth = TypeId.LONGINT_MAXWIDTH;
806                                 isNumericTypeId = true;
807                                 break;
808
809                         case StoredFormatIds.LONGVARBIT_TYPE_ID:
810                                 typePrecedence = LONGVARBIT_PRECEDENCE;
811                                 javaTypeName = "byte[]";
812                                 maxMaxWidth = TypeId.LONGVARBIT_MAXWIDTH;
813                                 isBitTypeId = true;
814                                 isConcatableTypeId = true;
815                                 isLongConcatableTypeId = true;
816                                 break;
817
818                         case StoredFormatIds.LONGVARCHAR_TYPE_ID:
819                                 typePrecedence = LONGVARCHAR_PRECEDENCE;
820                                 javaTypeName = "java.lang.String";
821                                 maxMaxWidth = TypeId.LONGVARCHAR_MAXWIDTH;
822                                 isStringTypeId = true;
823                                 isConcatableTypeId = true;
824                                 isLongConcatableTypeId = true;
825                                 break;
826
827                         case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
828                                 typePrecedence = NATIONAL_CHAR_PRECEDENCE;
829                                 javaTypeName = "java.lang.String";
830                                 maxMaxWidth = TypeId.NATIONAL_CHAR_MAXWIDTH;
831                                 isStringTypeId = true;
832                                 isConcatableTypeId = true;
833                                 break;
834
835                         case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
836                                 typePrecedence = NATIONAL_LONGVARCHAR_PRECEDENCE;
837                                 javaTypeName = "java.lang.String";
838                                 maxMaxWidth = TypeId.NATIONAL_LONGVARCHAR_MAXWIDTH;
839                                 isStringTypeId = true;
840                                 isConcatableTypeId = true;
841                                 isLongConcatableTypeId = true;
842                                 break;
843
844                         case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
845                                 typePrecedence = NATIONAL_VARCHAR_PRECEDENCE;
846                                 javaTypeName = "java.lang.String";
847                                 maxMaxWidth = TypeId.NATIONAL_VARCHAR_MAXWIDTH;
848                                 isStringTypeId = true;
849                                 isConcatableTypeId = true;
850                                 break;
851
852                         case StoredFormatIds.REAL_TYPE_ID:
853                                 maxPrecision = TypeId.REAL_PRECISION;
854                                 maxScale = TypeId.REAL_SCALE;
855                                 typePrecedence = REAL_PRECEDENCE;
856                                 javaTypeName = "java.lang.Float";
857                                 maxMaxWidth = TypeId.REAL_MAXWIDTH;
858                                 isNumericTypeId = true;
859                                 isRealTypeId = true;
860                                 isFloatingPointTypeId = true;
861                                 break;
862
863                         case StoredFormatIds.REF_TYPE_ID:
864                                 typePrecedence = REF_PRECEDENCE;
865                                 isRefTypeId = true;
866                                 break;
867
868                         case StoredFormatIds.SMALLINT_TYPE_ID:
869                                 maxPrecision = TypeId.SMALLINT_PRECISION;
870                                 maxScale = TypeId.SMALLINT_SCALE;
871                                 typePrecedence = SMALLINT_PRECEDENCE;
872                                 javaTypeName = "java.lang.Integer";
873                                 maxMaxWidth = TypeId.SMALLINT_MAXWIDTH;
874                                 isNumericTypeId = true;
875                                 break;
876
877                         case StoredFormatIds.TIME_TYPE_ID:
878                                 typePrecedence = TIME_PRECEDENCE;
879                                 javaTypeName = "java.sql.Time";
880                                 maxScale = TypeId.TIME_SCALE;
881                                 maxMaxWidth = TypeId.TIME_MAXWIDTH;
882                                 maxPrecision = TypeId.TIME_MAXWIDTH;
883                                 isDateTimeTimeStampTypeId = true;
884                                 break;
885
886                         case StoredFormatIds.TIMESTAMP_TYPE_ID:
887                                 typePrecedence = TIMESTAMP_PRECEDENCE;
888                                 javaTypeName = "java.sql.Timestamp";
889                                 maxScale = TypeId.TIMESTAMP_SCALE;
890                                 maxMaxWidth = TypeId.TIMESTAMP_MAXWIDTH;
891                                 maxPrecision = TypeId.TIMESTAMP_MAXWIDTH;
892                                 isDateTimeTimeStampTypeId = true;
893                                 break;
894
895                         case StoredFormatIds.TINYINT_TYPE_ID:
896                                 maxPrecision = TypeId.TINYINT_PRECISION;
897                                 maxScale = TypeId.TINYINT_SCALE;
898                                 typePrecedence = TINYINT_PRECEDENCE;
899                                 javaTypeName = "java.lang.Integer";
900                                 maxMaxWidth = TypeId.TINYINT_MAXWIDTH;
901                                 isNumericTypeId = true;
902                                 break;
903
904                         case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
905                                 if (baseTypeId != null)
906                                 {
907                                         setUserTypeIdInfo();
908                                 }
909                                 else
910                                 {
911                                         typePrecedence = USER_PRECEDENCE;
912                                 }
913                                 maxMaxWidth = -1;
914                                 isUserDefinedTypeId = true;
915                                 break;
916
917                         case StoredFormatIds.VARBIT_TYPE_ID:
918                                 typePrecedence = VARBIT_PRECEDENCE;
919                                 javaTypeName = "byte[]";
920                                 maxMaxWidth = TypeId.VARBIT_MAXWIDTH;
921                                 isBitTypeId = true;
922                                 isConcatableTypeId = true;
923                                 break;
924
925                         case StoredFormatIds.BLOB_TYPE_ID:
926                                 typePrecedence = BLOB_PRECEDENCE;
927                                 javaTypeName = "java.sql.Blob";
928                                 maxMaxWidth = TypeId.BLOB_MAXWIDTH;
929                                 isBitTypeId = true;
930                                 isConcatableTypeId = true;
931                                 isLongConcatableTypeId = true; // ??
932
isLOBTypeId = true;
933                                 break;
934
935                         case StoredFormatIds.VARCHAR_TYPE_ID:
936                                 typePrecedence = VARCHAR_PRECEDENCE;
937                                 javaTypeName = "java.lang.String";
938                                 maxMaxWidth = TypeId.VARCHAR_MAXWIDTH;
939                                 isStringTypeId = true;
940                                 isConcatableTypeId = true;
941                                 break;
942
943                       case StoredFormatIds.CLOB_TYPE_ID:
944                               typePrecedence = CLOB_PRECEDENCE;
945                               javaTypeName = "java.sql.Clob";
946                               maxMaxWidth = TypeId.CLOB_MAXWIDTH;
947                               isStringTypeId = true;
948                               isConcatableTypeId = true;
949                               isLongConcatableTypeId = true; // ??
950
isLOBTypeId = true;
951                               break;
952
953                       case StoredFormatIds.NCLOB_TYPE_ID:
954                               typePrecedence = NCLOB_PRECEDENCE;
955                               javaTypeName = "java.sql.Clob";
956                               maxMaxWidth = TypeId.NCLOB_MAXWIDTH;
957                               isStringTypeId = true;
958                               isConcatableTypeId = true;
959                               isLongConcatableTypeId = true; // ??
960
isLOBTypeId = true;
961                               break;
962
963                       case StoredFormatIds.XML_TYPE_ID:
964
965                               typePrecedence = XML_PRECEDENCE;
966                               javaTypeName = "org.apache.derby.iapi.types.XML";
967                               maxMaxWidth = TypeId.XML_MAXWIDTH;
968
969                               // We set this to true in order to disallow use
970
// of the XML datatype for procedure/function args.
971
isLongConcatableTypeId = true;
972                               break;
973
974                 }
975         }
976         /**
977          * JDBC has its own idea of type identifiers which is different from
978          * the Cloudscape internal type ids. The JDBC type ids are defined
979          * as public final static ints in java.sql.Types. This method translates
980          * a Cloudscape internal TypeId to a JDBC type id. For java objects this
981          * returns JAVA_OBJECT in Java2 and OTHER in JDK 1.1. For Boolean datatypes,
982          * this returns Type.BOOLEAN in JDK1.4 and Type.BIT for jdks prior to 1.4
983          *
984          * @return The JDBC type Id for this type
985          */

986         public final int getJDBCTypeId()
987         {
988                 return baseTypeId.getJDBCTypeId();
989         }
990         /**
991          * Returns the SQL name of the datatype. If it is a user-defined type,
992          * it returns the full Java path name for the datatype, meaning the
993          * dot-separated path including the package names.
994          *
995          * @return A String containing the SQL name of this type.
996          */

997         public String JavaDoc getSQLTypeName()
998         {
999                 return baseTypeId.getSQLTypeName();
1000        }
1001
1002        /**
1003         * Tell whether this is a built-in type.
1004         * NOTE: There are 3 "classes" of types:
1005         * built-in - system provided types which are implemented internally
1006         * (int, smallint, etc.)
1007         * system built-in - system provided types, independent of implementation
1008         * (date, time, etc.)
1009         * user types - types implemented outside of the system
1010         * (java.lang.Integer, asdf.asdf.asdf, etc.)
1011         *
1012         * @return true for built-in types, false for user-defined types.
1013         */

1014        public final boolean userType()
1015        {
1016                return baseTypeId.userType();
1017        }
1018
1019        /**
1020         * Get the maximum precision of the type. For types with variable
1021         * precision, this is an arbitrary high precision.
1022         *
1023         * @return The maximum precision of the type
1024         */

1025        public int getMaximumPrecision()
1026        {
1027                return maxPrecision;
1028        }
1029
1030        /**
1031         * Get the maximum scale of the type. For types with variable scale,
1032         * this is an arbitrary high scale.
1033         *
1034         * @return The maximum scale of the type
1035         */

1036        public int getMaximumScale()
1037        {
1038                return maxScale;
1039        }
1040
1041        /**
1042         * Set the nested BaseTypeId in this TypeId.
1043         */

1044        public void setNestedTypeId(BaseTypeIdImpl typeId)
1045        {
1046                baseTypeId = typeId;
1047                switch (formatId)
1048                {
1049                        case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
1050                                setUserTypeIdInfo();
1051                }
1052        }
1053
1054        private void setUserTypeIdInfo()
1055        {
1056                UserDefinedTypeIdImpl baseUserTypeId =
1057                                                        (UserDefinedTypeIdImpl) baseTypeId;
1058                typePrecedence = USER_PRECEDENCE;
1059                javaTypeName = baseUserTypeId.getClassName();
1060        }
1061
1062        /**
1063         * For user types, tell whether or not the class name was a
1064         * delimited identifier. For all other types, return false.
1065         *
1066         * @return Whether or not the class name was a delimited identifier.
1067         */

1068        public boolean getClassNameWasDelimitedIdentifier()
1069        {
1070                return classNameWasDelimitedIdentifier;
1071        }
1072
1073        /**
1074         * Does this TypeId represent a TypeId for a StringDataType.
1075         *
1076         * @return Whether or not this TypeId represents a TypeId for a StringDataType.
1077         */

1078        public boolean isStringTypeId()
1079        {
1080                return isStringTypeId;
1081        }
1082
1083        /**
1084         * Is this a TypeId for DATE/TIME/TIMESTAMP
1085         *
1086         * @return true if this is a DATE/TIME/TIMESTAMP
1087         */

1088        public boolean isDateTimeTimeStampTypeId()
1089        {
1090                return isDateTimeTimeStampTypeId;
1091        }
1092
1093        /**
1094         * Is this a TypeId for REAL
1095         *
1096         * @return true if this is a REAL
1097         */

1098        public boolean isRealTypeId()
1099        {
1100                return isRealTypeId;
1101        }
1102
1103        /**
1104         * Is this a TypeId for floating point (REAL/DOUBLE)
1105         *
1106         * @return true if this is a REAL or DOUBLE
1107         */

1108        public boolean isFloatingPointTypeId()
1109        {
1110                return isFloatingPointTypeId;
1111        }
1112        
1113        /**
1114         * Is this a TypeId for DOUBLE
1115         *
1116         * @return true if this is a DOUBLE
1117         */

1118        public boolean isDoubleTypeId()
1119        {
1120                return isFloatingPointTypeId && (! isRealTypeId);
1121        }
1122    
1123        /**
1124         * Is this a fixed string type?
1125         * @return true if this is CHAR or NCHAR
1126         */

1127        public boolean isFixedStringTypeId()
1128        {
1129                return ((formatId == StoredFormatIds.CHAR_TYPE_ID)||
1130                        (formatId == StoredFormatIds.NATIONAL_CHAR_TYPE_ID));
1131        }
1132
1133        /**
1134         *Is this a Clob?
1135         * @return true if this is CLOB or NCLOB
1136         */

1137        public boolean isClobTypeId()
1138        {
1139               return ((formatId == StoredFormatIds.CLOB_TYPE_ID)||
1140                       (formatId == StoredFormatIds.NCLOB_TYPE_ID));
1141        }
1142
1143        /**
1144         *Is this a Blob?
1145         * @return true if this is BLOB
1146         */

1147        public boolean isBlobTypeId()
1148        {
1149                return ((formatId == StoredFormatIds.BLOB_TYPE_ID));
1150        }
1151
1152    
1153        /**
1154         *Is this a LongVarchar?
1155         * @return true if this is LongVarchar
1156         */

1157        public boolean isLongVarcharTypeId()
1158        {
1159                return ((formatId == StoredFormatIds.LONGVARCHAR_TYPE_ID) ||
1160                        (formatId == StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID));
1161        }
1162
1163
1164        /**
1165         * Is this DATE/TIME or TIMESTAMP?
1166         *
1167         * @return true if this DATE/TIME or TIMESTAMP
1168         */

1169        public boolean isDateTimeTimeStampTypeID()
1170        {
1171                return ((formatId == StoredFormatIds.DATE_TYPE_ID) ||
1172                        (formatId == StoredFormatIds.TIME_TYPE_ID) ||
1173                        (formatId == StoredFormatIds.TIMESTAMP_TYPE_ID));
1174        }
1175
1176        /**
1177                Does this type id represent a national character string.
1178                If this returns true then isStringTypeId will also return true.
1179        */

1180        public boolean isNationalStringTypeId()
1181        {
1182                switch (formatId)
1183                {
1184                        default:
1185                                return false;
1186
1187                        case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1188                        case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
1189                        case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1190                        case StoredFormatIds.NCLOB_TYPE_ID:
1191                                return true;
1192
1193                }
1194        }
1195
1196        /**
1197         *Is this an XML doc?
1198         * @return true if this is XML
1199         */

1200        public boolean isXMLTypeId()
1201        {
1202               return (formatId == StoredFormatIds.XML_TYPE_ID);
1203        }
1204
1205        /**
1206         * Tell whether this type is orderable, that is, can participate
1207         * in comparisons.
1208         *
1209         * @param cf A ClassFactory
1210         *
1211         * @return true for orderable types, false for non-orderable types.
1212         */

1213        public boolean orderable(ClassFactory cf)
1214        {
1215                boolean orderable;
1216                switch (formatId)
1217                {
1218                        // cmp not allowed, indexing not allowed
1219
case StoredFormatIds.BLOB_TYPE_ID:
1220                        case StoredFormatIds.CLOB_TYPE_ID:
1221                        case StoredFormatIds.NCLOB_TYPE_ID:
1222                        case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
1223                        case StoredFormatIds.LONGVARCHAR_TYPE_ID:
1224                        case StoredFormatIds.XML_TYPE_ID:
1225                        case StoredFormatIds.LONGVARBIT_TYPE_ID:
1226                                return false;
1227
1228                        case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
1229                                /* Is this type orderable? */
1230
1231                                // For user java classes we are orderable if we
1232
// implement java.lang.Orderable (JDK1.2) or
1233
// have a int compareTo(Object) method (JDK1.1 or JDK1.2)
1234
UserDefinedTypeIdImpl baseUserTypeId =
1235                                                                                (UserDefinedTypeIdImpl) baseTypeId;
1236
1237                                String JavaDoc className = baseUserTypeId.getClassName();
1238
1239                                try
1240                                {
1241                                        Class JavaDoc c = cf.getClassInspector().getClass(className);
1242                                        orderable = java.lang.Comparable JavaDoc.class.isAssignableFrom(c);
1243                                }
1244                                catch (ClassNotFoundException JavaDoc cnfe)
1245                                {
1246                                        orderable = false;
1247                                }
1248                                break;
1249
1250                        default:
1251                                orderable = true;
1252                }
1253
1254                return orderable;
1255        }
1256
1257        /**
1258         * Each built-in type in JSQL has a precedence. This precedence determines
1259         * how to do type promotion when using binary operators. For example, float
1260         * has a higher precedence than int, so when adding an int to a float, the
1261         * result type is float.
1262         *
1263         * The precedence for some types is arbitrary. For example, it doesn't
1264         * matter what the precedence of the boolean type is, since it can't be
1265         * mixed with other types. But the precedence for the number types is
1266         * critical. The SQL standard requires that exact numeric types be
1267         * promoted to approximate numeric when one operator uses both. Also,
1268         * the precedence is arranged so that one will not lose precision when
1269         * promoting a type.
1270         * NOTE: char, varchar, and longvarchar must appear at the bottom of
1271         * the hierarchy, but above USER_PRECEDENCE, since we allow the implicit
1272         * conversion of those types to any other built-in system type.
1273         *
1274         * @return The precedence of this type.
1275         */

1276        public int typePrecedence()
1277        {
1278                return typePrecedence;
1279        }
1280
1281         /**
1282         * Get the name of the corresponding Java type.
1283         *
1284         * Each SQL type has a corresponding Java type. When a SQL value is
1285         * passed to a Java method, it is translated to its corresponding Java
1286         * type. For example, when a SQL date column is passed to a method,
1287         * it is translated to a java.sql.Date.
1288         *
1289         * @return The name of the corresponding Java type.
1290         */

1291        public String JavaDoc getCorrespondingJavaTypeName()
1292        {
1293                if (SanityManager.DEBUG)
1294                {
1295                        if (formatId == StoredFormatIds.REF_TYPE_ID)
1296                        {
1297                                SanityManager.THROWASSERT("getCorrespondingJavaTypeName not implemented for StoredFormatIds.REF_TYPE_ID");
1298                        }
1299                        SanityManager.ASSERT(javaTypeName != null,
1300                                "javaTypeName expected to be non-null");
1301                }
1302                return javaTypeName;
1303        }
1304
1305         /**
1306         * Get the name of the corresponding Java type.
1307         *
1308         * This method is used directly from EmbedResultSetMetaData (jdbc)
1309         * to return the corresponding type (as choosen by getObject).
1310         * It solves a specific problem for BLOB types where the
1311         * getCorrespondingJavaTypeName() is used internall for casting
1312         * which doesn't work if changed from byte[] to java.sql.Blob.
1313         * So we do it here instread, to avoid unexpected sideeffects.
1314         *
1315         * @return The name of the corresponding Java type.
1316         */

1317        public String JavaDoc getResultSetMetaDataTypeName()
1318        {
1319            if ((BLOB_ID != null) && BLOB_ID.equals(this))
1320                return "java.sql.Blob";
1321            if ((CLOB_ID != null) && CLOB_ID.equals(this))
1322                return "java.sql.Clob";
1323            if ((NCLOB_ID != null) && NCLOB_ID.equals(this))
1324                return "java.sql.Clob";
1325            return getCorrespondingJavaTypeName();
1326        }
1327
1328        /**
1329         * Get the maximum maximum width of the type (that's not a typo). For
1330         * types with variable length, this is the absolute maximum for the type.
1331         *
1332         * @return The maximum maximum width of the type
1333         */

1334        public int getMaximumMaximumWidth()
1335        {
1336                return maxMaxWidth;
1337        }
1338
1339        /**
1340         * Converts this TypeId, given a data type descriptor (including length/precision),
1341         * to a string. E.g.
1342         *
1343         * VARCHAR(30)
1344         *
1345         *
1346         * For most data types, we just return the SQL type name.
1347         *
1348         * @param dts Data type descriptor that holds the length/precision etc. as necessary
1349         *
1350         * @return String version of datatype, suitable for running through
1351         * the Parser.
1352         */

1353        public String JavaDoc toParsableString(DataTypeDescriptor dts)
1354        {
1355                return baseTypeId.toParsableString(dts);
1356        }
1357
1358        /**
1359         * Is this a type id for a numeric type?
1360         *
1361         * @return Whether or not this a type id for a numeric type.
1362         */

1363        public boolean isNumericTypeId()
1364        {
1365                return isNumericTypeId;
1366        }
1367
1368        /**
1369         * Is this a type id for a decimal type?
1370         *
1371         * @return Whether or not this a type id for a decimal type.
1372         */

1373        public boolean isDecimalTypeId()
1374        {
1375                return isDecimalTypeId;
1376        }
1377
1378
1379        /**
1380         * Is this a type id for a boolean type?
1381         *
1382         * @return Whether or not this a type id for a boolean type.
1383         */

1384        public boolean isBooleanTypeId()
1385        {
1386                return isBooleanTypeId;
1387        }
1388
1389        /**
1390         * Is this a type id for a ref type?
1391         *
1392         * @return Whether or not this a type id for a ref type.
1393         */

1394        public boolean isRefTypeId()
1395        {
1396                return isRefTypeId;
1397        }
1398
1399        /**
1400         * Is this a type id for a concatable type?
1401         *
1402         * @return Whether or not this a type id for a concatable type.
1403         */

1404        public boolean isConcatableTypeId()
1405        {
1406                return isConcatableTypeId;
1407        }
1408
1409        /**
1410         * Is this a type id for a bit type?
1411         *
1412         * @return Whether or not this a type id for a bit type.
1413         */

1414        public boolean isBitTypeId()
1415        {
1416                return isBitTypeId;
1417        }
1418
1419        /**
1420         * Is this a type id for a LOB type?
1421         *
1422         * @return Whether or not this a type id for a LOB type.
1423         */

1424        public boolean isLOBTypeId()
1425        {
1426                return isLOBTypeId;
1427        }
1428
1429
1430        /**
1431         * Is this a type id for a long concatable type?
1432         *
1433         * @return Whether or not this a type id for a long concatable type.
1434         */

1435        public boolean isLongConcatableTypeId()
1436        {
1437                return isLongConcatableTypeId;
1438        }
1439
1440        /**
1441         * Is this a type id for a user defined type?
1442         *
1443         * @return Whether or not this a type id for a user defined type.
1444         */

1445        public boolean isUserDefinedTypeId()
1446        {
1447                return isUserDefinedTypeId;
1448        }
1449
1450        // Formatable interface
1451

1452        /**
1453         * Read this object from a stream of stored objects.
1454         *
1455         * @param in read this.
1456         *
1457         * @exception IOException thrown on error
1458         * @exception ClassNotFoundException thrown on error
1459         */

1460        public void readExternal( ObjectInput JavaDoc in )
1461                 throws IOException JavaDoc, ClassNotFoundException JavaDoc
1462        {
1463                baseTypeId = (BaseTypeIdImpl) in.readObject();
1464                /* We need to set the type specific variables
1465                 * for user types when reading back off of the
1466                 * disk becuse the baseTypeId was null when the
1467                 * 0 argument constructor was called.
1468                 */

1469                switch (formatId)
1470                {
1471                        case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
1472                                setTypeIdSpecificInstanceVariables();
1473                }
1474        }
1475
1476        /**
1477         * Write this object to a stream of stored objects.
1478         *
1479         * @param out write bytes here.
1480         *
1481         * @exception IOException thrown on error
1482         */

1483        public void writeExternal( ObjectOutput JavaDoc out )
1484                 throws IOException JavaDoc
1485        {
1486                out.writeObject( baseTypeId );
1487        }
1488
1489        /**
1490         * Get the formatID which corresponds to this class.
1491         *
1492         * @return the formatID of this class
1493         */

1494        public int getTypeFormatId()
1495        {
1496                return formatId;
1497        }
1498
1499
1500        /**
1501         * Get SQL null value.
1502         * @return SQL null value for this type.
1503         */

1504        public DataValueDescriptor getNull()
1505        {
1506                switch (formatId)
1507                {
1508                        case StoredFormatIds.BIT_TYPE_ID:
1509                                return new SQLBit();
1510
1511                        case StoredFormatIds.BOOLEAN_TYPE_ID:
1512                                return new SQLBoolean();
1513
1514                        case StoredFormatIds.CHAR_TYPE_ID:
1515                                return new SQLChar();
1516
1517                        // Implementation of DECIMAL can change.
1518
case StoredFormatIds.DECIMAL_TYPE_ID:
1519                            return decimalImplementation.getNewNull();
1520
1521                        case StoredFormatIds.DOUBLE_TYPE_ID:
1522                                return new SQLDouble();
1523
1524                        case StoredFormatIds.INT_TYPE_ID:
1525                                return new SQLInteger();
1526
1527                        case StoredFormatIds.LONGINT_TYPE_ID:
1528                                return new SQLLongint();
1529
1530                        case StoredFormatIds.LONGVARBIT_TYPE_ID:
1531                                return new SQLLongVarbit();
1532
1533                        case StoredFormatIds.BLOB_TYPE_ID:
1534                                return new SQLBlob();
1535
1536                        case StoredFormatIds.CLOB_TYPE_ID:
1537                                return new SQLClob();
1538
1539                        case StoredFormatIds.NCLOB_TYPE_ID:
1540                                return new SQLNClob();
1541
1542                        case StoredFormatIds.LONGVARCHAR_TYPE_ID:
1543                                return new SQLLongvarchar();
1544
1545                        case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1546                                return new SQLNationalChar();
1547
1548                        case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1549                                return new SQLNationalVarchar();
1550
1551                        case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
1552                                return new SQLNationalLongvarchar();
1553
1554                        case StoredFormatIds.REAL_TYPE_ID:
1555                                return new SQLReal();
1556
1557                        case StoredFormatIds.REF_TYPE_ID:
1558                                return new SQLRef();
1559
1560                        case StoredFormatIds.SMALLINT_TYPE_ID:
1561                                return new SQLSmallint();
1562
1563                        case StoredFormatIds.TINYINT_TYPE_ID:
1564                                return new SQLTinyint();
1565
1566                        case StoredFormatIds.DATE_TYPE_ID:
1567                                return new SQLDate();
1568
1569                        case StoredFormatIds.TIME_TYPE_ID:
1570                                return new SQLTime();
1571
1572                        case StoredFormatIds.TIMESTAMP_TYPE_ID:
1573                                return new SQLTimestamp();
1574
1575                        case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
1576                                return new UserType();
1577
1578                        case StoredFormatIds.VARBIT_TYPE_ID:
1579                                return new SQLVarbit();
1580
1581                        case StoredFormatIds.VARCHAR_TYPE_ID:
1582                                return new SQLVarchar();
1583
1584                        case StoredFormatIds.XML_TYPE_ID:
1585                                return new XML();
1586
1587                        default:
1588                                if (SanityManager.DEBUG)
1589                                {
1590                                        SanityManager.THROWASSERT(
1591                                                "unexpected formatId in getNull() - " + formatId);
1592                                }
1593                                return null;
1594                }
1595        }
1596        /**
1597         * Is this type StreamStorable?
1598         *
1599         * @return true if this type has variable length.
1600         */

1601        public boolean streamStorable() {
1602                return isStringTypeId() || isBitTypeId();
1603        }
1604
1605
1606        //
1607
// Class methods
1608
//
1609

1610        /**
1611         * Get the approximate length of this type in bytes.
1612         * For most datatypes this is just going to be
1613         * dts.getMaximumWidth(). Some types, such as
1614         * bit, will override this.
1615         *
1616         * @param dts Data type descriptor that holds the
1617         * length/precision etc. as necessary
1618         *
1619         * @return the length in bytes
1620         */

1621        public int getApproximateLengthInBytes(DataTypeDescriptor dts)
1622        {
1623                switch (formatId)
1624                {
1625                        case StoredFormatIds.BIT_TYPE_ID:
1626                                return (int)(Math.ceil(dts.getMaximumWidth()/8d));
1627
1628                        case StoredFormatIds.CHAR_TYPE_ID:
1629                        case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1630                                return (2 * dts.getMaximumWidth()) + 2;
1631
1632                        case StoredFormatIds.DECIMAL_TYPE_ID:
1633                                // Return 200 if precision is max int
1634
if (dts.getPrecision() == Integer.MAX_VALUE)
1635                                {
1636                                        return 200;
1637                                }
1638                                else
1639                                {
1640                                        return 8 + (int) (Math.ceil(((double)dts.getPrecision())/2d));
1641                                }
1642
1643                        case StoredFormatIds.LONGVARBIT_TYPE_ID:
1644                        case StoredFormatIds.BLOB_TYPE_ID:
1645                        case StoredFormatIds.CLOB_TYPE_ID:
1646                        case StoredFormatIds.NCLOB_TYPE_ID:
1647                        // RESOLVE: Should XML be here? What's this value mean, anyway?
1648
case StoredFormatIds.XML_TYPE_ID:
1649                                return 10240;
1650
1651                        case StoredFormatIds.REF_TYPE_ID:
1652                                return 16;
1653
1654                        case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
1655                                /* For user types we'll guess on the high side
1656                                ** (200) to avoid being too low in most cases.
1657                                */

1658                                return 200;
1659
1660                        case StoredFormatIds.VARBIT_TYPE_ID:
1661                                // Return 200 if maximum width is max int
1662
if (dts.getMaximumWidth() == Integer.MAX_VALUE)
1663                                {
1664                                        return 200;
1665                                }
1666                                else
1667                                {
1668                                        return (int)(Math.ceil(dts.getMaximumWidth()/8d));
1669                                }
1670
1671                        case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1672                        case StoredFormatIds.VARCHAR_TYPE_ID:
1673                        case StoredFormatIds.LONGVARCHAR_TYPE_ID:
1674                        case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
1675                                // Return 200 if maximum width is max int
1676
if (dts.getMaximumWidth() == Integer.MAX_VALUE)
1677                                {
1678                                        return 200;
1679                                }
1680                                else
1681                                {
1682                                        return (dts.getMaximumWidth() * 2) + 2;
1683                                }
1684                        /*
1685                        ** For Date/time we know the exact size
1686                        ** thanks to some investigative work by
1687                        ** someone or other (sad isn't it).
1688                        */

1689                        case StoredFormatIds.DATE_TYPE_ID:
1690                                return 18;
1691                        case StoredFormatIds.TIME_TYPE_ID:
1692                                return 16;
1693                        case StoredFormatIds.TIMESTAMP_TYPE_ID:
1694                                return 29;
1695
1696                        default:
1697                                return dts.getMaximumWidth();
1698                }
1699        }
1700
1701        /**
1702         * Get the base type id that is embedded in this type id. The base type
1703         * id is an object with a minimal implementation of TypeId that is intended
1704         * to be usable on the client side.
1705         */

1706        public BaseTypeIdImpl getBaseTypeId()
1707        {
1708                return baseTypeId;
1709        }
1710
1711        /**
1712         * Get the precision of the merge of two Decimals
1713         *
1714         * @param leftType the left type
1715         * @param rightType the left type
1716         *
1717         * @return the resultant precision
1718         */

1719        public int getPrecision(DataTypeDescriptor leftType,
1720                                        DataTypeDescriptor rightType)
1721        {
1722                if (SanityManager.DEBUG)
1723                {
1724                        if (formatId != StoredFormatIds.DECIMAL_TYPE_ID)
1725                        {
1726                                SanityManager.THROWASSERT(
1727                                        "getPrecision() not expected to be called for formatId - " + formatId);
1728                        }
1729                }
1730                long lscale = (long)leftType.getScale();
1731                long rscale = (long)rightType.getScale();
1732                long lprec = (long)leftType.getPrecision();
1733                long rprec = (long)rightType.getPrecision();
1734                long val;
1735
1736                /*
1737                ** Take the maximum left of decimal digits plus the scale.
1738                */

1739                val = this.getScale(leftType, rightType) +
1740                                        Math.max(lprec - lscale, rprec - rscale);
1741
1742                if (val > Integer.MAX_VALUE)
1743                {
1744                        val = Integer.MAX_VALUE;
1745                }
1746                return (int)val;
1747        }
1748
1749        /**
1750         * Get the scale of the merge of two decimals
1751         *
1752         * @param leftType the left type
1753         * @param rightType the left type
1754         *
1755         * @return the resultant precision
1756         */

1757        public int getScale(DataTypeDescriptor leftType,
1758                                                DataTypeDescriptor rightType)
1759        {
1760                if (SanityManager.DEBUG)
1761                {
1762                        if (formatId != StoredFormatIds.DECIMAL_TYPE_ID)
1763                        {
1764                                SanityManager.THROWASSERT(
1765                                        "getPrecision() not expected to be called for formatId - " + formatId);
1766                        }
1767                }
1768                /*
1769                ** Retain greatest scale
1770                */

1771                return Math.max(leftType.getScale(), rightType.getScale());
1772        }
1773
1774        /**
1775         * Does type hava a declared variable length (defined by the application).
1776         * Examples are CHAR(10), CLOB(1M).
1777         * Unbounded long types, like LONG VARCHAR return false here.
1778         * @return boolean true if type is variable length false if not.
1779         */

1780        public boolean variableLength()
1781        {
1782                switch (formatId)
1783                {
1784                        case StoredFormatIds.BIT_TYPE_ID:
1785                        case StoredFormatIds.VARBIT_TYPE_ID:
1786                        case StoredFormatIds.DECIMAL_TYPE_ID:
1787                        case StoredFormatIds.CHAR_TYPE_ID:
1788                        case StoredFormatIds.VARCHAR_TYPE_ID:
1789                        case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
1790                        case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
1791                        case StoredFormatIds.BLOB_TYPE_ID:
1792                        case StoredFormatIds.CLOB_TYPE_ID:
1793                                 return true;
1794
1795                        default:
1796                                return false;
1797                }
1798        }
1799}
1800
1801
Popular Tags