Source Code Cross Referenced for DataTypeDescriptor.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » iapi » types » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.iapi.types 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.iapi.types.DataTypeDescriptor
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to you under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.iapi.types;
0023:
0024:        import org.apache.derby.iapi.services.io.Formatable;
0025:        import org.apache.derby.iapi.error.StandardException;
0026:        import org.apache.derby.iapi.services.loader.ClassFactory;
0027:
0028:        import org.apache.derby.catalog.TypeDescriptor;
0029:        import org.apache.derby.catalog.types.TypeDescriptorImpl;
0030:
0031:        import org.apache.derby.iapi.services.sanity.SanityManager;
0032:
0033:        import org.apache.derby.iapi.services.io.StoredFormatIds;
0034:        import org.apache.derby.iapi.services.io.FormatIdUtil;
0035:        import org.apache.derby.iapi.services.io.Formatable;
0036:
0037:        import org.apache.derby.iapi.error.StandardException;
0038:
0039:        import org.apache.derby.iapi.types.RowLocation;
0040:
0041:        import org.apache.derby.iapi.services.loader.ClassFactory;
0042:        import org.apache.derby.iapi.services.loader.ClassInspector;
0043:
0044:        import org.apache.derby.iapi.reference.SQLState;
0045:
0046:        import java.io.ObjectOutput;
0047:        import java.io.ObjectInput;
0048:        import java.io.IOException;
0049:
0050:        import java.sql.Types;
0051:
0052:        /**
0053:         * This is an implementation of DataTypeDescriptor from the generic language
0054:         * datatype module interface.
0055:         *
0056:         * @author Jeff Lichtman
0057:         * @version 1.0
0058:         */
0059:
0060:        public final class DataTypeDescriptor implements  TypeDescriptor,
0061:                Formatable {
0062:            /********************************************************
0063:             **
0064:             **	This class implements Formatable. That means that it
0065:             **	can write itself to and from a formatted stream. If
0066:             **	you add more fields to this class, make sure that you
0067:             **	also write/read them with the writeExternal()/readExternal()
0068:             **	methods.
0069:             **
0070:             **	If, inbetween releases, you add more fields to this class,
0071:             **	then you should bump the version number emitted by the getTypeFormatId()
0072:             **	method.
0073:             **
0074:             ********************************************************/
0075:
0076:            /*
0077:             ** Static creators
0078:             */
0079:            /**
0080:             * Get a descriptor that corresponds to a builtin JDBC type.
0081:             *
0082:             * @param jdbcType	The int type of the JDBC type for which to get
0083:             *						a corresponding SQL DataTypeDescriptor
0084:             *
0085:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0086:             *			A null return value means there is no corresponding SQL type
0087:             */
0088:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0089:                    int jdbcType) {
0090:                return DataTypeDescriptor.getBuiltInDataTypeDescriptor(
0091:                        jdbcType, true);
0092:            }
0093:
0094:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0095:                    int jdbcType, int length) {
0096:                return DataTypeDescriptor.getBuiltInDataTypeDescriptor(
0097:                        jdbcType, true, length);
0098:            }
0099:
0100:            /**
0101:             * Get a descriptor that corresponds to a builtin JDBC type.
0102:             *
0103:             * @param jdbcType	The int type of the JDBC type for which to get
0104:             *						a corresponding SQL DataTypeDescriptor
0105:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0106:             *			it definitely cannot contain NULL.
0107:             *
0108:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0109:             *			A null return value means there is no corresponding SQL type
0110:             */
0111:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0112:                    int jdbcType, boolean isNullable) {
0113:                TypeId typeId = TypeId.getBuiltInTypeId(jdbcType);
0114:                if (typeId == null) {
0115:                    return null;
0116:                }
0117:
0118:                return new DataTypeDescriptor(typeId, isNullable);
0119:            }
0120:
0121:            /**
0122:             * Get a descriptor that corresponds to a builtin JDBC type.
0123:             *
0124:             * @param jdbcType	The int type of the JDBC type for which to get
0125:             *						a corresponding SQL DataTypeDescriptor
0126:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0127:             *			it definitely cannot contain NULL.
0128:             *
0129:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0130:             *			A null return value means there is no corresponding SQL type
0131:             */
0132:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0133:                    int jdbcType, boolean isNullable, int maxLength) {
0134:                TypeId typeId = TypeId.getBuiltInTypeId(jdbcType);
0135:                if (typeId == null) {
0136:                    return null;
0137:                }
0138:
0139:                return new DataTypeDescriptor(typeId, isNullable, maxLength);
0140:            }
0141:
0142:            /**
0143:             * Get a DataTypeServices that corresponds to a builtin SQL type
0144:             *
0145:             * @param sqlTypeName	The name of the type for which to get
0146:             *						a corresponding SQL DataTypeDescriptor
0147:             *
0148:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0149:             *			A null return value means there is no corresponding SQL type (only for 'char')
0150:             */
0151:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0152:                    String sqlTypeName) {
0153:                return new DataTypeDescriptor(TypeId
0154:                        .getBuiltInTypeId(sqlTypeName), true);
0155:            }
0156:
0157:            /**
0158:             * Get a DataTypeServices that corresponds to a builtin SQL type
0159:             *
0160:             * @param sqlTypeName	The name of the type for which to get
0161:             *						a corresponding SQL DataTypeDescriptor
0162:             *
0163:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0164:             *			A null return value means there is no corresponding SQL type (only for 'char')
0165:             */
0166:            public static DataTypeDescriptor getBuiltInDataTypeDescriptor(
0167:                    String sqlTypeName, int length) {
0168:                return new DataTypeDescriptor(TypeId
0169:                        .getBuiltInTypeId(sqlTypeName), true, length);
0170:            }
0171:
0172:            /**
0173:             * Get a DataTypeServices that corresponds to a Java type
0174:             *
0175:             * @param javaTypeName	The name of the Java type for which to get
0176:             *						a corresponding SQL DataTypeDescriptor
0177:             *
0178:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0179:             *			A null return value means there is no corresponding SQL type (only for 'char')
0180:             */
0181:            public static DataTypeDescriptor getSQLDataTypeDescriptor(
0182:                    String javaTypeName) {
0183:                return DataTypeDescriptor.getSQLDataTypeDescriptor(
0184:                        javaTypeName, true);
0185:            }
0186:
0187:            /**
0188:             * Get a DataTypeServices that corresponds to a Java type
0189:             *
0190:             * @param javaTypeName	The name of the Java type for which to get
0191:             *						a corresponding SQL DataTypeDescriptor
0192:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0193:             *			it definitely cannot contain NULL.
0194:             *
0195:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0196:             *			A null return value means there is no corresponding SQL type (only for 'char')
0197:             */
0198:            public static DataTypeDescriptor getSQLDataTypeDescriptor(
0199:                    String javaTypeName, boolean isNullable) {
0200:                TypeId typeId = TypeId.getSQLTypeForJavaType(javaTypeName);
0201:                if (typeId == null) {
0202:                    return null;
0203:                }
0204:
0205:                return new DataTypeDescriptor(typeId, isNullable);
0206:            }
0207:
0208:            /**
0209:             * Get a DataTypeDescriptor that corresponds to a Java type
0210:             *
0211:             * @param javaTypeName	The name of the Java type for which to get
0212:             *						a corresponding SQL DataTypeDescriptor
0213:             * @param precision	The number of decimal digits
0214:             * @param scale		The number of digits after the decimal point
0215:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0216:             *			it definitely cannot contain NULL.
0217:             * @param maximumWidth	The maximum width of a data value
0218:             *			represented by this type.
0219:             *
0220:             * @return	A new DataTypeDescriptor that corresponds to the Java type.
0221:             *			A null return value means there is no corresponding SQL type.
0222:             */
0223:            public static DataTypeDescriptor getSQLDataTypeDescriptor(
0224:                    String javaTypeName, int precision, int scale,
0225:                    boolean isNullable, int maximumWidth) {
0226:                TypeId typeId = TypeId.getSQLTypeForJavaType(javaTypeName);
0227:                if (typeId == null) {
0228:                    return null;
0229:                }
0230:
0231:                return new DataTypeDescriptor(typeId, precision, scale,
0232:                        isNullable, maximumWidth);
0233:            }
0234:
0235:            /*
0236:             ** Instance fields & methods
0237:             */
0238:
0239:            private TypeDescriptorImpl typeDescriptor;
0240:            private TypeId typeId;
0241:
0242:            /**
0243:             * Public niladic constructor. Needed for Formatable interface to work.
0244:             *
0245:             */
0246:            public DataTypeDescriptor() {
0247:            }
0248:
0249:            /**
0250:             * Constructor for use with numeric types
0251:             *
0252:             * @param typeId	The typeId of the type being described
0253:             * @param precision	The number of decimal digits.
0254:             * @param scale		The number of digits after the decimal point.
0255:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0256:             *			it definitely cannot contain NULL.
0257:             * @param maximumWidth	The maximum number of bytes for this datatype
0258:             */
0259:            public DataTypeDescriptor(TypeId typeId, int precision, int scale,
0260:                    boolean isNullable, int maximumWidth) {
0261:                this .typeId = typeId;
0262:                typeDescriptor = new TypeDescriptorImpl(typeId.getBaseTypeId(),
0263:                        precision, scale, isNullable, maximumWidth);
0264:            }
0265:
0266:            /**
0267:             * Constructor for use with non-numeric types
0268:             *
0269:             * @param typeId	The typeId of the type being described
0270:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0271:             *			it definitely cannot contain NULL.
0272:             * @param maximumWidth	The maximum number of bytes for this datatype
0273:             */
0274:            public DataTypeDescriptor(TypeId typeId, boolean isNullable,
0275:                    int maximumWidth) {
0276:                this .typeId = typeId;
0277:                typeDescriptor = new TypeDescriptorImpl(typeId.getBaseTypeId(),
0278:                        isNullable, maximumWidth);
0279:            }
0280:
0281:            public DataTypeDescriptor(TypeId typeId, boolean isNullable) {
0282:
0283:                this .typeId = typeId;
0284:                typeDescriptor = new TypeDescriptorImpl(typeId.getBaseTypeId(),
0285:                        typeId.getMaximumPrecision(), typeId.getMaximumScale(),
0286:                        isNullable, typeId.getMaximumMaximumWidth());
0287:            }
0288:
0289:            public DataTypeDescriptor(DataTypeDescriptor source,
0290:                    boolean isNullable) {
0291:                this .typeId = source.typeId;
0292:                typeDescriptor = new TypeDescriptorImpl(source.typeDescriptor,
0293:                        source.getPrecision(), source.getScale(), isNullable,
0294:                        source.getMaximumWidth());
0295:            }
0296:
0297:            /**
0298:             * Constructor for internal uses only.  
0299:             * (This is useful when the precision and scale are potentially wider than
0300:             * those in the source, like when determining the dominant data type.)
0301:             *
0302:             * @param source	The DTSI to copy
0303:             * @param precision	The number of decimal digits.
0304:             * @param scale		The number of digits after the decimal point.
0305:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0306:             *			it definitely cannot contain NULL.
0307:             * @param maximumWidth	The maximum number of bytes for this datatype
0308:             */
0309:            public DataTypeDescriptor(DataTypeDescriptor source, int precision,
0310:                    int scale, boolean isNullable, int maximumWidth) {
0311:                this .typeId = source.typeId;
0312:                typeDescriptor = new TypeDescriptorImpl(source.typeDescriptor,
0313:                        precision, scale, isNullable, maximumWidth);
0314:            }
0315:
0316:            /**
0317:             * Constructor for internal uses only
0318:             *
0319:             * @param source	The DTSI to copy
0320:             * @param isNullable	TRUE means it could contain NULL, FALSE means
0321:             *			it definitely cannot contain NULL.
0322:             * @param maximumWidth	The maximum number of bytes for this datatype
0323:             */
0324:            public DataTypeDescriptor(DataTypeDescriptor source,
0325:                    boolean isNullable, int maximumWidth) {
0326:                this .typeId = source.typeId;
0327:                typeDescriptor = new TypeDescriptorImpl(source.typeDescriptor,
0328:                        isNullable, maximumWidth);
0329:            }
0330:
0331:            /**
0332:             * Constructor for use in reconstructing a DataTypeDescriptor from a
0333:             * TypeDescriptorImpl and a TypeId
0334:             *
0335:             * @param source	The TypeDescriptorImpl to construct this DTSI from
0336:             */
0337:            public DataTypeDescriptor(TypeDescriptorImpl source, TypeId typeId) {
0338:                typeDescriptor = source;
0339:                this .typeId = typeId;
0340:                ;
0341:            }
0342:
0343:            /* DataTypeDescriptor Interface */
0344:            public DataValueDescriptor normalize(DataValueDescriptor source,
0345:                    DataValueDescriptor cachedDest) throws StandardException {
0346:                if (SanityManager.DEBUG) {
0347:                    if (cachedDest != null) {
0348:                        if (!getTypeId().isUserDefinedTypeId()) {
0349:                            String t1 = getTypeName();
0350:                            String t2 = cachedDest.getTypeName();
0351:                            if (!t1.equals(t2)) {
0352:
0353:                                if (!(((t1.equals("DECIMAL") || t1
0354:                                        .equals("NUMERIC")) && (t2
0355:                                        .equals("DECIMAL") || t2
0356:                                        .equals("NUMERIC"))) || (t1
0357:                                        .startsWith("INT") && t2
0358:                                        .startsWith("INT")))) //INT/INTEGER
0359:
0360:                                    SanityManager
0361:                                            .THROWASSERT("Normalization of "
0362:                                                    + t2
0363:                                                    + " being asked to convert to "
0364:                                                    + t1);
0365:                            }
0366:                        }
0367:                    }
0368:                }
0369:
0370:                if (source.isNull()) {
0371:                    if (!isNullable())
0372:                        throw StandardException.newException(
0373:                                SQLState.LANG_NULL_INTO_NON_NULL, "");
0374:
0375:                    if (cachedDest == null)
0376:                        cachedDest = getNull();
0377:                    else
0378:                        cachedDest.setToNull();
0379:                } else {
0380:
0381:                    if (cachedDest == null)
0382:                        cachedDest = getNull();
0383:
0384:                    int jdbcId = getJDBCTypeId();
0385:
0386:                    cachedDest.normalize(this , source);
0387:                    //doing the following check after normalize so that normalize method would get called on long varchs and long varbinary
0388:                    //Need normalize to be called on long varchar for bug 5592 where we need to enforce a lenght limit in db2 mode
0389:                    if ((jdbcId == Types.LONGVARCHAR)
0390:                            || (jdbcId == Types.LONGVARBINARY)) {
0391:                        // special case for possible streams
0392:                        if (source.getClass() == cachedDest.getClass())
0393:                            return source;
0394:                    }
0395:
0396:                }
0397:                return cachedDest;
0398:            }
0399:
0400:            /**
0401:             * Get the dominant type (DataTypeDescriptor) of the 2.
0402:             * For variable length types, the resulting type will have the
0403:             * biggest max length of the 2.
0404:             * If either side is nullable, then the result will also be nullable.
0405:             *
0406:             * @param otherDTS	DataTypeDescriptor to compare with.
0407:             * @param cf		A ClassFactory
0408:             *
0409:             * @return DataTypeDescriptor  DTS for dominant type
0410:             *
0411:             * @exception StandardException		Thrown on error
0412:             */
0413:            public DataTypeDescriptor getDominantType(
0414:                    DataTypeDescriptor otherDTS, ClassFactory cf)
0415:                    throws StandardException {
0416:                boolean nullable;
0417:                TypeId this Type;
0418:                TypeId otherType;
0419:                DataTypeDescriptor higherType = null;
0420:                DataTypeDescriptor lowerType = null;
0421:                int maximumWidth;
0422:                int precision = getPrecision();
0423:                int scale = getScale();
0424:
0425:                this Type = getTypeId();
0426:                otherType = otherDTS.getTypeId();
0427:
0428:                /* The result is nullable if either side is nullable */
0429:                nullable = isNullable() || otherDTS.isNullable();
0430:
0431:                /*
0432:                 ** The result will have the maximum width of both sides
0433:                 */
0434:                maximumWidth = (getMaximumWidth() > otherDTS.getMaximumWidth()) ? getMaximumWidth()
0435:                        : otherDTS.getMaximumWidth();
0436:
0437:                /* We need 2 separate methods of determining type dominance - 1 if both
0438:                 * types are system built-in types and the other if at least 1 is
0439:                 * a user type. (typePrecedence is meaningless for user types.)
0440:                 */
0441:                if (!this Type.userType() && !otherType.userType()) {
0442:                    TypeId higherTypeId;
0443:                    TypeId lowerTypeId;
0444:                    if (this Type.typePrecedence() > otherType.typePrecedence()) {
0445:                        higherType = this ;
0446:                        lowerType = otherDTS;
0447:                        higherTypeId = this Type;
0448:                        lowerTypeId = otherType;
0449:                    } else {
0450:                        higherType = otherDTS;
0451:                        lowerType = this ;
0452:                        higherTypeId = otherType;
0453:                        lowerTypeId = this Type;
0454:                    }
0455:
0456:                    //Following is checking if higher type argument is real and other argument is decimal/bigint/integer/smallint,
0457:                    //then result type should be double
0458:                    if (higherTypeId.isRealTypeId()
0459:                            && (!lowerTypeId.isRealTypeId())
0460:                            && lowerTypeId.isNumericTypeId()) {
0461:                        higherType = DataTypeDescriptor
0462:                                .getBuiltInDataTypeDescriptor(Types.DOUBLE);
0463:                        higherTypeId = TypeId.getBuiltInTypeId(Types.DOUBLE);
0464:                    }
0465:                    /*
0466:                     ** If we have a DECIMAL/NUMERIC we have to do some
0467:                     ** extra work to make sure the resultant type can
0468:                     ** handle the maximum values for the two input
0469:                     ** types.  We cannot just take the maximum for
0470:                     ** precision.  E.g. we want something like:
0471:                     **
0472:                     **		DEC(10,10) and DEC(3,0) => DEC(13,10)
0473:                     **
0474:                     ** (var)char type needs some conversion handled later.
0475:                     */
0476:                    if (higherTypeId.isDecimalTypeId()
0477:                            && (!lowerTypeId.isStringTypeId())) {
0478:                        precision = higherTypeId.getPrecision(this , otherDTS);
0479:                        if (precision > 31)
0480:                            precision = 31; //db2 silently does this and so do we
0481:                        scale = higherTypeId.getScale(this , otherDTS);
0482:
0483:                        /* maximumWidth needs to count possible leading '-' and
0484:                         * decimal point and leading '0' if scale > 0.  See also
0485:                         * sqlgrammar.jj(exactNumericType).  Beetle 3875
0486:                         */
0487:                        maximumWidth = (scale > 0) ? precision + 3
0488:                                : precision + 1;
0489:                    } else if (this Type.typePrecedence() != otherType
0490:                            .typePrecedence()) {
0491:                        precision = higherType.getPrecision();
0492:                        scale = higherType.getScale();
0493:
0494:                        /* GROSS HACKS:
0495:                         * If we are doing an implicit (var)char->(var)bit conversion
0496:                         * then the maximum width for the (var)char as a (var)bit
0497:                         * is really 16 * its width as a (var)char.  Adjust
0498:                         * maximumWidth accordingly.
0499:                         * If we are doing an implicit (var)char->decimal conversion
0500:                         * then we need to increment the decimal's precision by
0501:                         * 2 * the maximum width for the (var)char and the scale
0502:                         * by the maximum width for the (var)char. The maximumWidth
0503:                         * becomes the new precision + 3.  This is because
0504:                         * the (var)char could contain any decimal value from XXXXXX
0505:                         * to 0.XXXXX.  (In other words, we don't know which side of the
0506:                         * decimal point the characters will be on.)
0507:                         */
0508:                        if (lowerTypeId.isStringTypeId()) {
0509:                            if (higherTypeId.isBitTypeId()
0510:                                    && !(higherTypeId.isLongConcatableTypeId())) {
0511:                                if (lowerTypeId.isLongConcatableTypeId()) {
0512:                                    if (maximumWidth > (Integer.MAX_VALUE / 16))
0513:                                        maximumWidth = Integer.MAX_VALUE;
0514:                                    else
0515:                                        maximumWidth *= 16;
0516:                                } else {
0517:                                    int charMaxWidth;
0518:
0519:                                    int fromWidth = lowerType.getMaximumWidth();
0520:                                    if (fromWidth > (Integer.MAX_VALUE / 16))
0521:                                        charMaxWidth = Integer.MAX_VALUE;
0522:                                    else
0523:                                        charMaxWidth = 16 * fromWidth;
0524:
0525:                                    maximumWidth = (maximumWidth >= charMaxWidth) ? maximumWidth
0526:                                            : charMaxWidth;
0527:                                }
0528:                            }
0529:                        }
0530:
0531:                        /*
0532:                         * If we are doing an implicit (var)char->decimal conversion
0533:                         * then the resulting decimal's precision could be as high as 
0534:                         * 2 * the maximum width (precisely 2mw-1) for the (var)char
0535:                         * and the scale could be as high as the maximum width
0536:                         * (precisely mw-1) for the (var)char.
0537:                         * The maximumWidth becomes the new precision + 3.  This is
0538:                         * because the (var)char could contain any decimal value from
0539:                         * XXXXXX to 0.XXXXX.  (In other words, we don't know which
0540:                         * side of the decimal point the characters will be on.)
0541:                         *
0542:                         * We don't follow this algorithm for long varchar because the
0543:                         * maximum length of a long varchar is maxint, and we don't
0544:                         * want to allocate a huge decimal value.  So in this case,
0545:                         * the precision, scale, and maximum width all come from
0546:                         * the decimal type.
0547:                         */
0548:                        if (lowerTypeId.isStringTypeId()
0549:                                && !(lowerTypeId.isLongConcatableTypeId())
0550:                                && higherTypeId.isDecimalTypeId()) {
0551:                            int charMaxWidth = lowerType.getMaximumWidth();
0552:                            int charPrecision;
0553:
0554:                            /*
0555:                             ** Be careful not to overflow when calculating the
0556:                             ** precision.  Remember that we will be adding
0557:                             ** three to the precision to get the maximum width.
0558:                             */
0559:                            if (charMaxWidth > (Integer.MAX_VALUE - 3) / 2)
0560:                                charPrecision = Integer.MAX_VALUE - 3;
0561:                            else
0562:                                charPrecision = charMaxWidth * 2;
0563:
0564:                            if (precision < charPrecision)
0565:                                precision = charPrecision;
0566:
0567:                            if (scale < charMaxWidth)
0568:                                scale = charMaxWidth;
0569:
0570:                            maximumWidth = precision + 3;
0571:                        }
0572:                    }
0573:                } else {
0574:                    /* At least 1 type is not a system built-in type */
0575:                    ClassInspector cu = cf.getClassInspector();
0576:
0577:                    TypeId this CompType = (TypeId) this Type;
0578:                    TypeId otherCompType = (TypeId) otherType;
0579:
0580:                    if (cu.assignableTo(this CompType
0581:                            .getCorrespondingJavaTypeName(), otherCompType
0582:                            .getCorrespondingJavaTypeName())) {
0583:                        higherType = otherDTS;
0584:                    } else {
0585:                        if (SanityManager.DEBUG)
0586:                            SanityManager
0587:                                    .ASSERT(
0588:                                            cu
0589:                                                    .assignableTo(
0590:                                                            otherCompType
0591:                                                                    .getCorrespondingJavaTypeName(),
0592:                                                            this CompType
0593:                                                                    .getCorrespondingJavaTypeName()),
0594:                                            otherCompType
0595:                                                    .getCorrespondingJavaTypeName()
0596:                                                    + " expected to be assignable to "
0597:                                                    + this CompType
0598:                                                            .getCorrespondingJavaTypeName());
0599:
0600:                        higherType = this ;
0601:                    }
0602:                    precision = higherType.getPrecision();
0603:                    scale = higherType.getScale();
0604:                }
0605:
0606:                higherType = new DataTypeDescriptor(higherType, precision,
0607:                        scale, nullable, maximumWidth);
0608:
0609:                return higherType;
0610:            }
0611:
0612:            /**
0613:             * Check whether or not the 2 types (DataTypeDescriptor) have the same type
0614:             * and length.
0615:             * This is useful for UNION when trying to decide whether a NormalizeResultSet
0616:             * is required.
0617:             *
0618:             * @param otherDTS	DataTypeDescriptor to compare with.
0619:             *
0620:             * @return boolean  Whether or not the 2 DTSs have the same type and length.
0621:             */
0622:            public boolean isExactTypeAndLengthMatch(DataTypeDescriptor otherDTS) {
0623:                /* Do both sides have the same length? */
0624:                if (getMaximumWidth() != otherDTS.getMaximumWidth()) {
0625:                    return false;
0626:                }
0627:                if (getScale() != otherDTS.getScale()) {
0628:                    return false;
0629:                }
0630:
0631:                if (getPrecision() != otherDTS.getPrecision()) {
0632:                    return false;
0633:                }
0634:
0635:                TypeId this Type = getTypeId();
0636:                TypeId otherType = otherDTS.getTypeId();
0637:
0638:                /* Do both sides have the same type? */
0639:                if (!this Type.equals(otherType)) {
0640:                    return false;
0641:                }
0642:
0643:                return true;
0644:            }
0645:
0646:            /**
0647:             * @see TypeDescriptor#getMaximumWidth
0648:             */
0649:            public int getMaximumWidth() {
0650:                return typeDescriptor.getMaximumWidth();
0651:            }
0652:
0653:            /**
0654:             * @see TypeDescriptor#getMaximumWidthInBytes
0655:             */
0656:            public int getMaximumWidthInBytes() {
0657:                return typeDescriptor.getMaximumWidthInBytes();
0658:            }
0659:
0660:            /**
0661:             * Gets the TypeId for the datatype.
0662:             *
0663:             * @return	The TypeId for the datatype.
0664:             */
0665:            public TypeId getTypeId() {
0666:                return typeId;
0667:            }
0668:
0669:            /**
0670:            	Get a Null for this type.
0671:             */
0672:            public DataValueDescriptor getNull() {
0673:                return typeId.getNull();
0674:            }
0675:
0676:            /**
0677:             * Gets the name of this datatype.
0678:             * 
0679:             *
0680:             *  @return	the name of this datatype
0681:             */
0682:            public String getTypeName() {
0683:                return typeId.getSQLTypeName();
0684:            }
0685:
0686:            /**
0687:             * Get the jdbc type id for this type.  JDBC type can be
0688:             * found in java.sql.Types. 
0689:             *
0690:             * @return	a jdbc type, e.g. java.sql.Types.DECIMAL 
0691:             *
0692:             * @see Types
0693:             */
0694:            public int getJDBCTypeId() {
0695:                return typeId.getJDBCTypeId();
0696:            }
0697:
0698:            /**
0699:             * Returns the number of decimal digits for the datatype, if applicable.
0700:             *
0701:             * @return	The number of decimal digits for the datatype.  Returns
0702:             *		zero for non-numeric datatypes.
0703:             */
0704:            public int getPrecision() {
0705:                return typeDescriptor.getPrecision();
0706:            }
0707:
0708:            /**
0709:             * Returns the number of digits to the right of the decimal for
0710:             * the datatype, if applicable.
0711:             *
0712:             * @return	The number of digits to the right of the decimal for
0713:             *		the datatype.  Returns zero for non-numeric datatypes.
0714:             */
0715:            public int getScale() {
0716:                return typeDescriptor.getScale();
0717:            }
0718:
0719:            /**
0720:             * Returns TRUE if the datatype can contain NULL, FALSE if not.
0721:             * JDBC supports a return value meaning "nullability unknown" -
0722:             * I assume we will never have columns where the nullability is unknown.
0723:             *
0724:             * @return	TRUE if the datatype can contain NULL, FALSE if not.
0725:             */
0726:            public boolean isNullable() {
0727:                return typeDescriptor.isNullable();
0728:            }
0729:
0730:            /**
0731:             * Set the nullability of the datatype described by this descriptor
0732:             *
0733:             * @param nullable	TRUE means set nullability to TRUE, FALSE
0734:             *			means set it to FALSE
0735:             */
0736:            public void setNullability(boolean nullable) {
0737:                typeDescriptor.setNullability(nullable);
0738:            }
0739:
0740:            /**
0741:              Compare if two TypeDescriptors are exactly the same
0742:              @param aTypeDescriptor the typeDescriptor to compare to.
0743:             */
0744:            public boolean equals(Object aTypeDescriptor) {
0745:                return typeDescriptor.equals(aTypeDescriptor);
0746:            }
0747:
0748:            /**
0749:             * Converts this data type descriptor (including length/precision)
0750:             * to a string. E.g.
0751:             *
0752:             *			VARCHAR(30)
0753:             *
0754:             *	or
0755:             *
0756:             *			 java.util.Hashtable 
0757:             *
0758:             * @return	String version of datatype, suitable for running through
0759:             *			the Parser.
0760:             */
0761:            public String getSQLstring() {
0762:                return typeId.toParsableString(this );
0763:            }
0764:
0765:            /**
0766:             * Get the simplified type descriptor that is intended to be stored
0767:             * in the system tables.
0768:             */
0769:            public TypeDescriptorImpl getCatalogType() {
0770:                return typeDescriptor;
0771:            }
0772:
0773:            /**
0774:             * Get the estimated memory usage for this type descriptor.
0775:             */
0776:            public double estimatedMemoryUsage() {
0777:                switch (typeId.getTypeFormatId()) {
0778:                case StoredFormatIds.LONGVARBIT_TYPE_ID:
0779:                    /* Who knows?  Let's just use some big number */
0780:                    return 10000.0;
0781:
0782:                case StoredFormatIds.BIT_TYPE_ID:
0783:                    return (double) ((((float) getMaximumWidth()) / 8.0) + 0.5);
0784:
0785:                case StoredFormatIds.BOOLEAN_TYPE_ID:
0786:                    return 4.0;
0787:
0788:                case StoredFormatIds.CHAR_TYPE_ID:
0789:                case StoredFormatIds.VARCHAR_TYPE_ID:
0790:                case StoredFormatIds.NATIONAL_CHAR_TYPE_ID:
0791:                case StoredFormatIds.NATIONAL_VARCHAR_TYPE_ID:
0792:                    return (double) (2.0 * getMaximumWidth());
0793:
0794:                case StoredFormatIds.LONGVARCHAR_TYPE_ID:
0795:                case StoredFormatIds.NATIONAL_LONGVARCHAR_TYPE_ID:
0796:                    /* Who knows? Let's just use some big number */
0797:                    return 10000.0;
0798:
0799:                case StoredFormatIds.DECIMAL_TYPE_ID:
0800:                    /*
0801:                     ** 0.415 converts from number decimal digits to number of 8-bit digits. 
0802:                     ** Add 1.0 for the sign byte, and 0.5 to force it to round up.
0803:                     */
0804:                    return (double) ((getPrecision() * 0.415) + 1.5);
0805:
0806:                case StoredFormatIds.DOUBLE_TYPE_ID:
0807:                    return 8.0;
0808:
0809:                case StoredFormatIds.INT_TYPE_ID:
0810:                    return 4.0;
0811:
0812:                case StoredFormatIds.LONGINT_TYPE_ID:
0813:                    return 8.0;
0814:
0815:                case StoredFormatIds.REAL_TYPE_ID:
0816:                    return 4.0;
0817:
0818:                case StoredFormatIds.SMALLINT_TYPE_ID:
0819:                    return 2.0;
0820:
0821:                case StoredFormatIds.TINYINT_TYPE_ID:
0822:                    return 1.0;
0823:
0824:                case StoredFormatIds.REF_TYPE_ID:
0825:                    /* I think 12 is the right number */
0826:                    return 12.0;
0827:
0828:                case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
0829:                    if (typeId.userType()) {
0830:                        /* Who knows?  Let's just use some medium-sized number */
0831:                        return 256.0;
0832:                    }
0833:                case StoredFormatIds.DATE_TYPE_ID:
0834:                case StoredFormatIds.TIME_TYPE_ID:
0835:                case StoredFormatIds.TIMESTAMP_TYPE_ID:
0836:                    return 12.0;
0837:
0838:                default:
0839:                    return 0.0;
0840:                }
0841:            }
0842:
0843:            /**
0844:             * Compare JdbcTypeIds to determine if they represent equivalent
0845:             * SQL types. For example Types.NUMERIC and Types.DECIMAL are
0846:             * equivalent
0847:             *
0848:             * @param existingType  JDBC type id of Cloudscape data type
0849:             * @param jdbcTypeId   JDBC type id passed in from application.
0850:             *
0851:             * @return boolean true if types are equivalent, false if not
0852:             */
0853:
0854:            public static boolean isJDBCTypeEquivalent(int existingType,
0855:                    int jdbcTypeId) {
0856:                // Any type matches itself.
0857:                if (existingType == jdbcTypeId)
0858:                    return true;
0859:
0860:                // To a numeric type
0861:                if (DataTypeDescriptor.isNumericType(existingType)) {
0862:                    if (DataTypeDescriptor.isNumericType(jdbcTypeId))
0863:                        return true;
0864:
0865:                    if (DataTypeDescriptor.isCharacterType(jdbcTypeId))
0866:                        return true;
0867:
0868:                    return false;
0869:                }
0870:
0871:                // To character type.
0872:                if (DataTypeDescriptor.isCharacterType(existingType)) {
0873:
0874:                    if (DataTypeDescriptor.isCharacterType(jdbcTypeId))
0875:                        return true;
0876:
0877:                    if (DataTypeDescriptor.isNumericType(jdbcTypeId))
0878:                        return true;
0879:
0880:                    switch (jdbcTypeId) {
0881:                    case Types.DATE:
0882:                    case Types.TIME:
0883:                    case Types.TIMESTAMP:
0884:                        return true;
0885:                    default:
0886:                        break;
0887:                    }
0888:
0889:                    return false;
0890:
0891:                }
0892:
0893:                // To binary type
0894:                if (DataTypeDescriptor.isBinaryType(existingType)) {
0895:
0896:                    if (DataTypeDescriptor.isBinaryType(jdbcTypeId))
0897:                        return true;
0898:
0899:                    return false;
0900:                }
0901:
0902:                // To DATE, TIME
0903:                if (existingType == Types.DATE || existingType == Types.TIME) {
0904:                    if (DataTypeDescriptor.isCharacterType(jdbcTypeId))
0905:                        return true;
0906:
0907:                    if (jdbcTypeId == Types.TIMESTAMP)
0908:                        return true;
0909:
0910:                    return false;
0911:                }
0912:
0913:                // To TIMESTAMP
0914:                if (existingType == Types.TIMESTAMP) {
0915:                    if (DataTypeDescriptor.isCharacterType(jdbcTypeId))
0916:                        return true;
0917:
0918:                    if (jdbcTypeId == Types.DATE)
0919:                        return true;
0920:
0921:                    return false;
0922:                }
0923:
0924:                // To CLOB
0925:                if (existingType == Types.CLOB
0926:                        && DataTypeDescriptor.isCharacterType(jdbcTypeId))
0927:                    return true;
0928:
0929:                return false;
0930:            }
0931:
0932:            public static boolean isNumericType(int jdbcType) {
0933:
0934:                switch (jdbcType) {
0935:                case Types.BIT:
0936:                case org.apache.derby.iapi.reference.JDBC30Translation.SQL_TYPES_BOOLEAN:
0937:                case Types.TINYINT:
0938:                case Types.SMALLINT:
0939:                case Types.INTEGER:
0940:                case Types.BIGINT:
0941:                case Types.REAL:
0942:                case Types.FLOAT:
0943:                case Types.DOUBLE:
0944:                case Types.DECIMAL:
0945:                case Types.NUMERIC:
0946:                    return true;
0947:                default:
0948:                    return false;
0949:                }
0950:            }
0951:
0952:            /**
0953:             * Check whether a JDBC type is one of the character types that are
0954:             * compatible with the Java type <code>String</code>.
0955:             *
0956:             * <p><strong>Note:</strong> <code>CLOB</code> is not compatible with
0957:             * <code>String</code>. See tables B-4, B-5 and B-6 in the JDBC 3.0
0958:             * Specification.
0959:             *
0960:             * <p> There are some non-character types that are compatible with
0961:             * <code>String</code> (examples: numeric types, binary types and
0962:             * time-related types), but they are not covered by this method.
0963:             *
0964:             * @param jdbcType a JDBC type
0965:             * @return <code>true</code> iff <code>jdbcType</code> is a character type
0966:             * and compatible with <code>String</code>
0967:             * @see java.sql.Types
0968:             */
0969:            private static boolean isCharacterType(int jdbcType) {
0970:
0971:                switch (jdbcType) {
0972:                case Types.CHAR:
0973:                case Types.VARCHAR:
0974:                case Types.LONGVARCHAR:
0975:                    return true;
0976:                default:
0977:                    return false;
0978:                }
0979:            }
0980:
0981:            /**
0982:             * Check whether a JDBC type is compatible with the Java type
0983:             * <code>byte[]</code>.
0984:             *
0985:             * <p><strong>Note:</strong> <code>BLOB</code> is not compatible with
0986:             * <code>byte[]</code>. See tables B-4, B-5 and B-6 in the JDBC 3.0
0987:             * Specification.
0988:             *
0989:             * @param jdbcType a JDBC type
0990:             * @return <code>true</code> iff <code>jdbcType</code> is compatible with
0991:             * <code>byte[]</code>
0992:             * @see java.sql.Types
0993:             */
0994:            private static boolean isBinaryType(int jdbcType) {
0995:                switch (jdbcType) {
0996:                case Types.BINARY:
0997:                case Types.VARBINARY:
0998:                case Types.LONGVARBINARY:
0999:                    return true;
1000:                default:
1001:                    return false;
1002:                }
1003:            }
1004:
1005:            /**
1006:             * Determine if an ASCII stream can be inserted into a column or parameter
1007:             * of type <code>jdbcType</code>.
1008:             *
1009:             * @param jdbcType JDBC type of column or parameter
1010:             * @return <code>true</code> if an ASCII stream can be inserted;
1011:             *         <code>false</code> otherwise
1012:             */
1013:            public static boolean isAsciiStreamAssignable(int jdbcType) {
1014:                return jdbcType == Types.CLOB || isCharacterType(jdbcType);
1015:            }
1016:
1017:            /**
1018:             * Determine if a binary stream can be inserted into a column or parameter
1019:             * of type <code>jdbcType</code>.
1020:             *
1021:             * @param jdbcType JDBC type of column or parameter
1022:             * @return <code>true</code> if a binary stream can be inserted;
1023:             *         <code>false</code> otherwise
1024:             */
1025:            public static boolean isBinaryStreamAssignable(int jdbcType) {
1026:                return jdbcType == Types.BLOB || isBinaryType(jdbcType);
1027:            }
1028:
1029:            /**
1030:             * Determine if a character stream can be inserted into a column or
1031:             * parameter of type <code>jdbcType</code>.
1032:             *
1033:             * @param jdbcType JDBC type of column or parameter
1034:             * @return <code>true</code> if a character stream can be inserted;
1035:             *         <code>false</code> otherwise
1036:             */
1037:            public static boolean isCharacterStreamAssignable(int jdbcType) {
1038:                // currently, we support the same types for ASCII streams and
1039:                // character streams
1040:                return isAsciiStreamAssignable(jdbcType);
1041:            }
1042:
1043:            public String toString() {
1044:                return typeDescriptor.toString();
1045:            }
1046:
1047:            // Formatable methods
1048:
1049:            /**
1050:             * Read this object from a stream of stored objects.
1051:             *
1052:             * @param in read this.
1053:             *
1054:             * @exception IOException					thrown on error
1055:             * @exception ClassNotFoundException		thrown on error
1056:             */
1057:            public void readExternal(ObjectInput in) throws IOException,
1058:                    ClassNotFoundException {
1059:                /* NOTE: We only write out the generic type id.
1060:                 * typeId will be reset to be the generic type id
1061:                 * when we get read back in since the generic
1062:                 * one is all that is needed at execution time.
1063:                 */
1064:                typeId = (TypeId) in.readObject();
1065:                typeDescriptor = (TypeDescriptorImpl) in.readObject();
1066:            }
1067:
1068:            /**
1069:             * Write this object to a stream of stored objects.
1070:             *
1071:             * @param out write bytes here.
1072:             *
1073:             * @exception IOException		thrown on error
1074:             */
1075:            public void writeExternal(ObjectOutput out) throws IOException {
1076:                out.writeObject(typeId);
1077:                out.writeObject(typeDescriptor);
1078:            }
1079:
1080:            /**
1081:             * Get the formatID which corresponds to this class.
1082:             *
1083:             *	@return	the formatID of this class
1084:             */
1085:            public int getTypeFormatId() {
1086:                return StoredFormatIds.DATA_TYPE_SERVICES_IMPL_V01_ID;
1087:            }
1088:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.