Source Code Cross Referenced for TableElementList.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.TableElementList
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.sanity.SanityManager;
025:
026:        import org.apache.derby.iapi.error.StandardException;
027:
028:        import org.apache.derby.iapi.sql.compile.CompilerContext;
029:        import org.apache.derby.iapi.sql.compile.C_NodeTypes;
030:
031:        import org.apache.derby.iapi.types.DataTypeDescriptor;
032:
033:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
034:        import org.apache.derby.iapi.sql.dictionary.DataDictionary;
035:        import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
036:        import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
037:
038:        import org.apache.derby.iapi.sql.depend.DependencyManager;
039:        import org.apache.derby.iapi.sql.depend.ProviderInfo;
040:        import org.apache.derby.iapi.sql.depend.ProviderList;
041:
042:        import org.apache.derby.iapi.reference.SQLState;
043:
044:        import org.apache.derby.impl.sql.execute.ColumnInfo;
045:        import org.apache.derby.impl.sql.execute.ConstraintInfo;
046:        import org.apache.derby.impl.sql.execute.ConstraintConstantAction;
047:        import org.apache.derby.impl.sql.execute.IndexConstantAction;
048:
049:        import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
050:        import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
051:
052:        import org.apache.derby.catalog.UUID;
053:
054:        import java.util.Hashtable;
055:        import java.util.Vector;
056:
057:        /**
058:         * A TableElementList represents the list of columns and other table elements
059:         * such as constraints in a CREATE TABLE or ALTER TABLE statement.
060:         *
061:         * @author Jeff Lichtman
062:         */
063:
064:        public class TableElementList extends QueryTreeNodeVector {
065:            private int numColumns;
066:            private TableDescriptor td;
067:
068:            /**
069:             * Add a TableElementNode to this TableElementList
070:             *
071:             * @param tableElement	The TableElementNode to add to this list
072:             */
073:
074:            public void addTableElement(TableElementNode tableElement) {
075:                addElement(tableElement);
076:                if ((tableElement instanceof  ColumnDefinitionNode)
077:                        || tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN) {
078:                    numColumns++;
079:                }
080:            }
081:
082:            /**
083:             * Convert this object to a String.  See comments in QueryTreeNode.java
084:             * for how this should be done for tree printing.
085:             *
086:             * @return	This object as a String
087:             */
088:
089:            public String toString() {
090:                if (SanityManager.DEBUG) {
091:                    StringBuffer buffer = new StringBuffer("");
092:
093:                    for (int index = 0; index < size(); index++) {
094:                        buffer.append(elementAt(index).toString()).append("\n");
095:                    }
096:
097:                    return buffer.toString();
098:                } else {
099:                    return "";
100:                }
101:            }
102:
103:            /**
104:             * Validate this TableElementList.  This includes checking for
105:             * duplicate columns names, and checking that user types really exist.
106:             *
107:             * @param ddlStmt	DDLStatementNode which contains this list
108:             * @param dd		DataDictionary to use
109:             * @param td		TableDescriptor for table, if existing table.
110:             *
111:             * @exception StandardException		Thrown on error
112:             */
113:            void validate(DDLStatementNode ddlStmt, DataDictionary dd,
114:                    TableDescriptor td) throws StandardException {
115:                this .td = td;
116:                int numAutoCols = 0;
117:
118:                int size = size();
119:                Hashtable columnHT = new Hashtable(size + 2, (float) .999);
120:                Hashtable constraintHT = new Hashtable(size + 2, (float) .999);
121:                //all the primary key/unique key constraints for this table
122:                Vector constraintsVector = new Vector();
123:
124:                //special case for alter table (td is not null in case of alter table)
125:                if (td != null) {
126:                    //In case of alter table, get the already existing primary key and unique
127:                    //key constraints for this table. And then we will compare them with  new
128:                    //primary key/unique key constraint column lists.
129:                    ConstraintDescriptorList cdl = dd
130:                            .getConstraintDescriptors(td);
131:                    ConstraintDescriptor cd;
132:
133:                    if (cdl != null) //table does have some pre-existing constraints defined on it
134:                    {
135:                        for (int i = 0; i < cdl.size(); i++) {
136:                            cd = cdl.elementAt(i);
137:                            //if the constraint type is not primary key or unique key, ignore it.
138:                            if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT
139:                                    || cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)
140:                                constraintsVector.addElement(cd);
141:                        }
142:                    }
143:                }
144:
145:                int tableType = TableDescriptor.BASE_TABLE_TYPE;
146:                if (ddlStmt instanceof  CreateTableNode)
147:                    tableType = ((CreateTableNode) ddlStmt).tableType;
148:
149:                for (int index = 0; index < size; index++) {
150:                    TableElementNode tableElement = (TableElementNode) elementAt(index);
151:
152:                    if (tableElement instanceof  ColumnDefinitionNode) {
153:                        ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
154:                        if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE
155:                                && (cdn.getDataTypeServices().getTypeId()
156:                                        .isLongConcatableTypeId() || cdn
157:                                        .getDataTypeServices().getTypeId()
158:                                        .isUserDefinedTypeId())) {
159:                            throw StandardException.newException(
160:                                    SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED,
161:                                    cdn.getColumnName());
162:                        }
163:                        checkForDuplicateColumns(ddlStmt, columnHT, cdn
164:                                .getColumnName());
165:                        cdn.checkUserType(td);
166:                        cdn.bindAndValidateDefault(dd, td);
167:
168:                        cdn.validateAutoincrement(dd, td, tableType);
169:
170:                        if (tableElement instanceof  ModifyColumnNode) {
171:                            ModifyColumnNode mcdn = (ModifyColumnNode) cdn;
172:                            mcdn.checkExistingConstraints(td);
173:                        } else if (cdn.isAutoincrementColumn())
174:                            numAutoCols++;
175:                    } else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN) {
176:                        String colName = tableElement.getName();
177:                        if (td.getColumnDescriptor(colName) == null) {
178:                            throw StandardException.newException(
179:                                    SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,
180:                                    colName, td.getQualifiedName());
181:                        }
182:                        break;
183:                    }
184:
185:                    /* The rest of this method deals with validating constraints */
186:                    if (!(tableElement.hasConstraint())) {
187:                        continue;
188:                    }
189:
190:                    ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;
191:
192:                    cdn.bind(ddlStmt, dd);
193:
194:                    //if constraint is primary key or unique key, add it to the vector
195:                    if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT
196:                            || cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT) {
197:                        /* In case of create table, the vector can have only ConstraintDefinitionNode
198:                         * elements. In case of alter table, it can have both ConstraintDefinitionNode
199:                         * (for new constraints) and ConstraintDescriptor(for pre-existing constraints).
200:                         */
201:
202:                        Object destConstraint;
203:                        String destName = null;
204:                        String[] destColumnNames = null;
205:
206:                        for (int i = 0; i < constraintsVector.size(); i++) {
207:
208:                            destConstraint = constraintsVector.elementAt(i);
209:                            if (destConstraint instanceof  ConstraintDefinitionNode) {
210:                                ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode) destConstraint;
211:                                destName = destCDN.getConstraintMoniker();
212:                                destColumnNames = destCDN.getColumnList()
213:                                        .getColumnNames();
214:                            } else if (destConstraint instanceof  ConstraintDescriptor) {
215:                                //will come here only for pre-existing constraints in case of alter table
216:                                ConstraintDescriptor destCD = (ConstraintDescriptor) destConstraint;
217:                                destName = destCD.getConstraintName();
218:                                destColumnNames = destCD.getColumnDescriptors()
219:                                        .getColumnNames();
220:                            }
221:                            //check if there are multiple constraints with same set of columns
222:                            if (columnsMatch(cdn.getColumnList()
223:                                    .getColumnNames(), destColumnNames))
224:                                throw StandardException
225:                                        .newException(
226:                                                SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS,
227:                                                cdn.getConstraintMoniker(),
228:                                                destName);
229:                        }
230:                        constraintsVector.addElement(cdn);
231:                    }
232:
233:                    /* Make sure that there are no duplicate constraint names in the list */
234:                    if (cdn instanceof  ConstraintDefinitionNode)
235:                        checkForDuplicateConstraintNames(ddlStmt, constraintHT,
236:                                cdn.getConstraintMoniker());
237:
238:                    /* Make sure that the constraint we are trying to drop exists */
239:                    if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT) {
240:                        /*
241:                         ** If no schema descriptor, then must be an invalid
242:                         ** schema name.
243:                         */
244:
245:                        String dropConstraintName = cdn.getConstraintMoniker();
246:
247:                        if (dropConstraintName != null) {
248:
249:                            String dropSchemaName = cdn.getDropSchemaName();
250:
251:                            SchemaDescriptor sd = dropSchemaName == null ? td
252:                                    .getSchemaDescriptor()
253:                                    : getSchemaDescriptor(dropSchemaName);
254:
255:                            ConstraintDescriptor cd = dd
256:                                    .getConstraintDescriptorByName(td, sd,
257:                                            dropConstraintName, false);
258:                            if (cd == null) {
259:                                throw StandardException
260:                                        .newException(
261:                                                SQLState.LANG_DROP_NON_EXISTENT_CONSTRAINT,
262:                                                (sd.getSchemaName() + "." + dropConstraintName),
263:                                                td.getQualifiedName());
264:                            }
265:                            /* Statement is dependendent on the ConstraintDescriptor */
266:                            getCompilerContext().createDependency(cd);
267:                        }
268:                    }
269:
270:                    if (cdn.hasPrimaryKeyConstraint()) {
271:                        // for PRIMARY KEY, check that columns are unique
272:                        verifyUniqueColumnList(ddlStmt, cdn);
273:
274:                        if (td == null) {
275:                            // in CREATE TABLE so set PRIMARY KEY columns to NOT NULL
276:                            setColumnListToNotNull(cdn);
277:                        } else {
278:                            // in ALTER TABLE so raise error if any columns are nullable
279:                            checkForNullColumns(cdn, td);
280:                        }
281:                    } else if (cdn.hasUniqueKeyConstraint()) {
282:                        // for UNIQUE, check that columns are unique and NOT NULL
283:                        verifyUniqueColumnList(ddlStmt, cdn);
284:                        checkForNullColumns(cdn, td);
285:                    } else if (cdn.hasForeignKeyConstraint()) {
286:                        // for FOREIGN KEY, check that columns are unique
287:                        verifyUniqueColumnList(ddlStmt, cdn);
288:                    }
289:                }
290:
291:                /* Can have only one autoincrement column in DB2 mode */
292:                if (numAutoCols > 1)
293:                    throw StandardException
294:                            .newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);
295:
296:            }
297:
298:            /**
299:             * Count the number of constraints of the specified type.
300:             *
301:             * @param constraintType	The constraint type to search for.
302:             *
303:             * @return int	The number of constraints of the specified type.
304:             */
305:            public int countConstraints(int constraintType) {
306:                int numConstraints = 0;
307:                int size = size();
308:
309:                for (int index = 0; index < size; index++) {
310:                    ConstraintDefinitionNode cdn;
311:                    TableElementNode element = (TableElementNode) elementAt(index);
312:
313:                    if (!(element instanceof  ConstraintDefinitionNode)) {
314:                        continue;
315:                    }
316:
317:                    cdn = (ConstraintDefinitionNode) element;
318:
319:                    if (constraintType == cdn.getConstraintType()) {
320:                        numConstraints++;
321:                    }
322:                }
323:
324:                return numConstraints;
325:            }
326:
327:            /**
328:             * Count the number of columns.
329:             *
330:             * @return int	The number of columns.
331:             */
332:            public int countNumberOfColumns() {
333:                return numColumns;
334:            }
335:
336:            /**
337:             * Fill in the ColumnInfo[] for this table element list.
338:             * 
339:             * @param colInfos	The ColumnInfo[] to be filled in.
340:             *
341:             * @return int		The number of constraints in the create table.
342:             */
343:            public int genColumnInfos(ColumnInfo[] colInfos) {
344:                int numConstraints = 0;
345:                int size = size();
346:
347:                for (int index = 0; index < size; index++) {
348:                    if (((TableElementNode) elementAt(index)).getElementType() == TableElementNode.AT_DROP_COLUMN) {
349:                        colInfos[index] = new ColumnInfo(
350:                                ((TableElementNode) elementAt(index)).getName(),
351:                                null, null, null, null, null, ColumnInfo.DROP,
352:                                0, 0, 0);
353:                        break;
354:                    }
355:
356:                    if (!(elementAt(index) instanceof  ColumnDefinitionNode)) {
357:                        if (SanityManager.DEBUG) {
358:                            SanityManager
359:                                    .ASSERT(
360:                                            elementAt(index) instanceof  ConstraintDefinitionNode,
361:                                            "elementAt(index) expected to be instanceof "
362:                                                    + "ConstraintDefinitionNode");
363:                        }
364:
365:                        /* Remember how many constraints that we've seen */
366:                        numConstraints++;
367:                        continue;
368:                    }
369:
370:                    ColumnDefinitionNode coldef = (ColumnDefinitionNode) elementAt(index);
371:
372:                    colInfos[index - numConstraints] = new ColumnInfo(
373:                            coldef.getColumnName(),
374:                            coldef.getDataTypeServices(),
375:                            coldef.getDefaultValue(),
376:                            coldef.getDefaultInfo(),
377:                            (UUID) null,
378:                            coldef.getOldDefaultUUID(),
379:                            coldef.getAction(),
380:                            (coldef.isAutoincrementColumn() ? coldef
381:                                    .getAutoincrementStart() : 0),
382:                            (coldef.isAutoincrementColumn() ? coldef
383:                                    .getAutoincrementIncrement() : 0),
384:                            (coldef.isAutoincrementColumn() ? coldef
385:                                    .getAutoinc_create_or_modify_Start_Increment()
386:                                    : -1));
387:
388:                    /* Remember how many constraints that we've seen */
389:                    if (coldef.hasConstraint()) {
390:                        numConstraints++;
391:                    }
392:                }
393:
394:                return numConstraints;
395:            }
396:
397:            /**
398:             * Append goobered up ResultColumns to the table's RCL.
399:             * This is useful for binding check constraints for CREATE and ALTER TABLE.
400:             *
401:             * @param table		The table in question.
402:             *
403:             * @exception StandardException		Thrown on error
404:             */
405:            public void appendNewColumnsToRCL(FromBaseTable table)
406:                    throws StandardException {
407:                int size = size();
408:                ResultColumnList rcl = table.getResultColumns();
409:                TableName exposedName = table.getTableName();
410:
411:                for (int index = 0; index < size; index++) {
412:                    if (elementAt(index) instanceof  ColumnDefinitionNode) {
413:                        ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);
414:                        ResultColumn resultColumn;
415:                        ValueNode valueNode;
416:
417:                        /* Build a ResultColumn/BaseColumnNode pair for the column */
418:                        valueNode = (ValueNode) getNodeFactory().getNode(
419:                                C_NodeTypes.BASE_COLUMN_NODE,
420:                                cdn.getColumnName(), exposedName,
421:                                cdn.getDataTypeServices(), getContextManager());
422:
423:                        resultColumn = (ResultColumn) getNodeFactory().getNode(
424:                                C_NodeTypes.RESULT_COLUMN,
425:                                cdn.getDataTypeServices(), valueNode,
426:                                getContextManager());
427:                        resultColumn.setName(cdn.getColumnName());
428:                        rcl.addElement(resultColumn);
429:                    }
430:                }
431:            }
432:
433:            /**
434:             * Bind and validate all of the check constraints in this list against
435:             * the specified FromList.  
436:             *
437:             * @param fromList		The FromList in question.
438:             *
439:             * @exception StandardException		Thrown on error
440:             */
441:            void bindAndValidateCheckConstraints(FromList fromList)
442:                    throws StandardException {
443:                CompilerContext cc;
444:                FromBaseTable table = (FromBaseTable) fromList.elementAt(0);
445:                int size = size();
446:
447:                cc = getCompilerContext();
448:
449:                Vector aggregateVector = new Vector();
450:
451:                for (int index = 0; index < size; index++) {
452:                    ConstraintDefinitionNode cdn;
453:                    TableElementNode element = (TableElementNode) elementAt(index);
454:                    ValueNode checkTree;
455:
456:                    if (!(element instanceof  ConstraintDefinitionNode)) {
457:                        continue;
458:                    }
459:
460:                    cdn = (ConstraintDefinitionNode) element;
461:
462:                    if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT) {
463:                        continue;
464:                    }
465:
466:                    checkTree = cdn.getCheckCondition();
467:
468:                    // bind the check condition
469:                    // verify that it evaluates to a boolean
470:                    final int previousReliability = cc.getReliability();
471:                    try {
472:                        /* Each check constraint can have its own set of dependencies.
473:                         * These dependencies need to be shared with the prepared
474:                         * statement as well.  We create a new auxiliary provider list
475:                         * for the check constraint, "push" it on the compiler context
476:                         * by swapping it with the current auxiliary provider list
477:                         * and the "pop" it when we're done by restoring the old 
478:                         * auxiliary provider list.
479:                         */
480:                        ProviderList apl = new ProviderList();
481:
482:                        ProviderList prevAPL = cc
483:                                .getCurrentAuxiliaryProviderList();
484:                        cc.setCurrentAuxiliaryProviderList(apl);
485:
486:                        // Tell the compiler context to only allow deterministic nodes
487:                        cc.setReliability(CompilerContext.CHECK_CONSTRAINT);
488:                        checkTree = checkTree.bindExpression(fromList,
489:                                (SubqueryList) null, aggregateVector);
490:
491:                        // no aggregates, please
492:                        if (aggregateVector.size() != 0) {
493:                            throw StandardException.newException(
494:                                    SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn
495:                                            .getConstraintText());
496:                        }
497:
498:                        checkTree = checkTree.checkIsBoolean();
499:                        cdn.setCheckCondition(checkTree);
500:
501:                        /* Save the APL off in the constraint node */
502:                        if (apl.size() > 0) {
503:                            cdn.setAuxiliaryProviderList(apl);
504:                        }
505:
506:                        // Restore the previous AuxiliaryProviderList
507:                        cc.setCurrentAuxiliaryProviderList(prevAPL);
508:                    } finally {
509:                        cc.setReliability(previousReliability);
510:                    }
511:
512:                    /* We have a valid check constraint, now build an array of
513:                     * 1-based columnIds that the constraint references.
514:                     */
515:                    ResultColumnList rcl = table.getResultColumns();
516:                    int numReferenced = rcl.countReferencedColumns();
517:                    int[] checkColumnReferences = new int[numReferenced];
518:
519:                    rcl.recordColumnReferences(checkColumnReferences, 1);
520:                    cdn.setCheckColumnReferences(checkColumnReferences);
521:
522:                    /* Now we build a list with only the referenced columns and
523:                     * copy it to the cdn.  Thus we can build the array of
524:                     * column names for the referenced columns during generate().
525:                     */
526:                    ResultColumnList refRCL = (ResultColumnList) getNodeFactory()
527:                            .getNode(C_NodeTypes.RESULT_COLUMN_LIST,
528:                                    getContextManager());
529:                    rcl.copyReferencedColumnsToNewList(refRCL);
530:
531:                    /* A column check constraint can only refer to that column. If this is a
532:                     * column constraint, we should have an RCL with that column
533:                     */
534:                    if (cdn.getColumnList() != null) {
535:                        String colName = ((ResultColumn) (cdn.getColumnList()
536:                                .elementAt(0))).getName();
537:                        if (numReferenced > 1
538:                                || !colName.equals(((ResultColumn) (refRCL
539:                                        .elementAt(0))).getName()))
540:                            throw StandardException.newException(
541:                                    SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT,
542:                                    colName);
543:
544:                    }
545:                    cdn.setColumnList(refRCL);
546:
547:                    /* Clear the column references in the RCL so each check constraint
548:                     * starts with a clean list.
549:                     */
550:                    rcl.clearColumnReferences();
551:                }
552:            }
553:
554:            /**
555:             * Fill in the ConstraintConstantAction[] for this create/alter table.
556:             * 
557:             * @param conActions	The ConstraintConstantAction[] to be filled in.
558:             * @param tableName		The name of the Table being created.
559:             * @param tableSd		The schema for that table.
560:             * @param dd	    	The DataDictionary
561:             *
562:             * @exception StandardException		Thrown on failure
563:             */
564:            void genConstraintActions(ConstraintConstantAction[] conActions,
565:                    String tableName, SchemaDescriptor tableSd,
566:                    DataDictionary dd) throws StandardException {
567:                int size = size();
568:                int conActionIndex = 0;
569:                for (int index = 0; index < size; index++) {
570:                    String[] columnNames = null;
571:                    TableElementNode ten = (TableElementNode) elementAt(index);
572:                    IndexConstantAction indexAction = null;
573:
574:                    if (!ten.hasConstraint()) {
575:                        continue;
576:                    }
577:
578:                    if (ten instanceof  ColumnDefinitionNode) {
579:                        continue;
580:                    }
581:
582:                    ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten;
583:
584:                    if (constraintDN.getColumnList() != null) {
585:                        columnNames = new String[constraintDN.getColumnList()
586:                                .size()];
587:                        constraintDN.getColumnList().exportNames(columnNames);
588:                    }
589:
590:                    int constraintType = constraintDN.getConstraintType();
591:                    String constraintText = constraintDN.getConstraintText();
592:
593:                    /*
594:                     ** If the constraint is not named (e.g.
595:                     ** create table x (x int primary key)), then
596:                     ** the constraintSd is the same as the table.
597:                     */
598:                    String constraintName = constraintDN.getConstraintMoniker();
599:
600:                    /* At execution time, we will generate a unique name for the backing
601:                     * index (for CREATE CONSTRAINT) and we will look up the conglomerate
602:                     * name (for DROP CONSTRAINT).
603:                     */
604:                    if (constraintDN.requiresBackingIndex()) {
605:                        indexAction = genIndexAction(constraintDN
606:                                .requiresUniqueIndex(), null, constraintDN,
607:                                columnNames, true, tableSd, tableName,
608:                                constraintType, dd);
609:                    }
610:
611:                    if (constraintType == DataDictionary.DROP_CONSTRAINT) {
612:                        conActions[conActionIndex] = getGenericConstantActionFactory()
613:                                .getDropConstraintConstantAction(
614:                                        constraintName,
615:                                        constraintDN.getDropSchemaName(), /// FiX
616:                                        tableName, td.getUUID(),
617:                                        tableSd.getSchemaName(), indexAction,
618:                                        constraintDN.getDropBehavior(),
619:                                        constraintDN.getVerifyType());
620:                    } else {
621:                        ProviderList apl = constraintDN
622:                                .getAuxiliaryProviderList();
623:                        ConstraintInfo refInfo = null;
624:                        ProviderInfo[] providerInfos = null;
625:
626:                        if (constraintDN instanceof  FKConstraintDefinitionNode) {
627:                            refInfo = ((FKConstraintDefinitionNode) constraintDN)
628:                                    .getReferencedConstraintInfo();
629:                        }
630:
631:                        /* Create the ProviderInfos, if the constraint is dependent on any Providers */
632:                        if (apl != null && apl.size() > 0) {
633:                            /* Get all the dependencies for the current statement and transfer
634:                             * them to this view.
635:                             */
636:                            DependencyManager dm = dd.getDependencyManager();
637:                            providerInfos = dm.getPersistentProviderInfos(apl);
638:                        } else {
639:                            providerInfos = new ProviderInfo[0];
640:                            // System.out.println("TABLE ELEMENT LIST EMPTY");
641:                        }
642:
643:                        conActions[conActionIndex++] = getGenericConstantActionFactory()
644:                                .getCreateConstraintConstantAction(
645:                                        constraintName,
646:                                        constraintType,
647:                                        tableName,
648:                                        ((td != null) ? td.getUUID()
649:                                                : (UUID) null),
650:                                        tableSd.getSchemaName(), columnNames,
651:                                        indexAction, constraintText, true, // enabled
652:                                        refInfo, providerInfos);
653:                    }
654:                }
655:            }
656:
657:            //check if one array is same as another 
658:            private boolean columnsMatch(String[] columnNames1,
659:                    String[] columnNames2) {
660:                int srcCount, srcSize, destCount, destSize;
661:                boolean match = true;
662:
663:                if (columnNames1.length != columnNames2.length)
664:                    return false;
665:
666:                srcSize = columnNames1.length;
667:                destSize = columnNames2.length;
668:
669:                for (srcCount = 0; srcCount < srcSize; srcCount++) {
670:                    match = false;
671:                    for (destCount = 0; destCount < destSize; destCount++) {
672:                        if (columnNames1[srcCount]
673:                                .equals(columnNames2[destCount])) {
674:                            match = true;
675:                            break;
676:                        }
677:                    }
678:                    if (match == false)
679:                        return false;
680:                }
681:
682:                return true;
683:            }
684:
685:            private IndexConstantAction genIndexAction(boolean isUnique,
686:                    String indexName, ConstraintDefinitionNode cdn,
687:                    String[] columnNames, boolean isConstraint,
688:                    SchemaDescriptor sd, String tableName, int constraintType,
689:                    DataDictionary dd) throws StandardException {
690:                if (indexName == null) {
691:                    indexName = cdn.getBackingIndexName(dd);
692:                }
693:
694:                if (constraintType == DataDictionary.DROP_CONSTRAINT) {
695:                    return getGenericConstantActionFactory()
696:                            .getDropIndexConstantAction(null, indexName,
697:                                    tableName, sd.getSchemaName(),
698:                                    td.getUUID(), td.getHeapConglomerateId());
699:                } else {
700:                    boolean[] isAscending = new boolean[columnNames.length];
701:                    for (int i = 0; i < isAscending.length; i++)
702:                        isAscending[i] = true;
703:                    return getGenericConstantActionFactory()
704:                            .getCreateIndexConstantAction(
705:                                    isUnique,
706:                                    "BTREE", // indexType
707:                                    sd.getSchemaName(),
708:                                    indexName,
709:                                    tableName,
710:                                    ((td != null) ? td.getUUID() : (UUID) null),
711:                                    0, // conglomId
712:                                    columnNames, isAscending, isConstraint,
713:                                    cdn.getBackingIndexUUID(),
714:                                    cdn.getProperties());
715:                }
716:            }
717:
718:            /**
719:             * Check to make sure that there are no duplicate column names
720:             * in the list.  (The comparison here is case sensitive.
721:             * The work of converting column names that are not quoted
722:             * identifiers to upper case is handled by the parser.)
723:             * RESOLVE: This check will also be performed by alter table.
724:             *
725:             * @param ddlStmt	DDLStatementNode which contains this list
726:             * @param ht		Hashtable for enforcing uniqueness.
727:             * @param colName	Column name to check for.
728:             *
729:             * @exception StandardException		Thrown on error
730:             */
731:            private void checkForDuplicateColumns(DDLStatementNode ddlStmt,
732:                    Hashtable ht, String colName) throws StandardException {
733:                Object object = ht.put(colName, colName);
734:                if (object != null) {
735:                    /* RESOLVE - different error messages for create and alter table */
736:                    if (ddlStmt instanceof  CreateTableNode) {
737:                        throw StandardException.newException(
738:                                SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE,
739:                                colName);
740:                    }
741:                }
742:            }
743:
744:            /**
745:             * Check to make sure that there are no duplicate constraint names
746:             * in the list.  (The comparison here is case sensitive.
747:             * The work of converting column names that are not quoted
748:             * identifiers to upper case is handled by the parser.)
749:             * RESOLVE: This check will also be performed by alter table.
750:             *
751:             * @param ddlStmt	DDLStatementNode which contains this list
752:             *
753:             * @exception StandardException		Thrown on error
754:             */
755:            private void checkForDuplicateConstraintNames(
756:                    DDLStatementNode ddlStmt, Hashtable ht,
757:                    String constraintName) throws StandardException {
758:                if (constraintName == null)
759:                    return;
760:
761:                Object object = ht.put(constraintName, constraintName);
762:                if (object != null) {
763:
764:                    /* RESOLVE - different error messages for create and alter table */
765:                    if (ddlStmt instanceof  CreateTableNode) {
766:                        /* RESOLVE - new error message */
767:                        throw StandardException.newException(
768:                                SQLState.LANG_DUPLICATE_CONSTRAINT_NAME_CREATE,
769:                                constraintName);
770:                    }
771:                }
772:            }
773:
774:            /**
775:             * Verify that a primary/unique table constraint has a valid column list.
776:             * (All columns in table and no duplicates.)
777:             *
778:             * @param ddlStmt	The outer DDLStatementNode
779:             * @param cdn		The ConstraintDefinitionNode
780:             *
781:             * @exception	StandardException	Thrown if the column list is invalid
782:             */
783:            private void verifyUniqueColumnList(DDLStatementNode ddlStmt,
784:                    ConstraintDefinitionNode cdn) throws StandardException {
785:                String invalidColName;
786:
787:                /* Verify that every column in the list appears in the table's list of columns */
788:                if (ddlStmt instanceof  CreateTableNode) {
789:                    invalidColName = cdn.getColumnList()
790:                            .verifyCreateConstraintColumnList(this );
791:                    if (invalidColName != null) {
792:                        throw StandardException
793:                                .newException(
794:                                        SQLState.LANG_INVALID_CREATE_CONSTRAINT_COLUMN_LIST,
795:                                        ddlStmt.getRelativeName(),
796:                                        invalidColName);
797:                    }
798:                } else {
799:                    /* RESOLVE - alter table will need to get table descriptor */
800:                }
801:
802:                /* Check the uniqueness of the column names within the list */
803:                invalidColName = cdn.getColumnList().verifyUniqueNames(false);
804:                if (invalidColName != null) {
805:                    throw StandardException.newException(
806:                            SQLState.LANG_DUPLICATE_CONSTRAINT_COLUMN_NAME,
807:                            invalidColName);
808:                }
809:            }
810:
811:            /**
812:             * Set all columns in that appear in a PRIMARY KEY constraint in a CREATE TABLE statement to NOT NULL.
813:             *
814:             * @param cdn		The ConstraintDefinitionNode for a PRIMARY KEY constraint
815:             */
816:            private void setColumnListToNotNull(ConstraintDefinitionNode cdn) {
817:                ResultColumnList rcl = cdn.getColumnList();
818:                int rclSize = rcl.size();
819:                for (int index = 0; index < rclSize; index++) {
820:                    String colName = ((ResultColumn) rcl.elementAt(index))
821:                            .getName();
822:                    DataTypeDescriptor dtd = getColumnDataTypeDescriptor(colName);
823:                    dtd.setNullability(false);
824:                }
825:            }
826:
827:            private void checkForNullColumns(ConstraintDefinitionNode cdn,
828:                    TableDescriptor td) throws StandardException {
829:                ResultColumnList rcl = cdn.getColumnList();
830:                int rclSize = rcl.size();
831:                for (int index = 0; index < rclSize; index++) {
832:                    String colName = ((ResultColumn) rcl.elementAt(index))
833:                            .getName();
834:                    DataTypeDescriptor dtd;
835:                    if (td == null) {
836:                        dtd = getColumnDataTypeDescriptor(colName);
837:                    } else {
838:                        dtd = getColumnDataTypeDescriptor(colName, td);
839:                    }
840:                    // todo dtd may be null if the column does not exist, we should check that first
841:                    if (dtd != null && dtd.isNullable()) {
842:                        throw StandardException
843:                                .newException(
844:                                        SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS,
845:                                        colName);
846:                    }
847:                }
848:            }
849:
850:            private DataTypeDescriptor getColumnDataTypeDescriptor(
851:                    String colName) {
852:                int size = size();
853:
854:                for (int index = 0; index < size; index++) {
855:                    TableElementNode tableElement = (TableElementNode) elementAt(index);
856:
857:                    if (tableElement instanceof  ColumnDefinitionNode) {
858:                        ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;
859:                        if (colName.equals(cdn.getColumnName())) {
860:                            return cdn.getDataTypeServices();
861:                        }
862:                    }
863:                }
864:                return null;
865:            }
866:
867:            private DataTypeDescriptor getColumnDataTypeDescriptor(
868:                    String colName, TableDescriptor td) {
869:                // check existing columns
870:                ColumnDescriptor cd = td.getColumnDescriptor(colName);
871:                if (cd != null) {
872:                    return cd.getType();
873:                }
874:                // check for new columns
875:                return getColumnDataTypeDescriptor(colName);
876:            }
877:
878:            /**
879:             * Determine whether or not the parameter matches a column name in this list.
880:             *
881:             * @param colName	The column name to search for.
882:             *
883:             * @return boolean  Whether or not a match is found.
884:             */
885:            public boolean containsColumnName(String colName) {
886:                int size = size();
887:                for (int index = 0; index < size; index++) {
888:                    TableElementNode tableElement = (TableElementNode) elementAt(index);
889:
890:                    if (tableElement instanceof  ColumnDefinitionNode) {
891:                        if (colName
892:                                .equals(((ColumnDefinitionNode) tableElement)
893:                                        .getName())) {
894:                            return true;
895:                        }
896:                    }
897:                }
898:
899:                return false;
900:            }
901:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.