Source Code Cross Referenced for ColumnDefinitionNode.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » compile » 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.impl.sql.compile 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.compile.ColumnDefinitionNode
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.sql.compile;
023:
024:        import org.apache.derby.iapi.services.loader.ClassInspector;
025:
026:        import org.apache.derby.iapi.services.sanity.SanityManager;
027:        import org.apache.derby.iapi.services.io.StoredFormatIds;
028:        import org.apache.derby.iapi.reference.Limits;
029:        import org.apache.derby.iapi.error.StandardException;
030:
031:        import org.apache.derby.iapi.sql.compile.CompilerContext;
032:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
033:
034:        import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
035:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
036:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
037:
038:        import org.apache.derby.iapi.types.DataTypeDescriptor;
039:        import org.apache.derby.iapi.types.DataValueDescriptor;
040:        import org.apache.derby.iapi.types.TypeId;
041:
042:        import org.apache.derby.iapi.sql.depend.DependencyManager;
043:        import org.apache.derby.iapi.sql.depend.ProviderList;
044:        import org.apache.derby.iapi.sql.depend.ProviderInfo;
045:
046:        import org.apache.derby.iapi.reference.SQLState;
047:
048:        import org.apache.derby.impl.sql.execute.ColumnInfo;
049:
050:        import org.apache.derby.catalog.AliasInfo;
051:        import org.apache.derby.catalog.DefaultInfo;
052:        import org.apache.derby.catalog.UUID;
053:
054:        import org.apache.derby.catalog.types.DefaultInfoImpl;
055:
056:        import java.util.Vector;
057:        import java.sql.Types;
058:
059:        /**
060:         * A ColumnDefinitionNode represents a column definition in a DDL statement.
061:         * There will be a ColumnDefinitionNode for each column in a CREATE TABLE
062:         * statement, and for the column in an ALTER TABLE ADD COLUMN statement.
063:         *
064:         * @author Jeff Lichtman
065:         */
066:
067:        public class ColumnDefinitionNode extends TableElementNode {
068:            boolean isAutoincrement;
069:            DataTypeDescriptor dataTypeServices;
070:            DataValueDescriptor defaultValue;
071:            DefaultInfoImpl defaultInfo;
072:            DefaultNode defaultNode;
073:            long autoincrementIncrement;
074:            long autoincrementStart;
075:            //This variable tells if the autoincrement column is participating 
076:            //in create or alter table. And if it is participating in alter
077:            //table, then it further knows if it is represting a change in 
078:            //increment value or a change in start value.
079:            //This information is later used to make sure that the autoincrement
080:            //column's increment value is not 0 at the time of create, or is not
081:            //getting set to 0 at the time of increment value modification.
082:            long autoinc_create_or_modify_Start_Increment;
083:            boolean autoincrementVerify;
084:
085:            //autoinc_create_or_modify_Start_Increment will be set to one of the
086:            //following 3 values.
087:            //CREATE_AUTOINCREMENT - this autoincrement column definition is for create table
088:            public static final int CREATE_AUTOINCREMENT = 0;
089:            //MODIFY_AUTOINCREMENT_RESTART_VALUE - this column definition is for
090:            //alter table command to change the start value of the column
091:            public static final int MODIFY_AUTOINCREMENT_RESTART_VALUE = 1;
092:            //MODIFY_AUTOINCREMENT_INC_VALUE - this column definition is for
093:            //alter table command to change the increment value of the column
094:            public static final int MODIFY_AUTOINCREMENT_INC_VALUE = 2;
095:
096:            /**
097:             * Initializer for a ColumnDefinitionNode
098:             *
099:             * @param name			The name of the column
100:             * @param defaultNode	The default value of the column
101:             * @param dataTypeServices	A DataTypeServices telling the type
102:             *				of the column
103:             * @param autoIncrementInfo	Info for autoincrement columns
104:             *
105:             */
106:
107:            public void init(Object name, Object defaultNode,
108:                    Object dataTypeServices, Object autoIncrementInfo)
109:                    throws StandardException {
110:                super .init(name);
111:                this .dataTypeServices = (DataTypeDescriptor) dataTypeServices;
112:                if (defaultNode instanceof  UntypedNullConstantNode) {
113:                    /* No DTS yet for MODIFY DEFAULT */
114:                    if (dataTypeServices != null) {
115:                        defaultValue = ((UntypedNullConstantNode) defaultNode)
116:                                .convertDefaultNode(this .dataTypeServices);
117:                    }
118:                } else {
119:                    if (SanityManager.DEBUG) {
120:                        if (defaultNode != null
121:                                && !(defaultNode instanceof  DefaultNode)) {
122:                            SanityManager
123:                                    .THROWASSERT("defaultNode expected to be instanceof DefaultNode, not "
124:                                            + defaultNode.getClass().getName());
125:                        }
126:                    }
127:                    this .defaultNode = (DefaultNode) defaultNode;
128:                    if (autoIncrementInfo != null) {
129:                        long[] aii = (long[]) autoIncrementInfo;
130:                        autoincrementStart = aii[QueryTreeNode.AUTOINCREMENT_START_INDEX];
131:                        autoincrementIncrement = aii[QueryTreeNode.AUTOINCREMENT_INC_INDEX];
132:                        //Parser has passed the info about autoincrement column's status in the
133:                        //following array element. It will tell if the autoinc column is part of 
134:                        //a create table or if is a part of alter table. And if it is part of 
135:                        //alter table, is it for changing the increment value or for changing 
136:                        //the start value?
137:                        autoinc_create_or_modify_Start_Increment = aii[QueryTreeNode.AUTOINCREMENT_CREATE_MODIFY];
138:
139:                        /*
140:                         * If using DB2 syntax to set increment value, will need to check if column
141:                         * is already created for autoincrement.
142:                         */
143:                        autoincrementVerify = (aii[QueryTreeNode.AUTOINCREMENT_IS_AUTOINCREMENT_INDEX] > 0) ? false
144:                                : true;
145:                        isAutoincrement = true;
146:                        // an autoincrement column cannot be null-- setting
147:                        // non-nullability for this column is needed because 
148:                        // you could create a column with ai default, add data, drop 
149:                        // the default, and try to add it back again you'll get an
150:                        // error because the column is marked nullable.
151:                        if (dataTypeServices != null)
152:                            (this .dataTypeServices).setNullability(false);
153:                    }
154:                }
155:            }
156:
157:            /**
158:             * Convert this object to a String.  See comments in QueryTreeNode.java
159:             * for how this should be done for tree printing.
160:             *
161:             * @return	This object as a String
162:             */
163:
164:            public String toString() {
165:                if (SanityManager.DEBUG) {
166:                    return "dataTypeServices: " + dataTypeServices.toString()
167:                            + "\n" + "defaultValue: " + defaultValue + "\n"
168:                            + super .toString();
169:                } else {
170:                    return "";
171:                }
172:            }
173:
174:            /**
175:             * Returns the unqualified name of the column being defined.
176:             *
177:             * @return	the name of the column
178:             */
179:            public String getColumnName() {
180:                return this .name;
181:            }
182:
183:            /**
184:             * Returns the data type services of the column being defined.
185:             *
186:             * @return	the data type services of the column
187:             */
188:            public DataTypeDescriptor getDataTypeServices() {
189:                return this .dataTypeServices;
190:            }
191:
192:            /**
193:             * Return the DataValueDescriptor containing the default value for this
194:             * column
195:             *
196:             * @return	The default value of the column
197:             */
198:
199:            public DataValueDescriptor getDefaultValue() {
200:                return this .defaultValue;
201:            }
202:
203:            /**
204:             * Return the DefaultInfo containing the default information for this
205:             * column
206:             *
207:             * @return	The default info for the column
208:             */
209:
210:            public DefaultInfo getDefaultInfo() {
211:                return defaultInfo;
212:            }
213:
214:            /**
215:             * Return the DefaultNode, if any, associated with this node.
216:             *
217:             * @return The DefaultNode, if any, associated with this node.
218:             */
219:            public DefaultNode getDefaultNode() {
220:                return defaultNode;
221:            }
222:
223:            /**
224:             * Is this an autoincrement column?
225:             *
226:             * @return Whether or not this is an autoincrement column.
227:             */
228:            public boolean isAutoincrementColumn() {
229:                if (SanityManager.DEBUG) {
230:                    //increment value for autoincrement column can't be 0 if the autoinc column
231:                    //is part of create table or it is part of alter table to change the 
232:                    //increment value. 
233:                    if (isAutoincrement
234:                            && autoincrementIncrement == 0
235:                            && (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.CREATE_AUTOINCREMENT || autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE)) {
236:                        SanityManager
237:                                .THROWASSERT("autoincrementIncrement expected to be non-zero");
238:                    }
239:                    if ((!isAutoincrement)
240:                            && (autoincrementStart != 0 || autoincrementIncrement != 0)) {
241:                        SanityManager
242:                                .THROWASSERT("both autoincrementStart and autoincrementIncrement expected to be 0");
243:                    }
244:                }
245:                return isAutoincrement;
246:            }
247:
248:            /**
249:             * Get the autoincrement start value
250:             *
251:             * @return Autoincrement start value.
252:             */
253:            long getAutoincrementStart() {
254:                if (SanityManager.DEBUG) {
255:                    SanityManager.ASSERT(isAutoincrement,
256:                            "isAutoincrement expected to be true");
257:                }
258:                return autoincrementStart;
259:            }
260:
261:            /**
262:             * Get the autoincrement increment value
263:             *
264:             * @return Autoincrement increment value.
265:             */
266:            long getAutoincrementIncrement() {
267:                if (SanityManager.DEBUG) {
268:                    SanityManager.ASSERT(isAutoincrement,
269:                            "isAutoincrement expected to be true");
270:                }
271:                return autoincrementIncrement;
272:            }
273:
274:            /**
275:             * Get the status of this autoincrement column 
276:             *
277:             * @return ColumnDefinitionNode.CREATE_AUTOINCREMENT - 
278:             * 		if this definition is for autoincrement column creatoin
279:             *   ColumnDefinitionNode.MODIFY_AUTOINCREMENT_RESTART_VALUE -
280:             * 		if this definition is for alter sutoincrement column to change the start value 
281:             *   ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE 
282:             * 		if this definition is for alter autoincrement column to change the increment value
283:             */
284:            long getAutoinc_create_or_modify_Start_Increment() {
285:                if (SanityManager.DEBUG) {
286:                    SanityManager.ASSERT(isAutoincrement,
287:                            "isAutoincrement expected to be true");
288:                }
289:                return autoinc_create_or_modify_Start_Increment;
290:            }
291:
292:            /**
293:             * Check the validity of a user type.  Checks whether this column
294:             * definition describes a user type that either doesn't exist or is
295:             * inaccessible, or that doesn't implement Serializable.
296:             *
297:             * @exception StandardException		Thrown on error
298:             */
299:
300:            public void checkUserType(TableDescriptor td)
301:                    throws StandardException {
302:                String columnTypeName;
303:
304:                /* Built-in types need no checking */
305:                if (!dataTypeServices.getTypeId().userType())
306:                    return;
307:
308:                ClassInspector classInspector = getClassFactory()
309:                        .getClassInspector();
310:
311:                columnTypeName = dataTypeServices.getTypeId()
312:                        .getCorrespondingJavaTypeName();
313:
314:                /* User type - We first check for the columnTypeName as a java class.
315:                 * If that fails, then we treat it as a class alias.
316:                 */
317:
318:                boolean foundMatch = false;
319:                Throwable reason = null;
320:                try {
321:                    foundMatch = classInspector.accessible(columnTypeName);
322:                } catch (ClassNotFoundException cnfe) {
323:                    reason = cnfe;
324:                }
325:
326:                if (!foundMatch) {
327:                    throw StandardException.newException(
328:                            SQLState.LANG_TYPE_DOESNT_EXIST, reason,
329:                            columnTypeName, name);
330:                }
331:
332:                if (!classInspector.assignableTo(columnTypeName,
333:                        "java.io.Serializable")
334:                        &&
335:                        // Before Java2, SQLData is not defined, assignableTo call returns false
336:                        !classInspector.assignableTo(columnTypeName,
337:                                "java.sql.SQLData")) {
338:                    getCompilerContext().addWarning(
339:                            StandardException.newWarning(
340:                                    SQLState.LANG_TYPE_NOT_SERIALIZABLE,
341:                                    columnTypeName, name));
342:                }
343:            }
344:
345:            /**
346:             * Get the UUID of the old column default.
347:             *
348:             * @return The UUID of the old column default.
349:             */
350:            UUID getOldDefaultUUID() {
351:                return null;
352:            }
353:
354:            /**
355:             * Get the action associated with this node.
356:             *
357:             * @return The action associated with this node.
358:             */
359:            int getAction() {
360:                return ColumnInfo.CREATE;
361:            }
362:
363:            /**
364:             * Check the validity of the default, if any, for this node.
365:             *
366:             * @param dd		The DataDictionary.
367:             * @param td		The TableDescriptor.
368:             *
369:             * @exception StandardException		Thrown on error
370:             */
371:            void bindAndValidateDefault(DataDictionary dd, TableDescriptor td)
372:                    throws StandardException {
373:                /* DB2 requires non-nullable columns to have a default in ALTER TABLE */
374:                if (td != null && !dataTypeServices.isNullable()
375:                        && defaultNode == null) {
376:                    if (!isAutoincrement)
377:                        throw StandardException
378:                                .newException(
379:                                        SQLState.LANG_DB2_NOT_NULL_COLUMN_INVALID_DEFAULT,
380:                                        getColumnName());
381:                }
382:
383:                // No work to do if no user specified default
384:                if (defaultNode == null) {
385:                    return;
386:                }
387:
388:                // No work to do if user specified NULL
389:                if (defaultValue != null) {
390:                    return;
391:                }
392:
393:                // Now validate the default
394:                validateDefault(dd, td);
395:            }
396:
397:            /**
398:             * Check the validity of the autoincrement values for this node.
399:             * The following errors are thrown by this routine.
400:             * 1. 42z21 Invalid Increment; i.e 0.
401:             * 2. 42z22 Invalid Type; autoincrement created on a non-exact-numeric type
402:             * 3. 42995 The requested function does not apply to global temporary tables
403:             *
404:             * @param 		dd		DataDictionary.
405:             * @param		td		table descriptor.
406:             * @param		tableType	base table or declared global temporary table.
407:             *
408:             * @exception 	StandardException if autoincrement default is incorrect; i.e
409:             * 				if increment is 0 or if initial or increment values are out
410:             * 				of range for the datatype.
411:             */
412:            public void validateAutoincrement(DataDictionary dd,
413:                    TableDescriptor td, int tableType) throws StandardException {
414:                if (isAutoincrement == false)
415:                    return;
416:
417:                if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
418:                    throw StandardException
419:                            .newException(SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE);
420:
421:                //increment value for autoincrement column can't be 0 if the autoinc column
422:                //is part of create table or it is part of alter table to change the 
423:                //increment value. 
424:                if (autoincrementIncrement == 0
425:                        && (autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.CREATE_AUTOINCREMENT || autoinc_create_or_modify_Start_Increment == ColumnDefinitionNode.MODIFY_AUTOINCREMENT_INC_VALUE))
426:                    throw StandardException
427:                            .newException(SQLState.LANG_AI_INVALID_INCREMENT,
428:                                    getColumnName());
429:                int jdbctype = dataTypeServices.getTypeId().getJDBCTypeId();
430:                switch (jdbctype) {
431:                case Types.TINYINT:
432:                    autoincrementCheckRange((long) Byte.MIN_VALUE,
433:                            (long) Byte.MAX_VALUE, TypeId.TINYINT_NAME);
434:                    break;
435:                case Types.SMALLINT:
436:                    autoincrementCheckRange((long) Short.MIN_VALUE,
437:                            (long) Short.MAX_VALUE, TypeId.SMALLINT_NAME);
438:                    break;
439:                case Types.INTEGER:
440:                    autoincrementCheckRange((long) Integer.MIN_VALUE,
441:                            (long) Integer.MAX_VALUE, TypeId.INTEGER_NAME);
442:                    break;
443:                case Types.BIGINT:
444:                    autoincrementCheckRange(Long.MIN_VALUE, Long.MAX_VALUE,
445:                            TypeId.LONGINT_NAME);
446:                    break;
447:                default:
448:                    throw StandardException.newException(
449:                            SQLState.LANG_AI_INVALID_TYPE, getColumnName());
450:                }
451:            }
452:
453:            /**
454:             * checks to see if autoincrementIncrement and autoincrementInitial
455:             * are within the bounds of the type whose min and max values are
456:             * passed into this routine.
457:             */
458:            private void autoincrementCheckRange(long minValue, long maxValue,
459:                    String typeName) throws StandardException {
460:                if ((minValue > autoincrementIncrement)
461:                        || (maxValue < autoincrementIncrement)) {
462:                    throw StandardException.newException(
463:                            SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, typeName);
464:                }
465:                if ((minValue > autoincrementStart)
466:                        || (maxValue < autoincrementStart)) {
467:                    throw StandardException.newException(
468:                            SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE, typeName);
469:                }
470:            }
471:
472:            /**
473:             * Check the validity of the default for this node.
474:             *
475:             * @param td		The TableDescriptor.
476:             *
477:             * @exception StandardException		Thrown on error
478:             */
479:            void validateDefault(DataDictionary dd, TableDescriptor td)
480:                    throws StandardException {
481:                if (defaultNode == null)
482:                    return;
483:
484:                //Examin whether default value is autoincrement.
485:                if (isAutoincrement) {
486:                    defaultInfo = createDefaultInfoOfAutoInc();
487:                    return;
488:                }
489:
490:                //Judged as default value is constant value.
491:
492:                CompilerContext cc = getCompilerContext();
493:
494:                ValueNode defaultTree = defaultNode.getDefaultTree();
495:
496:                /* bind the default.
497:                 * Verify that it does not contain any ColumnReferences or subqueries
498:                 * and that it is type compatable with the column.
499:                 */
500:                final int previousReliability = cc.getReliability();
501:                try {
502:                    /*
503:                    	Defaults cannot have dependencies as they
504:                    	should just be constants. Code used to exist
505:                    	to handle dependencies in defaults, now this
506:                    	is under sanity to ensure no dependencies exist.
507:                     */
508:                    ProviderList apl = null;
509:                    ProviderList prevAPL = null;
510:
511:                    if (SanityManager.DEBUG) {
512:                        apl = new ProviderList();
513:                        prevAPL = cc.getCurrentAuxiliaryProviderList();
514:                        cc.setCurrentAuxiliaryProviderList(apl);
515:                    }
516:
517:                    // Tell the compiler context to only allow deterministic nodes
518:                    cc.setReliability(CompilerContext.DEFAULT_RESTRICTION);
519:                    defaultTree = defaultTree.bindExpression(
520:                            (FromList) getNodeFactory().getNode(
521:                                    C_NodeTypes.FROM_LIST,
522:                                    getNodeFactory().doJoinOrderOptimization(),
523:                                    getContextManager()), (SubqueryList) null,
524:                            (Vector) null);
525:
526:                    TypeId columnTypeId = (TypeId) dataTypeServices.getTypeId();
527:                    TypeId defaultTypeId = defaultTree.getTypeId();
528:
529:                    // Check for 'invalid default' errors (42894)
530:                    // before checking for 'not storable' errors (42821).
531:                    if (!defaultTypeIsValid(columnTypeId, dataTypeServices,
532:                            defaultTypeId, defaultTree, defaultNode
533:                                    .getDefaultText())) {
534:                        throw StandardException.newException(
535:                                SQLState.LANG_DB2_INVALID_DEFAULT_VALUE,
536:                                this .name);
537:                    }
538:
539:                    // Now check 'not storable' errors.
540:                    if (!getTypeCompiler(columnTypeId).storable(defaultTypeId,
541:                            getClassFactory())) {
542:                        throw StandardException.newException(
543:                                SQLState.LANG_NOT_STORABLE, columnTypeId
544:                                        .getSQLTypeName(), defaultTypeId
545:                                        .getSQLTypeName());
546:                    }
547:
548:                    // Save off the default text
549:                    // RESOLVEDEFAULT - Convert to constant if possible
550:                    defaultInfo = new DefaultInfoImpl(false, defaultNode
551:                            .getDefaultText(), defaultValue);
552:
553:                    if (SanityManager.DEBUG) {
554:                        /* Save the APL off in the constraint node */
555:                        if (apl.size() > 0) {
556:
557:                            SanityManager
558:                                    .THROWASSERT("DEFAULT clause has unexpected dependencies");
559:                        }
560:                        // Restore the previous AuxiliaryProviderList
561:                        cc.setCurrentAuxiliaryProviderList(prevAPL);
562:                    }
563:
564:                } finally {
565:                    cc.setReliability(previousReliability);
566:                }
567:            }
568:
569:            private static DefaultInfoImpl createDefaultInfoOfAutoInc() {
570:                return new DefaultInfoImpl(true, null, null);
571:            }
572:
573:            /**
574:             * Check the validity of the default for this node
575:             *
576:             * @param columnType TypeId of the target column.
577:             * @param columnDesc Description of the type of the
578:             *		target column.
579:             * @param defaultType TypeId of the default node.
580:             * @param defaultNode Parsed ValueNode for the default value.
581:             * @param defaultText Unparsed default value (as entered
582:             * 		by user).
583:             * @return True if the defaultNode abides by the restrictions
584:             * 	imposed by DB2 on default constants; false otherwise.
585:             *
586:             */
587:
588:            public boolean defaultTypeIsValid(TypeId columnType,
589:                    DataTypeDescriptor columnDesc, TypeId defaultType,
590:                    ValueNode defaultNode, String defaultText)
591:                    throws StandardException {
592:
593:                if (defaultText.length() > Limits.DB2_CHAR_MAXWIDTH)
594:                    // DB2 spec says this isn't allowed.
595:                    return false;
596:
597:                /* We can use info about the way the parser works
598:                 * to guide this process a little (see the getNumericNode()
599:                 * method in sqlgrammar.jj):
600:                 *
601:                 * 1) Tinyint and Smallints are both parsed as "INT" types,
602:                 *	  while integers larger than a basic "INT" are parsed into
603:                 *	  "LONGINT" or, if needed, "DECIMAL".
604:                 * 2) Floats, doubles, and decimals with fractional parts
605:                 *	  are all parsed as "DECIMAL".
606:                 * 3) All strings are parsed as "CHAR" constants (no varchar
607:                 *	  or any others; see stringLiteral() method in
608:                 *	  sqlgrammar.jj).
609:                 */
610:
611:                int colType = columnType.getTypeFormatId();
612:                int defType = (defaultType == null ? -1 : defaultType
613:                        .getTypeFormatId());
614:
615:                if (!defaultNode.isConstantExpression()) {
616:                    // then we have a built-in function, such as "user"
617:                    // or "current schema".  If the function is a datetime
618:                    // value function, then we don't need any special
619:                    // action; however, if it's a "user" or "current schema"
620:                    // function, then the column must be a char type with
621:                    // minimum lengths matching those of DB2 (note that
622:                    // such limits are ONLY enforced on defaults, not at
623:                    // normal insertion time).
624:
625:                    boolean charCol = ((colType == StoredFormatIds.CHAR_TYPE_ID)
626:                            || (colType == StoredFormatIds.VARCHAR_TYPE_ID) || (colType == StoredFormatIds.LONGVARCHAR_TYPE_ID));
627:
628:                    if (defaultNode instanceof  SpecialFunctionNode) {
629:
630:                        switch (defaultNode.getNodeType()) {
631:                        case C_NodeTypes.USER_NODE:
632:                        case C_NodeTypes.CURRENT_USER_NODE:
633:                        case C_NodeTypes.SESSION_USER_NODE:
634:                        case C_NodeTypes.SYSTEM_USER_NODE:
635:                            // DB2 enforces min length of 8.
636:                            // Note also: any size under 30 gives a warning in DB2.
637:                            return (charCol && (columnDesc.getMaximumWidth() >= Limits.DB2_MIN_COL_LENGTH_FOR_CURRENT_USER));
638:
639:                        case C_NodeTypes.CURRENT_SCHEMA_NODE:
640:                            // DB2 enforces min length of 128.
641:                            return (charCol && (columnDesc.getMaximumWidth() >= Limits.DB2_MIN_COL_LENGTH_FOR_CURRENT_SCHEMA));
642:                        default:
643:                            // else, function not allowed.
644:                            return false;
645:                        }
646:                    }
647:
648:                }
649:
650:                switch (colType) {
651:
652:                case StoredFormatIds.INT_TYPE_ID:
653:                    // DB2 doesn't allow floating point values to be used
654:                    // as defaults for integer columns (they ARE allowed
655:                    // as part of normal insertions, but not as defaults).
656:                    // If the default is an integer that's too big, then
657:                    // it won't have type INT_TYPE_ID (it'll be either
658:                    // LONGINT or DECIMAL)--so we only allow the default
659:                    // value if it's integer.
660:                    return (defType == StoredFormatIds.INT_TYPE_ID);
661:
662:                case StoredFormatIds.LONGINT_TYPE_ID:
663:                    // This is a BIGINT column: we allow smallints, ints,
664:                    // and big int constants.  Smallint and int literals
665:                    // are both covered by INT_TYPE; big int literals are
666:                    // covered by LONG_INT type.
667:                    return ((defType == StoredFormatIds.INT_TYPE_ID) || (defType == StoredFormatIds.LONGINT_TYPE_ID));
668:
669:                case StoredFormatIds.DECIMAL_TYPE_ID:
670:                    if (defType == StoredFormatIds.DECIMAL_TYPE_ID) {
671:                        // only valid if scale and precision are within
672:                        // those of the column.  Note that scale here should
673:                        // exclude any trailing 0's after the decimal
674:                        DataTypeDescriptor defDesc = defaultNode
675:                                .getTypeServices();
676:                        int len = defaultText.length();
677:                        int precision = defDesc.getPrecision();
678:                        int scale = defDesc.getScale();
679:                        for (int i = 1; i <= scale; scale--, precision--) {
680:                            if (defaultText.charAt(len - i) != '0')
681:                                break;
682:                        }
683:                        return ((scale <= columnDesc.getScale()) && ((precision - scale) <= (columnDesc
684:                                .getPrecision() - columnDesc.getScale())));
685:                    } else if ((defType == StoredFormatIds.LONGINT_TYPE_ID)
686:                            || (defType == StoredFormatIds.INT_TYPE_ID)) {
687:                        // only valid if number of digits is within limits of
688:                        // the decimal column.  We'll check this at insertion time;
689:                        // see Beetle 5585 regarding the need to move that check to
690:                        // here instead of waiting until insert time.  Until that's
691:                        // done, just allow this and wait for insertion...
692:                        return true;
693:                    } else
694:                        // no other types allowed.
695:                        return false;
696:
697:                case StoredFormatIds.CHAR_TYPE_ID:
698:                case StoredFormatIds.VARCHAR_TYPE_ID:
699:                case StoredFormatIds.LONGVARCHAR_TYPE_ID:
700:                    // only valid if the default type is a character string.
701:                    // That's not to say that all character defaults are
702:                    // valid, but we only check for character string here;
703:                    // further checking will be done at insertion time.  See
704:                    // beetle 5585 regarding the need to move that check
705:                    // to here instead of waiting until insert time.
706:                    return (defType == StoredFormatIds.CHAR_TYPE_ID);
707:
708:                case StoredFormatIds.BIT_TYPE_ID:
709:                case StoredFormatIds.VARBIT_TYPE_ID:
710:                case StoredFormatIds.LONGVARBIT_TYPE_ID:
711:                    // only valid if the default type is a BIT string.
712:                    return (defType == StoredFormatIds.BIT_TYPE_ID);
713:
714:                case StoredFormatIds.USERDEFINED_TYPE_ID_V3:
715:                    // default is only valid if it's the same type as the column.
716:                    return (defType == colType);
717:
718:                case StoredFormatIds.BLOB_TYPE_ID:
719:                case StoredFormatIds.CLOB_TYPE_ID:
720:                case StoredFormatIds.SMALLINT_TYPE_ID:
721:                case StoredFormatIds.REAL_TYPE_ID:
722:                case StoredFormatIds.DOUBLE_TYPE_ID:
723:                case StoredFormatIds.DATE_TYPE_ID:
724:                case StoredFormatIds.TIME_TYPE_ID:
725:                case StoredFormatIds.TIMESTAMP_TYPE_ID:
726:                    // For these types, validity checks will be performed
727:                    // by Cloudscape at insertion time--see beetle 5585 regarding
728:                    // the need to do such checks here instead of later.  For now,
729:                    // just assume we're okay.
730:                    return true;
731:
732:                default:
733:                    // All other default type checks either 
734:                    // (TINYINT, NATIONAL_CHAR, etc), or 2) require a DB2 cast-
735:                    // function (ex. blob(...), which Cloudscape doesn't
736:                    // support yet--see Beetle 5281), and so they are not
737:                    // valid for Cloudscape running in DB2 compatibility mode.
738:                    return false;
739:
740:                }
741:
742:            }
743:
744:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.