Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / compile / TableElementList.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/compile/TableElementList.java
new file mode 100644 (file)
index 0000000..82e642e
--- /dev/null
@@ -0,0 +1,1011 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.TableElementList\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package        org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.compile.CompilerContext;\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.StringDataValue;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.ProviderInfo;\r
+import org.apache.derby.iapi.sql.depend.ProviderList;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+\r
+import org.apache.derby.impl.sql.execute.ColumnInfo;\r
+import org.apache.derby.impl.sql.execute.ConstraintInfo;\r
+import org.apache.derby.impl.sql.execute.ConstraintConstantAction;\r
+import org.apache.derby.impl.sql.execute.IndexConstantAction;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;\r
+import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+\r
+import java.util.Hashtable;\r
+import java.util.Vector;\r
+\r
+/**\r
+ * A TableElementList represents the list of columns and other table elements\r
+ * such as constraints in a CREATE TABLE or ALTER TABLE statement.\r
+ *\r
+ */\r
+\r
+public class TableElementList extends QueryTreeNodeVector\r
+{\r
+       private int                             numColumns;\r
+       private TableDescriptor td;\r
+\r
+       /**\r
+        * Add a TableElementNode to this TableElementList\r
+        *\r
+        * @param tableElement  The TableElementNode to add to this list\r
+        */\r
+\r
+       public void addTableElement(TableElementNode tableElement)\r
+       {\r
+               addElement(tableElement);\r
+               if ((tableElement instanceof ColumnDefinitionNode) ||\r
+                       tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)\r
+               {\r
+                       numColumns++;\r
+               }\r
+       } \r
+\r
+       /**\r
+        * Convert this object to a String.  See comments in QueryTreeNode.java\r
+        * for how this should be done for tree printing.\r
+        *\r
+        * @return      This object as a String\r
+        */\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       StringBuffer    buffer = new StringBuffer("");\r
+\r
+                       for (int index = 0; index < size(); index++)\r
+                       {\r
+                               buffer.append(elementAt(index).toString()).append("\n");\r
+                       }\r
+\r
+                       return buffer.toString();\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Use the passed schema descriptor's collation type to set the collation\r
+        * of the character string types in create table node\r
+        * @param sd\r
+        */\r
+       void setCollationTypesOnCharacterStringColumns(SchemaDescriptor sd) {\r
+               int                     size = size();\r
+               int collationType = sd.getCollationType();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       TableElementNode tableElement = (TableElementNode) elementAt(index);\r
+\r
+                       if (tableElement instanceof ColumnDefinitionNode)\r
+                       {\r
+                               ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);\r
+                               if (cdn.getDataTypeServices().getTypeId().isStringTypeId()) {\r
+                                       cdn.getDataTypeServices().setCollationType(collationType);\r
+                                       cdn.getDataTypeServices().setCollationDerivation(StringDataValue.COLLATION_DERIVATION_IMPLICIT);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Validate this TableElementList.  This includes checking for\r
+        * duplicate columns names, and checking that user types really exist.\r
+        *\r
+        * @param ddlStmt       DDLStatementNode which contains this list\r
+        * @param dd            DataDictionary to use\r
+        * @param td            TableDescriptor for table, if existing table.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void validate(DDLStatementNode ddlStmt,\r
+                                            DataDictionary dd,\r
+                                                TableDescriptor td)\r
+                                       throws StandardException\r
+       {\r
+               this.td = td;\r
+               int numAutoCols = 0;\r
+\r
+               int                     size = size();\r
+               Hashtable       columnHT = new Hashtable(size + 2, (float) .999);\r
+               Hashtable       constraintHT = new Hashtable(size + 2, (float) .999);\r
+               //all the primary key/unique key constraints for this table\r
+               Vector constraintsVector = new Vector();\r
+\r
+               //special case for alter table (td is not null in case of alter table)\r
+               if (td != null)\r
+               {\r
+                       //In case of alter table, get the already existing primary key and unique\r
+                       //key constraints for this table. And then we will compare them with  new\r
+                       //primary key/unique key constraint column lists.\r
+                       ConstraintDescriptorList cdl = dd.getConstraintDescriptors(td);\r
+                       ConstraintDescriptor cd;\r
+\r
+                       if (cdl != null) //table does have some pre-existing constraints defined on it\r
+                       {\r
+                               for (int i=0; i<cdl.size();i++)\r
+                               {\r
+                                       cd = cdl.elementAt(i);\r
+                                       //if the constraint type is not primary key or unique key, ignore it.\r
+                                       if (cd.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||\r
+                                       cd.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)\r
+                                               constraintsVector.addElement(cd);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               int tableType = TableDescriptor.BASE_TABLE_TYPE;\r
+               if (ddlStmt instanceof CreateTableNode)\r
+                       tableType = ((CreateTableNode)ddlStmt).tableType;\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       TableElementNode tableElement = (TableElementNode) elementAt(index);\r
+\r
+                       if (tableElement instanceof ColumnDefinitionNode)\r
+                       {\r
+                               ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);\r
+                               if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE &&\r
+                                       (cdn.getDataTypeServices().getTypeId().isLongConcatableTypeId() ||\r
+                                       cdn.getDataTypeServices().getTypeId().isUserDefinedTypeId()))\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_LONG_DATA_TYPE_NOT_ALLOWED, cdn.getColumnName());\r
+                               }\r
+                               checkForDuplicateColumns(ddlStmt, columnHT, cdn.getColumnName());\r
+                               cdn.checkUserType(td);\r
+                               cdn.bindAndValidateDefault(dd, td);\r
+\r
+                               cdn.validateAutoincrement(dd, td, tableType);\r
+\r
+                               if (tableElement instanceof ModifyColumnNode)\r
+                               {\r
+                                       ModifyColumnNode mcdn = (ModifyColumnNode)cdn;\r
+                                       mcdn.checkExistingConstraints(td);\r
+                                       mcdn.useExistingCollation(td);\r
+                               } else if (cdn.isAutoincrementColumn())\r
+                                       numAutoCols ++;\r
+                       }\r
+                       else if (tableElement.getElementType() == TableElementNode.AT_DROP_COLUMN)\r
+                       {\r
+                               String colName = tableElement.getName();\r
+                               if (td.getColumnDescriptor(colName) == null)\r
+                               {\r
+                                       throw StandardException.newException(\r
+                                                                                               SQLState.LANG_COLUMN_NOT_FOUND_IN_TABLE,\r
+                                                                                               colName,\r
+                                                                                               td.getQualifiedName());\r
+                               }\r
+                               break;\r
+                       }\r
+\r
+                       /* The rest of this method deals with validating constraints */\r
+                       if (! (tableElement.hasConstraint()))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       ConstraintDefinitionNode cdn = (ConstraintDefinitionNode) tableElement;\r
+\r
+                       cdn.bind(ddlStmt, dd);\r
+\r
+                       //if constraint is primary key or unique key, add it to the vector\r
+                       if (cdn.getConstraintType() == DataDictionary.PRIMARYKEY_CONSTRAINT ||\r
+                       cdn.getConstraintType() == DataDictionary.UNIQUE_CONSTRAINT)\r
+                       {\r
+                               /* In case of create table, the vector can have only ConstraintDefinitionNode\r
+                               * elements. In case of alter table, it can have both ConstraintDefinitionNode\r
+                               * (for new constraints) and ConstraintDescriptor(for pre-existing constraints).\r
+                               */\r
+\r
+                               Object destConstraint;\r
+                               String destName = null;\r
+                               String[] destColumnNames = null;\r
+\r
+                               for (int i=0; i<constraintsVector.size();i++)\r
+                               {\r
+\r
+                                       destConstraint = constraintsVector.elementAt(i);\r
+                                       if (destConstraint instanceof ConstraintDefinitionNode)\r
+                                       {\r
+                                               ConstraintDefinitionNode destCDN = (ConstraintDefinitionNode)destConstraint;\r
+                                               destName = destCDN.getConstraintMoniker();\r
+                                               destColumnNames = destCDN.getColumnList().getColumnNames();\r
+                                       }\r
+                                       else if (destConstraint instanceof ConstraintDescriptor)\r
+                                       {\r
+                                               //will come here only for pre-existing constraints in case of alter table\r
+                                               ConstraintDescriptor destCD = (ConstraintDescriptor)destConstraint;\r
+                                               destName = destCD.getConstraintName();\r
+                                               destColumnNames = destCD.getColumnDescriptors().getColumnNames();\r
+                                       }\r
+                                       //check if there are multiple constraints with same set of columns\r
+                                       if (columnsMatch(cdn.getColumnList().getColumnNames(), destColumnNames))\r
+                                               throw StandardException.newException(SQLState.LANG_MULTIPLE_CONSTRAINTS_WITH_SAME_COLUMNS,\r
+                                               cdn.getConstraintMoniker(), destName);\r
+                               }\r
+                               constraintsVector.addElement(cdn);\r
+                       }\r
+\r
+                       /* Make sure that there are no duplicate constraint names in the list */\r
+                       if (cdn instanceof ConstraintDefinitionNode)\r
+                               checkForDuplicateConstraintNames(ddlStmt, constraintHT, cdn.getConstraintMoniker());\r
+\r
+                       /* Make sure that the constraint we are trying to drop exists */\r
+                       if (cdn.getConstraintType() == DataDictionary.DROP_CONSTRAINT)\r
+                       {\r
+                               /*\r
+                               ** If no schema descriptor, then must be an invalid\r
+                               ** schema name.\r
+                               */\r
+\r
+                               String dropConstraintName = cdn.getConstraintMoniker();\r
+\r
+                               if (dropConstraintName != null) {\r
+\r
+                                       String dropSchemaName = cdn.getDropSchemaName();\r
+\r
+                                       SchemaDescriptor sd = dropSchemaName == null ? td.getSchemaDescriptor() :\r
+                                                                                       getSchemaDescriptor(dropSchemaName);\r
+\r
+                                       ConstraintDescriptor cd =\r
+                                                               dd.getConstraintDescriptorByName(\r
+                                                                               td, sd, dropConstraintName,\r
+                                                                               false);\r
+                                       if (cd == null)\r
+                                       {\r
+                                               throw StandardException.newException(SQLState.LANG_DROP_NON_EXISTENT_CONSTRAINT,\r
+                                                               (sd.getSchemaName() + "."+ dropConstraintName),\r
+                                                               td.getQualifiedName());\r
+                                       }\r
+                                       /* Statement is dependendent on the ConstraintDescriptor */\r
+                                       getCompilerContext().createDependency(cd);\r
+                               }\r
+                       }\r
+\r
+            if (cdn.hasPrimaryKeyConstraint())\r
+            {\r
+                // for PRIMARY KEY, check that columns are unique\r
+                verifyUniqueColumnList(ddlStmt, cdn);\r
+\r
+                if (td == null)\r
+                {\r
+                    // in CREATE TABLE so set PRIMARY KEY columns to NOT NULL\r
+                    setColumnListToNotNull(cdn);\r
+                }\r
+                else\r
+                {\r
+                    // in ALTER TABLE so raise error if any columns are nullable\r
+                    checkForNullColumns(cdn, td);\r
+                }\r
+            }\r
+            else if (cdn.hasUniqueKeyConstraint())\r
+            {\r
+                // for UNIQUE, check that columns are unique and NOT NULL\r
+                verifyUniqueColumnList(ddlStmt, cdn);\r
+                checkForNullColumns(cdn, td);\r
+            }\r
+            else if (cdn.hasForeignKeyConstraint())\r
+            {\r
+                // for FOREIGN KEY, check that columns are unique\r
+                verifyUniqueColumnList(ddlStmt, cdn);\r
+            }\r
+               }\r
+\r
+               /* Can have only one autoincrement column in DB2 mode */\r
+               if (numAutoCols > 1)\r
+                       throw StandardException.newException(SQLState.LANG_MULTIPLE_AUTOINCREMENT_COLUMNS);\r
+\r
+       }\r
+\r
+    /**\r
+        * Count the number of constraints of the specified type.\r
+        *\r
+        * @param constraintType        The constraint type to search for.\r
+        *\r
+        * @return int  The number of constraints of the specified type.\r
+        */\r
+       public int countConstraints(int constraintType)\r
+       {\r
+               int     numConstraints = 0;\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ConstraintDefinitionNode cdn;\r
+                       TableElementNode element = (TableElementNode) elementAt(index);\r
+\r
+                       if (! (element instanceof ConstraintDefinitionNode))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       cdn = (ConstraintDefinitionNode) element;\r
+\r
+                       if (constraintType == cdn.getConstraintType())\r
+                       {\r
+                               numConstraints++;\r
+                       }\r
+               }\r
+\r
+               return numConstraints;\r
+       }\r
+\r
+       /**\r
+        * Count the number of columns.\r
+        *\r
+        * @return int  The number of columns.\r
+        */\r
+       public int countNumberOfColumns()\r
+       {\r
+               return numColumns;\r
+       }\r
+\r
+       /**\r
+        * Fill in the ColumnInfo[] for this table element list.\r
+        * \r
+        * @param colInfos      The ColumnInfo[] to be filled in.\r
+        *\r
+        * @return int          The number of constraints in the create table.\r
+        */\r
+       public int genColumnInfos(ColumnInfo[] colInfos)\r
+       {\r
+               int     numConstraints = 0;\r
+               int size = size();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       if (((TableElementNode) elementAt(index)).getElementType() == TableElementNode.AT_DROP_COLUMN)\r
+                       {\r
+                               colInfos[index] = new ColumnInfo(\r
+                                                               ((TableElementNode) elementAt(index)).getName(),\r
+                                                               null, null, null, null, null,\r
+                                                               ColumnInfo.DROP, 0, 0, 0);\r
+                               break;\r
+                       }\r
+\r
+                       if (! (elementAt(index) instanceof ColumnDefinitionNode))\r
+                       {\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       SanityManager.ASSERT( elementAt(index) instanceof ConstraintDefinitionNode,\r
+                                               "elementAt(index) expected to be instanceof " +\r
+                                               "ConstraintDefinitionNode");\r
+                               }\r
+\r
+                               /* Remember how many constraints that we've seen */\r
+                               numConstraints++;\r
+                               continue;\r
+                       }\r
+\r
+                       ColumnDefinitionNode coldef = (ColumnDefinitionNode) elementAt(index);\r
+\r
+                       colInfos[index - numConstraints] = \r
+                               new ColumnInfo(coldef.getColumnName(),\r
+                                                          coldef.getDataTypeServices(),\r
+                                                          coldef.getDefaultValue(),\r
+                                                          coldef.getDefaultInfo(),\r
+                                                          (UUID) null,\r
+                                                          coldef.getOldDefaultUUID(),\r
+                                                          coldef.getAction(),\r
+                                                          (coldef.isAutoincrementColumn() ? \r
+                                                               coldef.getAutoincrementStart() : 0),\r
+                                                          (coldef.isAutoincrementColumn() ? \r
+                                                               coldef.getAutoincrementIncrement() : 0),\r
+                                                          (coldef.isAutoincrementColumn() ? \r
+                                                               coldef.getAutoinc_create_or_modify_Start_Increment() : -1));\r
+\r
+                       /* Remember how many constraints that we've seen */\r
+                       if (coldef.hasConstraint())\r
+                       {\r
+                               numConstraints++;\r
+                       }\r
+               }\r
+\r
+               return numConstraints;\r
+       }\r
+       /**\r
+        * Append goobered up ResultColumns to the table's RCL.\r
+        * This is useful for binding check constraints for CREATE and ALTER TABLE.\r
+        *\r
+        * @param table         The table in question.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void appendNewColumnsToRCL(FromBaseTable table)\r
+               throws StandardException\r
+       {\r
+               int                              size = size();\r
+               ResultColumnList rcl = table.getResultColumns();\r
+               TableName                exposedName = table.getTableName();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       if (elementAt(index) instanceof ColumnDefinitionNode)\r
+                       {\r
+                               ColumnDefinitionNode cdn = (ColumnDefinitionNode) elementAt(index);\r
+                               ResultColumn    resultColumn;\r
+                               ValueNode               valueNode;\r
+\r
+                               /* Build a ResultColumn/BaseColumnNode pair for the column */\r
+                               valueNode = (ValueNode) getNodeFactory().getNode(\r
+                                                                                       C_NodeTypes.BASE_COLUMN_NODE,\r
+                                                                                       cdn.getColumnName(),\r
+                                                                                       exposedName,\r
+                                                                                       cdn.getDataTypeServices(),\r
+                                                                                       getContextManager());\r
+\r
+                               resultColumn = (ResultColumn) getNodeFactory().getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN,\r
+                                                                                               cdn.getDataTypeServices(), \r
+                                                                                               valueNode,\r
+                                                                                               getContextManager());\r
+                               resultColumn.setName(cdn.getColumnName());\r
+                               rcl.addElement(resultColumn);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Bind and validate all of the check constraints in this list against\r
+        * the specified FromList.  \r
+        *\r
+        * @param fromList              The FromList in question.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       void bindAndValidateCheckConstraints(FromList fromList)\r
+               throws StandardException\r
+       {\r
+               CompilerContext cc;\r
+               FromBaseTable                           table = (FromBaseTable) fromList.elementAt(0);\r
+               int                                               size = size();\r
+\r
+               cc = getCompilerContext();\r
+\r
+               Vector aggregateVector = new Vector();\r
+\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       ConstraintDefinitionNode cdn;\r
+                       TableElementNode element = (TableElementNode) elementAt(index);\r
+                       ValueNode       checkTree;\r
+\r
+                       if (! (element instanceof ConstraintDefinitionNode))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       cdn = (ConstraintDefinitionNode) element;\r
+\r
+                       if (cdn.getConstraintType() != DataDictionary.CHECK_CONSTRAINT)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       checkTree = cdn.getCheckCondition();\r
+\r
+                       // bind the check condition\r
+                       // verify that it evaluates to a boolean\r
+                       final int previousReliability = cc.getReliability();\r
+                       try\r
+                       {\r
+                               /* Each check constraint can have its own set of dependencies.\r
+                                * These dependencies need to be shared with the prepared\r
+                                * statement as well.  We create a new auxiliary provider list\r
+                                * for the check constraint, "push" it on the compiler context\r
+                                * by swapping it with the current auxiliary provider list\r
+                                * and the "pop" it when we're done by restoring the old \r
+                                * auxiliary provider list.\r
+                                */\r
+                               ProviderList apl = new ProviderList();\r
+\r
+                               ProviderList prevAPL = cc.getCurrentAuxiliaryProviderList();\r
+                               cc.setCurrentAuxiliaryProviderList(apl);\r
+\r
+                               // Tell the compiler context to only allow deterministic nodes\r
+                               cc.setReliability( CompilerContext.CHECK_CONSTRAINT );\r
+                               checkTree = checkTree.bindExpression(fromList, (SubqueryList) null,\r
+                                                                                aggregateVector);\r
+\r
+                               // no aggregates, please\r
+                               if (aggregateVector.size() != 0)\r
+                               {\r
+                                       throw StandardException.newException(SQLState.LANG_INVALID_CHECK_CONSTRAINT, cdn.getConstraintText());\r
+                               }\r
+                               \r
+                               checkTree = checkTree.checkIsBoolean();\r
+                               cdn.setCheckCondition(checkTree);\r
+\r
+                               /* Save the APL off in the constraint node */\r
+                               if (apl.size() > 0)\r
+                               {\r
+                                       cdn.setAuxiliaryProviderList(apl);\r
+                               }\r
+\r
+                               // Restore the previous AuxiliaryProviderList\r
+                               cc.setCurrentAuxiliaryProviderList(prevAPL);\r
+                       }\r
+                       finally\r
+                       {\r
+                               cc.setReliability(previousReliability);\r
+                       }\r
+       \r
+                       /* We have a valid check constraint, now build an array of\r
+                        * 1-based columnIds that the constraint references.\r
+                        */\r
+                       ResultColumnList rcl = table.getResultColumns();\r
+                       int             numReferenced = rcl.countReferencedColumns();\r
+                       int[]   checkColumnReferences = new int[numReferenced];\r
+\r
+                       rcl.recordColumnReferences(checkColumnReferences, 1);\r
+                       cdn.setCheckColumnReferences(checkColumnReferences);\r
+\r
+                       /* Now we build a list with only the referenced columns and\r
+                        * copy it to the cdn.  Thus we can build the array of\r
+                        * column names for the referenced columns during generate().\r
+                        */\r
+                       ResultColumnList refRCL =\r
+                                               (ResultColumnList) getNodeFactory().getNode(\r
+                                                                                               C_NodeTypes.RESULT_COLUMN_LIST,\r
+                                                                                               getContextManager());\r
+                       rcl.copyReferencedColumnsToNewList(refRCL);\r
+\r
+                       /* A column check constraint can only refer to that column. If this is a\r
+                        * column constraint, we should have an RCL with that column\r
+                        */\r
+                       if (cdn.getColumnList() != null)\r
+                       {\r
+                               String colName = ((ResultColumn)(cdn.getColumnList().elementAt(0))).getName();\r
+                               if (numReferenced > 1 ||\r
+                                       !colName.equals(((ResultColumn)(refRCL.elementAt(0))).getName()))\r
+                                       throw StandardException.newException(SQLState.LANG_DB2_INVALID_CHECK_CONSTRAINT, colName);\r
+                               \r
+                       }\r
+                       cdn.setColumnList(refRCL);\r
+\r
+                       /* Clear the column references in the RCL so each check constraint\r
+                        * starts with a clean list.\r
+                        */\r
+                       rcl.clearColumnReferences();\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Fill in the ConstraintConstantAction[] for this create/alter table.\r
+        * \r
+        * @param conActions    The ConstraintConstantAction[] to be filled in.\r
+        * @param tableName             The name of the Table being created.\r
+        * @param tableSd               The schema for that table.\r
+        * @param dd            The DataDictionary\r
+        *\r
+        * @exception StandardException         Thrown on failure\r
+        */\r
+       void genConstraintActions(\r
+                               ConstraintConstantAction[] conActions,\r
+                               String tableName,\r
+                               SchemaDescriptor tableSd,\r
+                               DataDictionary dd)\r
+               throws StandardException\r
+       {\r
+               int size = size();\r
+               int conActionIndex = 0;\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       String[]        columnNames = null;\r
+                       TableElementNode ten = (TableElementNode) elementAt(index);\r
+                       IndexConstantAction indexAction = null;\r
+\r
+                       if (! ten.hasConstraint())\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       if (ten instanceof ColumnDefinitionNode)\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       ConstraintDefinitionNode constraintDN = (ConstraintDefinitionNode) ten;\r
+\r
+                       if (constraintDN.getColumnList() != null)\r
+                       {\r
+                               columnNames = new String[constraintDN.getColumnList().size()];\r
+                               constraintDN.getColumnList().exportNames(columnNames);\r
+                       }\r
+\r
+                       int constraintType = constraintDN.getConstraintType();\r
+                       String constraintText = constraintDN.getConstraintText();\r
+\r
+                       /*\r
+                       ** If the constraint is not named (e.g.\r
+                       ** create table x (x int primary key)), then\r
+                       ** the constraintSd is the same as the table.\r
+                       */\r
+                       String constraintName = constraintDN.getConstraintMoniker();\r
+\r
+                       /* At execution time, we will generate a unique name for the backing\r
+                        * index (for CREATE CONSTRAINT) and we will look up the conglomerate\r
+                        * name (for DROP CONSTRAINT).\r
+                        */\r
+                       if (constraintDN.requiresBackingIndex())\r
+                       {\r
+                               indexAction = genIndexAction(constraintDN.requiresUniqueIndex(),\r
+                                                                                        null, constraintDN, \r
+                                                                                        columnNames, true, tableSd, tableName,\r
+                                                                                        constraintType, dd);\r
+                       }\r
+\r
+                       if (constraintType == DataDictionary.DROP_CONSTRAINT)\r
+                       {\r
+                               conActions[conActionIndex] = \r
+                                       getGenericConstantActionFactory().\r
+                                               getDropConstraintConstantAction(\r
+                                                                                                constraintName, \r
+                                                                                                constraintDN.getDropSchemaName(), /// FiX\r
+                                                                                                tableName,\r
+                                                                                                td.getUUID(),\r
+                                                                                                tableSd.getSchemaName(),\r
+                                                                                                indexAction,\r
+                                                                                                constraintDN.getDropBehavior(),\r
+                                                 constraintDN.getVerifyType());\r
+                       }\r
+                       else\r
+                       {\r
+                               ProviderList apl = constraintDN.getAuxiliaryProviderList();\r
+                               ConstraintInfo refInfo = null;\r
+                               ProviderInfo[]  providerInfos = null;\r
+\r
+                               if (constraintDN instanceof FKConstraintDefinitionNode)\r
+                               {\r
+                                       refInfo = ((FKConstraintDefinitionNode)constraintDN).getReferencedConstraintInfo();\r
+                               }                               \r
+\r
+                               /* Create the ProviderInfos, if the constraint is dependent on any Providers */\r
+                               if (apl != null && apl.size() > 0)\r
+                               {\r
+                                       /* Get all the dependencies for the current statement and transfer\r
+                                        * them to this view.\r
+                                        */\r
+                                       DependencyManager dm = dd.getDependencyManager();\r
+                                       providerInfos = dm.getPersistentProviderInfos(apl);\r
+                               }\r
+                               else\r
+                               {\r
+                                       providerInfos = new ProviderInfo[0];\r
+                                       // System.out.println("TABLE ELEMENT LIST EMPTY");\r
+                               }\r
+\r
+                               conActions[conActionIndex++] = \r
+                                       getGenericConstantActionFactory().\r
+                                               getCreateConstraintConstantAction(\r
+                                                                                                constraintName, \r
+                                                                                            constraintType,\r
+                                                                                                tableName,\r
+                                                                                                ((td != null) ? td.getUUID() : (UUID) null),\r
+                                                                                                tableSd.getSchemaName(),\r
+                                                                                                columnNames,\r
+                                                                                                indexAction,\r
+                                                                                                constraintText,\r
+                                                                                                true,          // enabled\r
+                                                                                                refInfo,\r
+                                                                                                providerInfos);\r
+                       }\r
+               }\r
+       }\r
+\r
+      //check if one array is same as another \r
+       private boolean columnsMatch(String[] columnNames1, String[] columnNames2)\r
+       {\r
+               int srcCount, srcSize, destCount,destSize;\r
+               boolean match = true;\r
+\r
+               if (columnNames1.length != columnNames2.length)\r
+                       return false;\r
+\r
+               srcSize = columnNames1.length;\r
+               destSize = columnNames2.length;\r
+\r
+               for (srcCount = 0; srcCount < srcSize; srcCount++)\r
+               {\r
+                       match = false;\r
+                       for (destCount = 0; destCount < destSize; destCount++) {\r
+                               if (columnNames1[srcCount].equals(columnNames2[destCount])) {\r
+                                       match = true;\r
+                                       break;\r
+                               }\r
+                       }\r
+                       if (match == false)\r
+                               return false;\r
+               }\r
+\r
+               return true;\r
+       }\r
+\r
+       private IndexConstantAction genIndexAction(\r
+                                                                               boolean isUnique,\r
+                                                                               String indexName,\r
+                                                                               ConstraintDefinitionNode cdn,\r
+                                                                               String[] columnNames,\r
+                                                                               boolean isConstraint,\r
+                                                                               SchemaDescriptor sd,\r
+                                                                               String tableName,\r
+                                                                               int constraintType,\r
+                                                                               DataDictionary dd)\r
+               throws StandardException\r
+       {\r
+               if ( indexName == null ) { indexName = cdn.getBackingIndexName(dd); }\r
+\r
+               if (constraintType == DataDictionary.DROP_CONSTRAINT)\r
+               {\r
+                       return  getGenericConstantActionFactory().getDropIndexConstantAction(\r
+                                                                         null,\r
+                                                                         indexName,\r
+                                                                         tableName,\r
+                                                                         sd.getSchemaName(),\r
+                                                                         td.getUUID(),\r
+                                                                         td.getHeapConglomerateId());\r
+               }\r
+               else\r
+               {\r
+                       boolean[]       isAscending = new boolean[columnNames.length];\r
+                       for (int i = 0; i < isAscending.length; i++)\r
+                               isAscending[i] = true;\r
+                       return  getGenericConstantActionFactory().getCreateIndexConstantAction(\r
+                                                                       isUnique,\r
+                                                                       "BTREE", // indexType\r
+                                                                       sd.getSchemaName(),\r
+                                                                       indexName,\r
+                                                                       tableName,\r
+                                                                       ((td != null) ? td.getUUID() : (UUID) null),\r
+                                                                       columnNames,\r
+                                                                       isAscending,\r
+                                                                       isConstraint,\r
+                                                                       cdn.getBackingIndexUUID(),\r
+                                                                       cdn.getProperties());\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check to make sure that there are no duplicate column names\r
+        * in the list.  (The comparison here is case sensitive.\r
+        * The work of converting column names that are not quoted\r
+        * identifiers to upper case is handled by the parser.)\r
+        * RESOLVE: This check will also be performed by alter table.\r
+        *\r
+        * @param ddlStmt       DDLStatementNode which contains this list\r
+        * @param ht            Hashtable for enforcing uniqueness.\r
+        * @param colName       Column name to check for.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       private void checkForDuplicateColumns(DDLStatementNode ddlStmt,\r
+                                                                       Hashtable ht,\r
+                                                                       String colName)\r
+                       throws StandardException\r
+       {\r
+               Object object = ht.put(colName, colName);\r
+               if (object != null)\r
+               {\r
+                       /* RESOLVE - different error messages for create and alter table */\r
+                       if (ddlStmt instanceof CreateTableNode)\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE, colName);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Check to make sure that there are no duplicate constraint names\r
+        * in the list.  (The comparison here is case sensitive.\r
+        * The work of converting column names that are not quoted\r
+        * identifiers to upper case is handled by the parser.)\r
+        * RESOLVE: This check will also be performed by alter table.\r
+        *\r
+        * @param ddlStmt       DDLStatementNode which contains this list\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       private void checkForDuplicateConstraintNames(DDLStatementNode ddlStmt,\r
+                                                                       Hashtable ht,\r
+                                                                       String constraintName)\r
+                       throws StandardException\r
+       {\r
+               if (constraintName == null)\r
+                       return;\r
+\r
+               Object object = ht.put(constraintName, constraintName);\r
+               if (object != null) {\r
+\r
+                       /* RESOLVE - different error messages for create and alter table */\r
+                       if (ddlStmt instanceof CreateTableNode)\r
+                       {\r
+                               /* RESOLVE - new error message */\r
+                               throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_NAME_CREATE, \r
+                                               constraintName);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Verify that a primary/unique table constraint has a valid column list.\r
+        * (All columns in table and no duplicates.)\r
+        *\r
+        * @param ddlStmt       The outer DDLStatementNode\r
+        * @param cdn           The ConstraintDefinitionNode\r
+        *\r
+        * @exception   StandardException       Thrown if the column list is invalid\r
+        */\r
+       private void verifyUniqueColumnList(DDLStatementNode ddlStmt,\r
+                                                               ConstraintDefinitionNode cdn)\r
+               throws StandardException\r
+       {\r
+               String invalidColName;\r
+\r
+               /* Verify that every column in the list appears in the table's list of columns */\r
+               if (ddlStmt instanceof CreateTableNode)\r
+               {\r
+                       invalidColName = cdn.getColumnList().verifyCreateConstraintColumnList(this);\r
+                       if (invalidColName != null)\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_INVALID_CREATE_CONSTRAINT_COLUMN_LIST, \r
+                                                               ddlStmt.getRelativeName(),\r
+                                                               invalidColName);\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       /* RESOLVE - alter table will need to get table descriptor */\r
+               }\r
+\r
+               /* Check the uniqueness of the column names within the list */\r
+               invalidColName = cdn.getColumnList().verifyUniqueNames(false);\r
+               if (invalidColName != null)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_DUPLICATE_CONSTRAINT_COLUMN_NAME, invalidColName);\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Set all columns in that appear in a PRIMARY KEY constraint in a CREATE TABLE statement to NOT NULL.\r
+        *\r
+        * @param cdn           The ConstraintDefinitionNode for a PRIMARY KEY constraint\r
+        */\r
+       private void setColumnListToNotNull(ConstraintDefinitionNode cdn)\r
+       {\r
+               ResultColumnList rcl = cdn.getColumnList();\r
+               int rclSize = rcl.size();\r
+               for (int index = 0; index < rclSize; index++)\r
+               {\r
+                       String colName = ((ResultColumn) rcl.elementAt(index)).getName();\r
+            DataTypeDescriptor dtd = getColumnDataTypeDescriptor(colName);\r
+            dtd.setNullability(false);\r
+        }\r
+       }\r
+\r
+\r
+    private void checkForNullColumns(ConstraintDefinitionNode cdn, TableDescriptor td) throws StandardException\r
+    {\r
+        ResultColumnList rcl = cdn.getColumnList();\r
+        int rclSize = rcl.size();\r
+        for (int index = 0; index < rclSize; index++)\r
+        {\r
+            String colName = ((ResultColumn) rcl.elementAt(index)).getName();\r
+            DataTypeDescriptor dtd;\r
+            if (td == null)\r
+            {\r
+                dtd = getColumnDataTypeDescriptor(colName);\r
+            }\r
+            else\r
+            {\r
+                dtd = getColumnDataTypeDescriptor(colName, td);\r
+            }\r
+            // todo dtd may be null if the column does not exist, we should check that first\r
+            if (dtd != null && dtd.isNullable())\r
+            {\r
+                throw StandardException.newException(SQLState.LANG_DB2_ADD_UNIQUE_OR_PRIMARY_KEY_ON_NULL_COLS, colName);\r
+            }\r
+        }\r
+    }\r
+\r
+    private DataTypeDescriptor getColumnDataTypeDescriptor(String colName)\r
+    {\r
+        int size = size();\r
+\r
+        for (int index = 0; index < size; index++)\r
+        {\r
+            TableElementNode tableElement = (TableElementNode) elementAt(index);\r
+\r
+            if (tableElement instanceof ColumnDefinitionNode)\r
+            {\r
+                ColumnDefinitionNode cdn = (ColumnDefinitionNode) tableElement;\r
+                if (colName.equals(cdn.getColumnName()))\r
+                {\r
+                    return cdn.getDataTypeServices();\r
+                }\r
+            }\r
+        }\r
+        return null;\r
+    }\r
+\r
+    private DataTypeDescriptor getColumnDataTypeDescriptor(String colName, TableDescriptor td)\r
+    {\r
+        // check existing columns\r
+        ColumnDescriptor cd = td.getColumnDescriptor(colName);\r
+        if (cd != null)\r
+        {\r
+            return cd.getType();\r
+        }\r
+        // check for new columns\r
+        return getColumnDataTypeDescriptor(colName);\r
+    }\r
+\r
+       /**\r
+        * Determine whether or not the parameter matches a column name in this list.\r
+        *\r
+        * @param colName       The column name to search for.\r
+        *\r
+        * @return boolean  Whether or not a match is found.\r
+        */\r
+       public boolean containsColumnName(String colName)\r
+       {\r
+               int size = size();\r
+               for (int index = 0; index < size; index++)\r
+               {\r
+                       TableElementNode tableElement = (TableElementNode) elementAt(index);\r
+\r
+                       if (tableElement instanceof ColumnDefinitionNode)\r
+                       {\r
+                               if (colName.equals(((ColumnDefinitionNode) tableElement).getName()))\r
+                               {\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       }\r
+}\r
+\r