Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / iapi / sql / dictionary / ReferencedKeyConstraintDescriptor.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/sql/dictionary/ReferencedKeyConstraintDescriptor.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/iapi/sql/dictionary/ReferencedKeyConstraintDescriptor.java
new file mode 100644 (file)
index 0000000..2c75ff2
--- /dev/null
@@ -0,0 +1,355 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor\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.iapi.sql.dictionary;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.StatementType;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.catalog.UUID;\r
+/**\r
+ * A ReferencedConstraintDeescriptor is a primary key or a unique\r
+ * key that is referenced by a foreign key.\r
+ *\r
+ */\r
+public class ReferencedKeyConstraintDescriptor extends KeyConstraintDescriptor\r
+{\r
+       /**\r
+          public interface to this descriptor:\r
+          <ol>\r
+          <li>public boolean hasSelfReferencingFK(ConstraintDescriptorList cdl, int type) \r
+               throws StandardException;</li>\r
+               <li>public ConstraintDescriptorList getForeignKeyConstraints(int type) throws StandardException;</li>\r
+               <li>public boolean isReferenced();</li>\r
+               <li>public int getReferenceCount();</li>\r
+               <li>public int incrementReferenceCount();</li>\r
+               <li>public int decrementReferenceCount();</li>\r
+               </ol>\r
+       */\r
+\r
+       //Implementation\r
+       private final int constraintType;\r
+\r
+       int                     referenceCount;\r
+\r
+       // enabled foreign keys\r
+       private ConstraintDescriptorList fkEnabledConstraintList;\r
+       // all foreign keys\r
+       private ConstraintDescriptorList fkConstraintList;\r
+\r
+       private boolean checkedSelfReferencing;\r
+       private boolean hasSelfReferencing;\r
+\r
+       /**\r
+        * Constructor for a KeyConstraintDescriptorImpl\r
+        *\r
+        * @param constraintType        The type of the constraint\r
+        * @param dataDictionary                The data dictionary that this descriptor lives in\r
+        * @param table         The descriptor of the table the constraint is on\r
+        * @param constraintName        The name of the constraint.\r
+        * @param deferrable            If the constraint can be deferred.\r
+        * @param initiallyDeferred If the constraint starts life deferred.\r
+        * @param columns                       columns involved in the constraint\r
+        * @param constraintId          UUID of constraint\r
+        * @param indexId                       The UUID for the backing index\r
+        * @param schemaDesc            The SchemaDescriptor for the constraint\r
+        * @param isEnabled                     is the constraint enabled?\r
+        * @param referenceCount        number of FKs (enabled only)\r
+        */\r
+       protected ReferencedKeyConstraintDescriptor(int constraintType,\r
+                   DataDictionary dataDictionary,\r
+                       TableDescriptor table,\r
+                       String constraintName,\r
+                       boolean deferrable,\r
+                       boolean initiallyDeferred,\r
+                       int[] columns,\r
+                       UUID constraintId,\r
+                       UUID indexId,\r
+                       SchemaDescriptor schemaDesc,\r
+                       boolean isEnabled,\r
+                       int referenceCount\r
+                       )                                                       \r
+       {\r
+               super(dataDictionary, table, constraintName, deferrable,\r
+                         initiallyDeferred, columns, \r
+                         constraintId, indexId, schemaDesc, isEnabled);\r
+               this.referenceCount = referenceCount;\r
+               this.constraintType = constraintType;\r
+       }\r
+\r
+       public final int getConstraintType() {\r
+               return constraintType;\r
+       }\r
+\r
+       /**\r
+        * Am I referenced by a FK on the same table?\r
+        *\r
+        * @param cdl   ConstraintDescriptorList for the table\r
+        * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)\r
+        *\r
+        * @return      true/false\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public boolean hasSelfReferencingFK(ConstraintDescriptorList cdl, int type) \r
+               throws StandardException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       checkType(type);\r
+               }\r
+       \r
+               if (checkedSelfReferencing)\r
+               {\r
+                       return hasSelfReferencing;\r
+               }\r
+       \r
+               ConstraintDescriptor cd;\r
+               ForeignKeyConstraintDescriptor fkcd;\r
+               /* Get a full list of referencing keys, if caller\r
+                * passed in null CDL.\r
+                */\r
+               if (cdl == null)\r
+               {\r
+                       cdl = getForeignKeyConstraints(type);\r
+               }\r
+               int cdlSize = cdl.size();\r
+\r
+               for (int index = 0; index < cdlSize; index++)\r
+               {\r
+                       cd = (ConstraintDescriptor) cdl.elementAt(index);\r
+                       if (! (cd instanceof ForeignKeyConstraintDescriptor))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       fkcd = (ForeignKeyConstraintDescriptor) cd;\r
+                       if (fkcd.getReferencedConstraintId().equals(getUUID()))\r
+                       {\r
+                               hasSelfReferencing = true;\r
+                               break;\r
+                       }\r
+               }\r
+               return hasSelfReferencing;\r
+       }\r
+\r
+\r
+       /**\r
+        * Am I referenced by a FK on another table?\r
+        * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)\r
+        * @return      true/false\r
+        * @exception StandardException on error\r
+        */\r
+       public boolean hasNonSelfReferencingFK(int type) \r
+               throws StandardException\r
+       {\r
+\r
+               boolean hasNonSelfReferenceFk = false;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       checkType(type);\r
+               }\r
+       \r
+               ConstraintDescriptor cd;\r
+               ForeignKeyConstraintDescriptor fkcd;\r
+               // Get a full list of referencing keys,\r
+               ConstraintDescriptorList cdl = getForeignKeyConstraints(type);\r
+               int cdlSize = cdl.size();\r
+\r
+               for (int index = 0; index < cdlSize; index++)\r
+               {\r
+                       cd = (ConstraintDescriptor) cdl.elementAt(index);\r
+                       if (! (cd instanceof ForeignKeyConstraintDescriptor))\r
+                       {\r
+                               continue;\r
+                       }\r
+\r
+                       fkcd = (ForeignKeyConstraintDescriptor) cd;\r
+                       if(!(fkcd.getTableId().equals(getTableId())))\r
+                       {\r
+                               hasNonSelfReferenceFk = true;\r
+                               break;\r
+                       }\r
+               }\r
+               return hasNonSelfReferenceFk;\r
+       }\r
+\r
+\r
+\r
+       /**\r
+        * Get the referencing foreign key constraints\r
+        *\r
+        * @param type ConstraintDescriptor.(ENABLED|DISABLED|ALL)\r
+        *\r
+        * @return      the list of constraints (ConstraintDescriptorListImpl)\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public ConstraintDescriptorList getForeignKeyConstraints(int type)\r
+               throws StandardException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       checkType(type);\r
+               }\r
+\r
+               // optimized for this case\r
+               if (type == ENABLED)\r
+               {\r
+                       // optimization to avoid any lookups if we know we\r
+                       // aren't referenced.\r
+                       if (!isReferenced())\r
+                       {\r
+                               return new ConstraintDescriptorList();\r
+                       }\r
+                       else if (fkEnabledConstraintList != null)\r
+                       {\r
+                               return fkEnabledConstraintList;\r
+                       }\r
+                       else if (fkConstraintList == null)\r
+                       {\r
+                               fkConstraintList = getDataDictionary().getForeignKeys(constraintId);\r
+                       }\r
+                       fkEnabledConstraintList = fkConstraintList.getConstraintDescriptorList(true);\r
+                       return fkEnabledConstraintList;\r
+               }\r
+\r
+               // not optimized for this case\r
+               else if (type == DISABLED)\r
+               {\r
+                       if (fkConstraintList == null)\r
+                       {\r
+                               fkConstraintList = getDataDictionary().getForeignKeys(constraintId);\r
+                       }\r
+                       return fkConstraintList.getConstraintDescriptorList(false);\r
+               }\r
+               else\r
+               {\r
+                       if (fkConstraintList == null)\r
+                       {\r
+                               fkConstraintList = getDataDictionary().getForeignKeys(constraintId);\r
+                       }\r
+                       return fkConstraintList;\r
+               }\r
+       }\r
+               \r
+       /**\r
+        * Is this constraint referenced? Returns\r
+        * true if there are enabled fks that \r
+        * reference this constraint.\r
+        *\r
+        * @return false\r
+        */\r
+       public boolean isReferenced()\r
+       {\r
+               return referenceCount != 0;\r
+       }\r
+\r
+       /**\r
+        * Get the number of enabled fks that\r
+        * reference this key.\r
+        *\r
+        * @return the number of fks\r
+        */\r
+       public int getReferenceCount()\r
+       {\r
+               return referenceCount;\r
+       }\r
+\r
+       /**\r
+        * Bump the reference count by one.\r
+        *\r
+        * @return the number of fks\r
+        */\r
+       public int incrementReferenceCount()\r
+       {\r
+               return referenceCount++;\r
+       }\r
+\r
+       /**\r
+        * Decrement the reference count by one.\r
+        *\r
+        * @return the number of fks\r
+        */\r
+       public int decrementReferenceCount()\r
+       {\r
+               return referenceCount--;\r
+       }\r
+\r
+       /**\r
+        * Does this constraint need to fire on this type of\r
+        * DML?  For referenced keys, fire if referenced by\r
+        * a fk, and stmt is delete or bulk insert replace, \r
+        * or stmt is update and columns intersect.\r
+        *\r
+        * @param stmtType      the type of DML \r
+        * (StatementType.INSERT|StatementType.UPDATE|StatementType.DELETE)\r
+        * @param modifiedCols  the columns modified, or null for all\r
+        *\r
+        * @return true/false\r
+        */\r
+       public boolean needsToFire(int stmtType, int[] modifiedCols)\r
+       {\r
+               /*\r
+               ** If we are disabled, we never fire\r
+               */\r
+               if (!isEnabled)\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               if (!isReferenced() ||\r
+                       (stmtType == StatementType.INSERT))\r
+               {\r
+                       return false;\r
+               }\r
+\r
+               if (stmtType == StatementType.DELETE ||\r
+                       stmtType == StatementType.BULK_INSERT_REPLACE)\r
+               {\r
+                       return true;\r
+               }\r
+\r
+               // if update, only relevant if columns intersect\r
+               return doColumnsIntersect(modifiedCols, getReferencedColumns());\r
+       }\r
+\r
+       private void checkType(int type) throws StandardException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       switch (type)\r
+                       {\r
+                         case ENABLED:\r
+                         case DISABLED:\r
+                         case ALL:\r
+                               break;\r
+                         default:\r
+                               SanityManager.THROWASSERT("constraint type "+type+" is invalid");\r
+                       }\r
+               }\r
+       }\r
+               \r
+}\r