Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / execute / FKInfo.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/FKInfo.java
new file mode 100644 (file)
index 0000000..2757a8c
--- /dev/null
@@ -0,0 +1,411 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.FKInfo\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.execute;\r
+\r
+import org.apache.derby.catalog.UUID;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;\r
+\r
+import org.apache.derby.iapi.types.RowLocation;\r
+\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.services.io.FormatIdUtil;\r
+import org.apache.derby.iapi.services.io.ArrayUtil;\r
+import org.apache.derby.iapi.services.io.Formatable;\r
+\r
+import java.io.StreamCorruptedException;\r
+import java.io.ObjectOutput;\r
+import java.io.ObjectInput;\r
+import java.io.IOException;\r
+\r
+import java.util.Vector;\r
+\r
+/**\r
+ * This is a simple class used to store the run time information\r
+ * about a foreign key.  Used by DML to figure out what to\r
+ * check.\r
+ *\r
+ */\r
+public class FKInfo implements Formatable \r
+{\r
+       /********************************************************\r
+       **\r
+       **      This class implements Formatable. That means that it\r
+       **      can write itself to and from a formatted stream. If\r
+       **      you add more fields to this class, make sure that you\r
+       **      also write/read them with the writeExternal()/readExternal()\r
+       **      methods.\r
+       **\r
+       **      If, inbetween releases, you add more fields to this class,\r
+       **      then you should bump the version number emitted by the getTypeFormatId()\r
+       **      method.  OR, since this is something that is used\r
+       **      in stored prepared statements, it is ok to change it\r
+       **      if you make sure that stored prepared statements are\r
+       **      invalidated across releases.\r
+       **\r
+       ********************************************************/\r
+\r
+       public static final int FOREIGN_KEY = 1;\r
+       public static final int REFERENCED_KEY = 2;\r
+\r
+       /*\r
+       ** See the constructor for the meaning of these fields\r
+       */\r
+       public String                           fkConstraintNames[];\r
+       public String                           tableName;\r
+       public int                                      type;\r
+       public UUID                                     refUUID;\r
+       public long                                     refConglomNumber;\r
+       public UUID[]                           fkUUIDs;\r
+       public long[]                           fkConglomNumbers;\r
+       public boolean[]                        fkIsSelfReferencing;\r
+       public int[]                            colArray;\r
+       public int                                      stmtType;\r
+       public RowLocation                      rowLocation;\r
+       public int[]                raRules;\r
+\r
+       /**\r
+        * Niladic constructor for Formattable\r
+        */\r
+       public FKInfo() {}\r
+\r
+       /**\r
+        * Consructor for FKInfo\r
+        *\r
+        * @param fkConstraintNames the foreign key constraint names\r
+        * @param tableName     the name of the table being modified\r
+        * @param stmtType      the type of the statement: e.g. StatementType.INSERT\r
+        * @param type either FKInfo.REFERENCED_KEY or FKInfo.FOREIGN_KEY\r
+        * @param refUUID UUID of the referenced constraint\r
+        * @param refConglomNumber congomerate number of the referenced key\r
+        * @param fkUUIDs an array of fkUUIDs of backing indexes.  if\r
+        *                      FOREIGN_KEY, then just one element, the backing\r
+        *                      index of the referrenced keys.  if REFERENCED_KEY,\r
+        *                      then all the foreign keys\r
+        * @param fkConglomNumbers array of conglomerate numbers, corresponds\r
+        *                      to fkUUIDs\r
+        * @param fkIsSelfReferencing array of conglomerate booleans indicating\r
+        *                      whether the fk references a key in the same table\r
+        * @param colArray map of columns to the base row that DML\r
+        *                      is changing.  1 based.  Note that this maps the\r
+        *                      constraint index to a row in the target table of\r
+        *                      the current dml operation.\r
+        * @param rowLocation a row location template for the target table\r
+        *                      used to pass in a template row to tc.openScan()\r
+        */\r
+       public FKInfo(\r
+                                       String[]                        fkConstraintNames,\r
+                                       String                          tableName,\r
+                                       int                                     stmtType,\r
+                                       int                                     type,\r
+                                       UUID                            refUUID,\r
+                                       long                            refConglomNumber,\r
+                                       UUID[]                          fkUUIDs,\r
+                                       long[]                          fkConglomNumbers,\r
+                                       boolean[]                       fkIsSelfReferencing,\r
+                                       int[]                           colArray,\r
+                                       RowLocation                     rowLocation,\r
+                                       int[]               raRules\r
+                                       )\r
+       {\r
+               this.fkConstraintNames = fkConstraintNames;\r
+               this.tableName = tableName;\r
+               this.stmtType = stmtType;\r
+               this.type = type;\r
+               this.refUUID = refUUID;\r
+               this.refConglomNumber = refConglomNumber;\r
+               this.fkUUIDs = fkUUIDs;\r
+               this.fkConglomNumbers = fkConglomNumbers;\r
+               this.fkIsSelfReferencing = fkIsSelfReferencing;\r
+               this.colArray = colArray;\r
+               this.rowLocation = rowLocation;\r
+               this.raRules = raRules;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (fkUUIDs.length != fkConglomNumbers.length)\r
+                       {\r
+                               SanityManager.THROWASSERT("number of ForeignKey UUIDS ("+fkUUIDs.length+\r
+                                                                               ") doesn't match the number of conglomerate numbers"+\r
+                                                                               " ("+fkConglomNumbers.length+")");\r
+                       }\r
+                       if (type == FOREIGN_KEY)\r
+                       {\r
+                               SanityManager.ASSERT(fkUUIDs.length == 1, "unexpected number of fkUUIDs for a foreign key, should only have the uuid of the key it references");\r
+                       }\r
+                       else if (type == REFERENCED_KEY)\r
+                       {\r
+                               SanityManager.ASSERT(fkUUIDs.length >= 1, "too few fkUUIDs for a referenced key, expect at least one foreign key");\r
+                       }\r
+                       else\r
+                       {\r
+                               SanityManager.THROWASSERT("bad type: "+type);\r
+                       }\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Comb through the FKInfo structures and pick out the\r
+        * ones that have columns that intersect with the input\r
+        * columns.\r
+        *\r
+        * @param fkInfo                array of fkinfos\r
+        * @param cols              array of columns\r
+        * @param addAllTypeIsFK        take all with type == FORIEGN_KEY\r
+        *\r
+        * @return array of relevant fkinfos\r
+        */\r
+       public static FKInfo[] chooseRelevantFKInfos\r
+       (       \r
+               FKInfo[]        fkInfo, \r
+               int[]           cols,\r
+               boolean         addAllTypeIsFK)\r
+       {\r
+               if (fkInfo == null)\r
+               {\r
+                       return (FKInfo[])null;\r
+               }\r
+\r
+               Vector newfksVector = new Vector();\r
+               FKInfo[] newfks = null;\r
+\r
+               /*\r
+               ** For each FKInfo\r
+               */\r
+               for (int i = 0; i < fkInfo.length; i++)\r
+               {\r
+                       if (addAllTypeIsFK && \r
+                               (fkInfo[i].type == FOREIGN_KEY))\r
+                       {\r
+                               newfksVector.addElement(fkInfo[i]);\r
+                               continue;\r
+                       }\r
+                               \r
+                       int fkcollen = fkInfo[i].colArray.length;\r
+                       for (int fkCols = 0; fkCols < fkcollen; fkCols++)\r
+                       {\r
+                               for (int chcol = 0; chcol < cols.length; chcol++)\r
+                               {\r
+                                       /*\r
+                                       ** If any column intersects, the FKInfo is\r
+                                       ** relevant.\r
+                                       */\r
+                                       if (fkInfo[i].colArray[fkCols] == cols[chcol])\r
+                                       {\r
+                                               newfksVector.addElement(fkInfo[i]);\r
+                                               \r
+                                               // go to the next fk\r
+                                               fkCols = fkcollen;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               \r
+               /*\r
+               ** Now convert the vector into an array.\r
+               */\r
+               int size = newfksVector.size();\r
+               if (size > 0)\r
+               {\r
+                       newfks = new FKInfo[size];\r
+                       for (int i = 0; i < size; i++)\r
+                       {\r
+                               newfks[i] = (FKInfo)newfksVector.elementAt(i);\r
+                       }\r
+               }\r
+               return newfks;\r
+       }\r
+               \r
+       //////////////////////////////////////////////\r
+       //\r
+       // FORMATABLE\r
+       //\r
+       //////////////////////////////////////////////\r
+       /**\r
+        * Write this object out\r
+        *\r
+        * @param out write bytes here\r
+        *\r
+        * @exception IOException thrown on error\r
+        */\r
+       public void writeExternal(ObjectOutput out) throws IOException\r
+       {\r
+               /*\r
+               ** Row locations cannot be written unless they\r
+               ** have a valid value.  So we'll just write out\r
+               ** the format id, and create a new RowLocation\r
+               ** when we read it back in.\r
+               */\r
+               FormatIdUtil.writeFormatIdInteger(out, rowLocation.getTypeFormatId());\r
+\r
+               out.writeObject(tableName);\r
+               out.writeInt(type);\r
+               out.writeInt(stmtType);\r
+               out.writeObject(refUUID);\r
+               out.writeLong(refConglomNumber);\r
+\r
+               ArrayUtil.writeArray(out, fkConstraintNames);\r
+               ArrayUtil.writeArray(out, fkUUIDs);\r
+               ArrayUtil.writeLongArray(out, fkConglomNumbers);\r
+               ArrayUtil.writeBooleanArray(out, fkIsSelfReferencing);\r
+               ArrayUtil.writeIntArray(out, colArray);\r
+               ArrayUtil.writeIntArray(out, raRules);\r
+               \r
+       }\r
+\r
+       /**\r
+        * Read this object from a stream of stored objects.\r
+        *\r
+        * @param in read this.\r
+        *\r
+        * @exception IOException                                       thrown on error\r
+        * @exception ClassNotFoundException            thrown on error\r
+        */\r
+       public void readExternal(ObjectInput in)\r
+               throws IOException, ClassNotFoundException\r
+       {\r
+               try\r
+               {\r
+                       /*\r
+                       ** Create a new RowLocation from the format id.\r
+                       */\r
+                       int formatid = FormatIdUtil.readFormatIdInteger(in);\r
+                       rowLocation = (RowLocation)Monitor.newInstanceFromIdentifier(formatid);\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               SanityManager.ASSERT(rowLocation != null, "row location is null in readExternal");\r
+                       }\r
+\r
+                       tableName = (String)in.readObject();\r
+                       type = in.readInt();\r
+                       stmtType = in.readInt();\r
+                       refUUID = (UUID)in.readObject();\r
+                       refConglomNumber = in.readLong();\r
+\r
+                       fkConstraintNames = new String[ArrayUtil.readArrayLength(in)];\r
+                       ArrayUtil.readArrayItems(in, fkConstraintNames);\r
+\r
+                       fkUUIDs = new UUID[ArrayUtil.readArrayLength(in)];\r
+                       ArrayUtil.readArrayItems(in, fkUUIDs);\r
+\r
+                       fkConglomNumbers = ArrayUtil.readLongArray(in);\r
+                       fkIsSelfReferencing = ArrayUtil.readBooleanArray(in);\r
+                       colArray = ArrayUtil.readIntArray(in);\r
+                       raRules = ArrayUtil.readIntArray(in);\r
+               }\r
+               catch (StandardException exception)\r
+               {\r
+                       throw new StreamCorruptedException(exception.toString());\r
+               }\r
+       }\r
+       \r
+       /**\r
+        * Get the formatID which corresponds to this class.\r
+        *\r
+        *      @return the formatID of this class\r
+        */\r
+       public  int     getTypeFormatId()       { return StoredFormatIds.FK_INFO_V01_ID; }\r
+\r
+       //////////////////////////////////////////////////////////////\r
+       //\r
+       // Misc\r
+       //\r
+       //////////////////////////////////////////////////////////////\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       StringBuffer str = new StringBuffer();\r
+                       str.append("\nTableName:\t\t\t");\r
+                       str.append(tableName);\r
+\r
+                       str.append("\ntype:\t\t\t\t");\r
+                       str.append((type == FOREIGN_KEY) ? "FOREIGN_KEY" : "REFERENCED_KEY");\r
+\r
+                       str.append("\nReferenced Key UUID:\t\t"+refUUID);\r
+                       str.append("\nReferenced Key ConglomNum:\t"+refConglomNumber);\r
+\r
+                       str.append("\nForeign Key Names:\t\t(");\r
+                       for (int i = 0; i < fkUUIDs.length; i++)\r
+                       {\r
+                               if (i > 0)\r
+                                       str.append(",");\r
+                       \r
+                               str.append(fkConstraintNames[i]);\r
+                       }\r
+                       str.append(")");\r
+\r
+                       str.append("\nForeign Key UUIDS:\t\t(");\r
+                       for (int i = 0; i < fkUUIDs.length; i++)\r
+                       {\r
+                               if (i > 0)\r
+                                       str.append(",");\r
+                       \r
+                               str.append(fkUUIDs[i]);\r
+                       }\r
+                       str.append(")");\r
+\r
+                       str.append("\nForeign Key Conglom Nums:\t(");\r
+                       for (int i = 0; i < fkConglomNumbers.length; i++)\r
+                       {\r
+                               if (i > 0)\r
+                                       str.append(",");\r
+                       \r
+                               str.append(fkConglomNumbers[i]);\r
+                       }\r
+                       str.append(")");\r
+               \r
+                       str.append("\nForeign Key isSelfRef:\t\t(");\r
+                       for (int i = 0; i < fkIsSelfReferencing.length; i++)\r
+                       {\r
+                               if (i > 0)\r
+                                       str.append(",");\r
+                       \r
+                               str.append(fkIsSelfReferencing[i]);\r
+                       }\r
+                       str.append(")");\r
+               \r
+                       str.append("\ncolumn Array:\t\t\t(");\r
+                       for (int i = 0; i < colArray.length; i++)\r
+                       {\r
+                               if (i > 0)\r
+                                       str.append(",");\r
+                       \r
+                               str.append(colArray[i]);\r
+                       }\r
+                       str.append(")\n");\r
+\r
+                       return str.toString();\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+}\r