Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / execute / OnceResultSet.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/OnceResultSet.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/OnceResultSet.java
new file mode 100644 (file)
index 0000000..ce99032
--- /dev/null
@@ -0,0 +1,307 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.OnceResultSet\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.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.stream.HeaderPrintWriter;\r
+import org.apache.derby.iapi.services.stream.InfoStreams;\r
+\r
+import org.apache.derby.iapi.sql.conn.StatementContext;\r
+\r
+import org.apache.derby.iapi.sql.execute.ExecRow;\r
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;\r
+\r
+import org.apache.derby.iapi.types.DataValueDescriptor;\r
+import org.apache.derby.iapi.sql.Activation;\r
+import org.apache.derby.iapi.sql.ResultSet;\r
+\r
+import org.apache.derby.iapi.services.loader.GeneratedMethod;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+/**\r
+ * Takes an expression subquery's result set and verifies that only\r
+ * a single scalar value is being returned.\r
+ * NOTE: A row with a single column containing null will be returned from\r
+ * getNextRow() if the underlying subquery ResultSet is empty.\r
+ *\r
+ */\r
+public class OnceResultSet extends NoPutResultSetImpl\r
+{\r
+       /* Statics for cardinality check */\r
+       public static final int DO_CARDINALITY_CHECK            = 1;\r
+       public static final int NO_CARDINALITY_CHECK            = 2;\r
+       public static final int UNIQUE_CARDINALITY_CHECK        = 3;\r
+\r
+       /* Used to cache row with nulls for case when subquery result set\r
+        * is empty.\r
+        */\r
+       private ExecRow rowWithNulls;\r
+\r
+       /* Used to cache the StatementContext */\r
+       private StatementContext statementContext;\r
+\r
+    // set in constructor and not altered during\r
+    // life of object.\r
+    public NoPutResultSet source;\r
+       private GeneratedMethod emptyRowFun;\r
+       private int cardinalityCheck;\r
+       public int subqueryNumber;\r
+       public int pointOfAttachment;\r
+\r
+    //\r
+    // class interface\r
+    //\r
+    public OnceResultSet(NoPutResultSet s, Activation a, GeneratedMethod emptyRowFun,\r
+                                                int cardinalityCheck, int resultSetNumber,\r
+                                                int subqueryNumber, int pointOfAttachment,\r
+                                                double optimizerEstimatedRowCount,\r
+                                                double optimizerEstimatedCost)\r
+       {\r
+               super(a, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost);\r
+        source = s;\r
+               this.emptyRowFun = emptyRowFun;\r
+               this.cardinalityCheck = cardinalityCheck;\r
+               this.subqueryNumber = subqueryNumber;\r
+               this.pointOfAttachment = pointOfAttachment;\r
+               constructorTime += getElapsedMillis(beginTime);\r
+    }\r
+\r
+       //\r
+       // ResultSet interface (leftover from NoPutResultSet)\r
+       //\r
+\r
+       /**\r
+     * open 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     openCore() throws StandardException \r
+       {\r
+               /* NOTE: We can't get code generation\r
+                * to generate calls to reopenCore() for\r
+                * subsequent probes, so we just handle\r
+                * it here.\r
+                */\r
+               if (isOpen)\r
+               {\r
+                       reopenCore();\r
+                       return;\r
+               }\r
+\r
+               beginTime = getCurrentTimeMillis();\r
+\r
+        source.openCore();\r
+\r
+               /* Notify StatementContext about ourself so that we can\r
+                * get closed down, if necessary, on an exception.\r
+                */\r
+               if (statementContext == null)\r
+               {\r
+                       statementContext = getLanguageConnectionContext().getStatementContext();\r
+               }\r
+               statementContext.setSubqueryResultSet(subqueryNumber, this, \r
+                                                                                         activation.getNumSubqueries());\r
+\r
+               numOpens++;\r
+           isOpen = true;\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, "OnceResultSet already open");\r
+\r
+        source.reopenCore();\r
+               numOpens++;\r
+\r
+               openTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+       /**\r
+     * Return the requested value computed from the next row.  \r
+        *\r
+        * @exception StandardException thrown on failure.\r
+        *                        StandardException ScalarSubqueryCardinalityViolation\r
+        *                                              Thrown if scalar subquery returns more than 1 row.\r
+        */\r
+       public ExecRow  getNextRowCore() throws StandardException \r
+       {\r
+           ExecRow candidateRow = null;\r
+               ExecRow secondRow = null;\r
+           ExecRow result = null;\r
+\r
+               beginTime = getCurrentTimeMillis();\r
+               // This is an ASSERT and not a real error because this is never\r
+               // outermost in the tree and so a next call when closed will not occur.\r
+               if (SanityManager.DEBUG)\r
+               SanityManager.ASSERT( isOpen, "OpenResultSet not open");\r
+\r
+           if ( isOpen ) \r
+               {\r
+                       candidateRow = source.getNextRowCore();\r
+\r
+                       if (candidateRow != null)\r
+                       {\r
+                               switch (cardinalityCheck)\r
+                               {\r
+                                       case DO_CARDINALITY_CHECK:\r
+                                       case NO_CARDINALITY_CHECK:\r
+                                               candidateRow = candidateRow.getClone();\r
+                                               if (cardinalityCheck == DO_CARDINALITY_CHECK)\r
+                                               {\r
+                                                       /* Raise an error if the subquery returns > 1 row \r
+                                                        * We need to make a copy of the current candidateRow since\r
+                                                        * the getNextRow() for this check will wipe out the underlying\r
+                                                        * row.\r
+                                                        */\r
+                                                       secondRow = source.getNextRowCore();\r
+                                                       if (secondRow != null)\r
+                                                       {\r
+                                                               close();\r
+                                                               StandardException se = StandardException.newException(SQLState.LANG_SCALAR_SUBQUERY_CARDINALITY_VIOLATION);\r
+                                                               throw se;\r
+                                                       }\r
+                                               }\r
+                                               result = candidateRow;\r
+                                               break;\r
+\r
+                                       case UNIQUE_CARDINALITY_CHECK:\r
+                                               candidateRow = candidateRow.getClone();\r
+                                               secondRow = source.getNextRowCore();\r
+                                               DataValueDescriptor orderable1 = candidateRow.getColumn(1);\r
+                                               while (secondRow != null)\r
+                                               {\r
+                                                       DataValueDescriptor orderable2 = secondRow.getColumn(1);\r
+                                                       if (! (orderable1.compare(DataValueDescriptor.ORDER_OP_EQUALS, orderable2, true, true)))\r
+                                                       {\r
+                                                               close();\r
+                                                               StandardException se = StandardException.newException(SQLState.LANG_SCALAR_SUBQUERY_CARDINALITY_VIOLATION);\r
+                                                               throw se;\r
+                                                       }\r
+                                                       secondRow = source.getNextRowCore();\r
+                                               }\r
+                                               result = candidateRow;\r
+                                               break;\r
+\r
+                                       default:\r
+                                               if (SanityManager.DEBUG)\r
+                                               {\r
+                                                       SanityManager.THROWASSERT(\r
+                                                               "cardinalityCheck not unexpected to be " +\r
+                                                               cardinalityCheck);\r
+                                               }\r
+                                               break;\r
+                               }\r
+                       }\r
+                       else if (rowWithNulls == null)\r
+                       {\r
+                               rowWithNulls = (ExecRow) emptyRowFun.invoke(activation);\r
+                               result = rowWithNulls;\r
+                       }\r
+                       else\r
+                       {\r
+                               result = rowWithNulls;\r
+                       }\r
+           }\r
+\r
+               currentRow = result;\r
+               setCurrentRow(result);\r
+               rowsSeen++;\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
+                       // we don't want to keep around a pointer to the\r
+                       // row ... so it can be thrown away.\r
+                       // REVISIT: does this need to be in a finally\r
+                       // block, to ensure that it is executed?\r
+                   clearCurrentRow();\r
+\r
+               source.close();\r
+\r
+                       super.close();\r
+           }\r
+               else\r
+                       if (SanityManager.DEBUG)\r
+                               SanityManager.DEBUG("CloseRepeatInfo","Close of OnceResultSet repeated");\r
+\r
+               closeTime += getElapsedMillis(beginTime);\r
+       }\r
+\r
+       /**\r
+        * @see NoPutResultSet#getPointOfAttachment\r
+        */\r
+       public int getPointOfAttachment()\r
+       {\r
+               return pointOfAttachment;\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