Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / execute / UpdateStatisticsConstantAction.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/UpdateStatisticsConstantAction.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/UpdateStatisticsConstantAction.java
new file mode 100644 (file)
index 0000000..27cf36a
--- /dev/null
@@ -0,0 +1,233 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.UpdateStatisticsConstantAction\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.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.StatisticsDescriptor;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.execute.ExecIndexRow;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.store.access.GroupFetchScanController;\r
+import org.apache.derby.iapi.store.access.ConglomerateController;\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.catalog.types.StatisticsImpl;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+/**\r
+ * This class describes actions that are performed for an \r
+ * UPDATE STATISTICS Statement at execution time.\r
+ */\r
+\r
+class UpdateStatisticsConstantAction extends DDLConstantAction\r
+{\r
+       private UUID tableUUID;\r
+       private UUID[] objectUUID;\r
+       private String objectName;\r
+       private boolean forTable;\r
+       private long[] conglomerateNumber;\r
+       private ExecIndexRow[] indexRow;\r
+\r
+       /* RUNTIME state of the system is maintained in these objects.\r
+        * rowBufferOne simply reuses the index row prepared by\r
+        * makeConstantAction. rowBufferTwo is a clone (an extra copy) of\r
+        * objects. rowBufferCurrent just switches between rowBufferOne and\r
+        * rowBufferTwo. \r
+        */\r
+       private DataValueDescriptor[][] rowBufferArray;\r
+       private DataValueDescriptor[] rowBuffer;\r
+       private DataValueDescriptor[] lastUniqueKey;\r
+\r
+       private static final int GROUP_FETCH_SIZE = 16;\r
+\r
+       public UpdateStatisticsConstantAction() {};\r
+\r
+       public UpdateStatisticsConstantAction(boolean forTable,\r
+                                                                                 String objectName,\r
+                                                                                 UUID tableUUID,\r
+                                                                                 UUID[] objectUUID,\r
+                                                                                 long[] conglomerateNumber,\r
+                                                                                 ExecIndexRow[] indexRow)\r
+       {\r
+               \r
+               this.forTable = forTable;\r
+               this.objectName = objectName;\r
+               this.tableUUID = tableUUID;\r
+               this.objectUUID = objectUUID;\r
+               this.conglomerateNumber = conglomerateNumber;\r
+               this.indexRow = indexRow;\r
+       }\r
+\r
+       public String toString()\r
+       {\r
+               return "UPDATE STATISTICS FOR " + (forTable ? "TABLE" : "INDEX") + " " +\r
+                       objectName; \r
+                       \r
+       }\r
+\r
+       public void executeConstantAction(Activation activation) \r
+               throws StandardException\r
+       \r
+       {\r
+               GroupFetchScanController gsc = null;\r
+               TransactionController tc = activation.getTransactionController();\r
+               LanguageConnectionContext lcc = activation.getLanguageConnectionContext();\r
+               DataDictionary dd = lcc.getDataDictionary();\r
+               DependencyManager dm = dd.getDependencyManager();\r
+\r
+               \r
+               dd.startWriting(lcc);\r
+\r
+               TableDescriptor td = dd.getTableDescriptor(tableUUID);\r
+               dm.invalidateFor(td, DependencyManager.UPDATE_STATISTICS, lcc);\r
+\r
+               for (int indexNumber = 0; indexNumber < conglomerateNumber.length;\r
+                        indexNumber++) \r
+               {\r
+                       if (conglomerateNumber[indexNumber] == -1)\r
+                               continue;\r
+\r
+                       int numCols = indexRow[indexNumber].nColumns() - 1;;\r
+                       long[] cardinality = new long[numCols];\r
+                       long numRows = 0;\r
+                       initializeRowBuffers(indexRow[indexNumber]);\r
+\r
+                       try\r
+                       {\r
+                               /* Read uncommited, with record locking. Actually CS store may\r
+                                  not hold record locks */\r
+                               gsc = \r
+                    tc.openGroupFetchScan(\r
+                        conglomerateNumber[indexNumber], \r
+                        false,  // hold\r
+                        0,      // openMode: for read\r
+                        TransactionController.MODE_RECORD, // locking\r
+                        TransactionController.ISOLATION_READ_UNCOMMITTED, //isolation level\r
+                        null,   // scancolumnlist-- want everything.\r
+                        null,   // startkeyvalue-- start from the beginning.\r
+                        0,\r
+                        null,   // qualifiers, none!\r
+                        null,   // stopkeyvalue,\r
+                        0);\r
+               \r
+                               boolean firstRow = true;\r
+                               int rowsFetched = 0;\r
+                               while ((rowsFetched = gsc.fetchNextGroup(rowBufferArray, null)) > 0)\r
+                               {\r
+                                       for (int i = 0; i < rowsFetched; i++)\r
+                                       {\r
+                                               int whichPositionChanged = compareWithPrevKey(i, firstRow);\r
+                                               firstRow = false;\r
+                                               if (whichPositionChanged >= 0)\r
+                                               {\r
+                                                       for (int j = whichPositionChanged; j < cardinality.length; j++)\r
+                                                               cardinality[j]++;\r
+                                               }\r
+                                               numRows++;\r
+                                       }\r
+\r
+                                       DataValueDescriptor[] tmp;\r
+                                       tmp = rowBufferArray[GROUP_FETCH_SIZE - 1];\r
+                                       rowBufferArray[GROUP_FETCH_SIZE - 1] = lastUniqueKey;\r
+                                       lastUniqueKey = tmp;\r
+                               } // while\r
+                       } // try\r
+                       finally \r
+                       {\r
+                               if (gsc != null)\r
+                               {\r
+                                       gsc.close();\r
+                                       gsc = null;\r
+                               }\r
+                       }\r
+\r
+                   if (numRows == 0)\r
+                       {\r
+                               /* if there is no data in the table: no need to write anything\r
+                                * to sys.systatstics.\r
+                                */\r
+                               break;                  \r
+                       }                       \r
+\r
+                       StatisticsDescriptor statDesc;\r
+               \r
+                       dd.dropStatisticsDescriptors(tableUUID, objectUUID[indexNumber],\r
+                                                                                tc); \r
+\r
+                       for (int i = 0; i < indexRow[indexNumber].nColumns() - 1; i++)\r
+                       {\r
+                               statDesc = new StatisticsDescriptor(dd, dd.getUUIDFactory().createUUID(),\r
+                                                                                                          objectUUID[indexNumber],\r
+                                                                                                          tableUUID,\r
+                                                                                                          "I",\r
+                                                                                                          new StatisticsImpl(numRows,\r
+                                                                                                                                                 cardinality[i]),\r
+                                                                                                          i + 1);\r
+                               dd.addDescriptor(statDesc, null,\r
+                                                                DataDictionary.SYSSTATISTICS_CATALOG_NUM,\r
+                                                                true, tc);\r
+                       } // for each leading column (c1) (c1,c2)....\r
+\r
+               } // for each index.\r
+       }\r
+\r
+\r
+       private void initializeRowBuffers(ExecIndexRow ir)\r
+       {\r
+\r
+               rowBufferArray = new DataValueDescriptor[GROUP_FETCH_SIZE][];\r
+               lastUniqueKey = ir.getRowArrayClone();\r
+               rowBufferArray[0] = ir.getRowArray(); // 1 gets old objects.\r
+       }\r
+\r
+       private int compareWithPrevKey(int index, boolean firstRow)\r
+               throws StandardException\r
+       {\r
+               if (firstRow)\r
+                       return 0;\r
+\r
+               DataValueDescriptor[] prev = (index == 0) ? lastUniqueKey : rowBufferArray[index - 1];\r
+               DataValueDescriptor[] curr = rowBufferArray[index];\r
+               // no point trying to do rowlocation; hence - 1\r
+               for (int i = 0; i < (prev.length - 1); i++)\r
+               {\r
+                       DataValueDescriptor dvd = (DataValueDescriptor)prev[i];\r
+\r
+                       if (dvd.isNull())\r
+                               return i;               // nulls are counted as unique values.\r
+\r
+                       if (prev[i].compare(curr[i]) != 0)\r
+                       {\r
+                               return i;\r
+                       }\r
+               }\r
+\r
+               return -1;\r
+       }\r
+\r
+       \r
+\r
+}\r