Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / execute / NormalizeResultSet.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/execute/NormalizeResultSet.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/execute/NormalizeResultSet.java
new file mode 100644 (file)
index 0000000..31d27a7
--- /dev/null
@@ -0,0 +1,368 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.NormalizeResultSet\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.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ResultColumnDescriptor;\r
+import org.apache.derby.iapi.sql.ResultDescription;\r
+import org.apache.derby.iapi.sql.execute.CursorResultSet;\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.types.RowLocation;\r
+\r
+/**\r
+ * Cast the rows from the source result set to match the format of the\r
+ * result set for the entire statement.\r
+ */\r
+\r
+class NormalizeResultSet extends NoPutResultSetImpl\r
+       implements CursorResultSet\r
+{\r
+       /*\r
+    ** Set in constructor and not altered during life of object.\r
+       */\r
+\r
+    public NoPutResultSet      source;\r
+       private ExecRow                 normalizedRow;\r
+       private int                             numCols;\r
+       private int                             startCol;\r
+\r
+       /* RESOLVE - We need to pass the ResultDescription for this ResultSet\r
+        * as a parameter to the constructor and use it instead of the one from\r
+        * the activation\r
+        */\r
+       private ResultDescription resultDescription;\r
+\r
+       /* info for caching DTSs */\r
+       private DataTypeDescriptor[] desiredTypes;\r
+\r
+       /**\r
+        * Constructor for a NormalizeResultSet\r
+        *\r
+        * @param source                                        The NoPutResultSet from which to get rows\r
+        *                                                                      to be normalized\r
+        * @param activation                            The activation for this execution\r
+        * @param resultSetNumber                       The resultSetNumber\r
+        * @param erdNumber                                     The integer for the ResultDescription\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+\r
+       public NormalizeResultSet(NoPutResultSet source,\r
+                                                         Activation activation, int resultSetNumber,\r
+                                                         int erdNumber,\r
+                                                     double optimizerEstimatedRowCount,\r
+                                                         double optimizerEstimatedCost,\r
+                                                         boolean forUpdate) throws StandardException\r
+       {\r
+               super(activation, resultSetNumber, optimizerEstimatedRowCount, \r
+                         optimizerEstimatedCost);\r
+               this.source = source;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (! (activation.getPreparedStatement().getSavedObject(erdNumber)\r
+                                                        instanceof ResultDescription))\r
+                       {\r
+                               SanityManager.THROWASSERT(\r
+                                       "activation.getPreparedStatement().getSavedObject(erdNumber) " +\r
+                                       "expected to be instanceof ResultDescription");\r
+                       }\r
+\r
+                       // source expected to be non-null, mystery stress test bug\r
+                       // - sometimes get NullPointerException in openCore().\r
+                       SanityManager.ASSERT(source != null,\r
+                               "NRS(), source expected to be non-null");\r
+               }\r
+\r
+               this.resultDescription = \r
+                       (ResultDescription) activation.getPreparedStatement().getSavedObject(erdNumber);\r
+\r
+               numCols = resultDescription.getColumnCount();\r
+               \r
+               /*\r
+                 An update row, for an update statement which sets n columns; i.e\r
+                    UPDATE tab set x,y,z=.... where ...;\r
+                 has,\r
+                 before values of x,y,z after values of x,y,z and rowlocation.\r
+                 need only normalize after values of x,y,z.\r
+                 i.e insead of starting at index = 1, I need to start at index = 4.\r
+                 also I needn't normalize the last value in the row.\r
+       */\r
+               startCol = (forUpdate) ? ((numCols - 1)/ 2) + 1 : 1;\r
+               normalizedRow = activation.getExecutionFactory().getValueRow(numCols);\r
+               constructorTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+\r
+       //\r
+       // ResultSet interface (leftover from NoPutResultSet)\r
+       //\r
+\r
+       /**\r
+     * open a scan on the source. scan parameters are evaluated\r
+     * at each open, so there is probably some way of altering\r
+     * their values...\r
+        *\r
+        * @exception StandardException thrown on failure \r
+     */\r
+       public void     openCore() throws StandardException\r
+       {\r
+               beginTime = getCurrentTimeMillis();\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT( ! isOpen, "NormalizeResultSet already open");\r
+\r
+               // source expected to be non-null, mystery stress test bug\r
+               // - sometimes get NullPointerException in openCore().\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(source != null,\r
+                               "NRS().openCore(), source expected to be non-null");\r
+               }\r
+\r
+        source.openCore();\r
+           isOpen = true;\r
+               numOpens++;\r
+\r
+               openTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+       /**\r
+        * reopen a scan on the table. scan parameters are evaluated\r
+        * at each open, so there is probably some way of altering\r
+        * their values...\r
+        *\r
+        * @exception StandardException thrown if cursor finished.\r
+        */\r
+       public void     reopenCore() throws StandardException \r
+       {\r
+               beginTime = getCurrentTimeMillis();\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT(isOpen, "NormalizeResultSet already open");\r
+\r
+               source.reopenCore();\r
+               numOpens++;\r
+\r
+               openTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+       /**\r
+        *\r
+        * @exception StandardException thrown on failure \r
+        */\r
+       public ExecRow  getNextRowCore() throws StandardException\r
+       {\r
+               ExecRow         sourceRow = null;\r
+               ExecRow         result = null;\r
+\r
+               beginTime = getCurrentTimeMillis();\r
+               if (!isOpen)\r
+                       throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, "next");\r
+\r
+               sourceRow = source.getNextRowCore();\r
+               if (sourceRow != null)\r
+               {\r
+                       result = normalizeRow(sourceRow);\r
+                       rowsSeen++;\r
+               }\r
+\r
+               currentRow = result;\r
+               setCurrentRow(result);\r
+\r
+               nextTime += getElapsedMillis(beginTime);\r
+               return result;\r
+       }\r
+\r
+       /**\r
+        * If the result set has been opened,\r
+        * close the open scan.\r
+        *\r
+        * @exception StandardException thrown on error\r
+        */\r
+       public void     close() throws StandardException\r
+       {\r
+               beginTime = getCurrentTimeMillis();\r
+           if ( isOpen )\r
+           {\r
+                       currentRow = null;\r
+               source.close();\r
+\r
+                       super.close();\r
+           }\r
+               else\r
+                       if (SanityManager.DEBUG)\r
+                               SanityManager.DEBUG("CloseRepeatInfo","Close of NormalizeResultSet repeated");\r
+\r
+               closeTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+       /**\r
+        * Return the total amount of time spent in this ResultSet\r
+        *\r
+        * @param type  CURRENT_RESULTSET_ONLY - time spent only in this ResultSet\r
+        *                              ENTIRE_RESULTSET_TREE  - time spent in this ResultSet and below.\r
+        *\r
+        * @return long         The total amount of time spent (in milliseconds).\r
+        */\r
+       public long getTimeSpent(int type)\r
+       {\r
+               long totTime = constructorTime + openTime + nextTime + closeTime;\r
+\r
+               if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY)\r
+               {\r
+                       return  totTime - source.getTimeSpent(ENTIRE_RESULTSET_TREE);\r
+               }\r
+               else\r
+               {\r
+                       return totTime;\r
+               }\r
+       }\r
+\r
+       //\r
+       // CursorResultSet interface\r
+       //\r
+\r
+       /**\r
+        * Gets information from its source. We might want\r
+        * to have this take a CursorResultSet in its constructor some day,\r
+        * instead of doing a cast here?\r
+        *\r
+        * @see CursorResultSet\r
+        *\r
+        * @return the row location of the current cursor row.\r
+        *\r
+        * @exception StandardException thrown on failure \r
+        */\r
+       public RowLocation getRowLocation() throws StandardException \r
+       {\r
+               if (SanityManager.DEBUG)\r
+                       SanityManager.ASSERT(source instanceof CursorResultSet, "source is not a cursorresultset");\r
+               return ( (CursorResultSet)source ).getRowLocation();\r
+       }\r
+\r
+       /**\r
+        * Gets information from last getNextRow call.\r
+        *\r
+        * @see CursorResultSet\r
+        *\r
+        * @return the last row returned.\r
+        */\r
+       /* RESOLVE - this should return activation.getCurrentRow(resultSetNumber),\r
+        * once there is such a method.  (currentRow is redundant)\r
+        */\r
+       public ExecRow getCurrentRow() \r
+       {\r
+               return currentRow;\r
+       }\r
+\r
+       //\r
+       // class implementation\r
+       //\r
+       /**\r
+        * Normalize a row.  For now, this means calling constructors through\r
+        * the type services to normalize a type to itself.  For example,\r
+        * if you're putting a char(30) value into a char(15) column, it\r
+        * calls a SQLChar constructor with the char(30) value, and the\r
+        * constructor truncates the value and makes sure that no non-blank\r
+        * characters are truncated.\r
+        *\r
+        * In the future, this mechanism will be extended to do type conversions,\r
+        * as well.  I didn't implement type conversions yet because it looks\r
+        * like a lot of work, and we needed char and varchar right away.\r
+        *\r
+        * @param sourceRow             The row to normalize\r
+        *\r
+        * @return      The normalized row\r
+        *\r
+        * @exception StandardException thrown on failure \r
+        */\r
+       private ExecRow normalizeRow(ExecRow sourceRow) throws StandardException\r
+       {\r
+               int                                     whichCol;\r
+\r
+               if (desiredTypes == null)\r
+               {\r
+                       desiredTypes = new DataTypeDescriptor[numCols];\r
+                       for (whichCol = 1; whichCol <= numCols; whichCol++)\r
+                       {\r
+                               DataTypeDescriptor dtd = resultDescription.getColumnDescriptor(whichCol).getType();\r
+\r
+                               desiredTypes[whichCol - 1] = dtd;\r
+                       }\r
+\r
+               }\r
+\r
+               for (whichCol = 1; whichCol <= numCols; whichCol++)\r
+               {\r
+                       DataValueDescriptor sourceCol = sourceRow.getColumn(whichCol);\r
+                       if (sourceCol != null)\r
+                       {\r
+                               DataValueDescriptor     normalizedCol;\r
+                               // skip the before values in case of update\r
+                               if (whichCol < startCol)\r
+                                       normalizedCol = sourceCol;\r
+                               else\r
+                                       try {\r
+                                               normalizedCol = \r
+                                               desiredTypes[whichCol - 1].normalize(sourceCol, \r
+                                                                       normalizedRow.getColumn(whichCol));\r
+                                       } catch (StandardException se) {\r
+                                               // Catch illegal null insert and add column info\r
+                                               if (se.getMessageId().startsWith(SQLState.LANG_NULL_INTO_NON_NULL))\r
+                                               {\r
+                                                       ResultColumnDescriptor columnDescriptor =\r
+                                                               resultDescription.getColumnDescriptor(whichCol);\r
+                                                       throw\r
+                                                               StandardException.newException(SQLState.LANG_NULL_INTO_NON_NULL, \r
+                                                                                                                          columnDescriptor.getName());\r
+                                               }\r
+                                               //just rethrow if not LANG_NULL_INTO_NON_NULL\r
+                                               throw se;\r
+                                       }\r
+\r
+                               normalizedRow.setColumn(whichCol, normalizedCol);\r
+                       }\r
+               }\r
+\r
+               return normalizedRow;\r
+       }\r
+\r
+       /**\r
+        * @see NoPutResultSet#updateRow\r
+        */\r
+       public void updateRow (ExecRow row) throws StandardException {\r
+               source.updateRow(row);\r
+       }\r
+\r
+       /**\r
+        * @see NoPutResultSet#markRowAsDeleted\r
+        */\r
+       public void markRowAsDeleted() throws StandardException {\r
+               source.markRowAsDeleted();\r
+       }\r
+\r
+}\r