Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / execute / CallStatementResultSet.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/execute/CallStatementResultSet.java
new file mode 100644 (file)
index 0000000..49c3b45
--- /dev/null
@@ -0,0 +1,176 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.execute.CallStatementResultSet\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 java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.jdbc.ConnectionContext;\r
+import org.apache.derby.iapi.services.loader.GeneratedMethod;\r
+import org.apache.derby.iapi.sql.Activation;\r
+\r
+/**\r
+ * Call a Java procedure. This calls a generated method in the\r
+ * activation which sets up the parameters and then calls the\r
+ * Java method that the procedure resolved to.\r
+ * <P>\r
+ * Valid dynamic results returned by the procedure will be closed\r
+ * as inaccessible when this is closed (e.g. a CALL within a trigger).\r
+ * \r
+ * <BR>\r
+ * Any code that requires the dynamic results to be accessible\r
+ * (such as the JDBC Statement object executing the CALL) must\r
+ * obtain the dynamic results from Activation.getDynamicResults()\r
+ * and remove each ResultSet it will be handling by clearing the\r
+ * reference in the object returned.\r
+ * \r
+ * @see Activation#getDynamicResults()\r
+ */\r
+class CallStatementResultSet extends NoRowsResultSetImpl\r
+{\r
+\r
+       private final GeneratedMethod methodCall;\r
+\r
+    /*\r
+     * class interface\r
+     *\r
+     */\r
+    CallStatementResultSet(\r
+                               GeneratedMethod methodCall,\r
+                               Activation a) \r
+                       throws StandardException\r
+    {\r
+               super(a);\r
+               this.methodCall = methodCall;\r
+       }\r
+\r
+       /**\r
+     * Just invoke the method.\r
+               @exception StandardException Standard Derby error policy\r
+       */\r
+       public void open() throws StandardException\r
+       {\r
+               setup();\r
+               methodCall.invoke(activation);\r
+    }\r
+    \r
+    /**\r
+     * Need to explicitly close any dynamic result sets.\r
+     * <BR>\r
+     * If the dynamic results are not accessible then they\r
+     * need to be destroyed (ie. closed) according the the\r
+     * SQL Standard.\r
+     * <BR>\r
+     * An execution of a CALL statement through JDBC makes the\r
+     * dynamic results accessible, in this case the closing\r
+     * of the dynamic result sets is handled by the JDBC\r
+     * statement object (EmbedStatement) that executed the CALL.\r
+     * We cannot unify the closing of dynamic result sets to\r
+     * this close, as in accessible case it is called during\r
+     * the Statement.execute call, thus it would close the\r
+     * dynamic results before the application has a change\r
+     * to use them.\r
+     * \r
+     * <BR>\r
+     * With an execution of a CALL\r
+     * statement as a trigger's action statement the dynamic\r
+     * result sets are not accessible. In this case this close\r
+     * method is called after the execution of the trigger's\r
+     * action statement.\r
+     * <BR>\r
+     * <BR>\r
+     * Section 4.27.5 of the TECHNICAL CORRIGENDUM 1 to the SQL 2003\r
+     * Standard details what happens to dynamic result sets in detail,\r
+     * the SQL 2003 foundation document is missing these details.\r
+     */\r
+    public void close() throws StandardException\r
+    {\r
+        super.close();\r
+        \r
+        \r
+        \r
+        ResultSet[][] dynamicResults = getActivation().getDynamicResults();\r
+        if (dynamicResults != null)\r
+        {\r
+            // Need to ensure all the result sets opened by this\r
+            // CALL statement for this connection are closed.\r
+            // If any close() results in an exception we need to keep going,\r
+            // save any exceptions and then throw them once we are complete.\r
+            StandardException errorOnClose = null;\r
+            \r
+            ConnectionContext jdbcContext = null;\r
+            \r
+            for (int i = 0; i < dynamicResults.length; i++)\r
+            {\r
+                ResultSet[] param = dynamicResults[i];\r
+                ResultSet drs = param[0];\r
+                \r
+                // Can be null if the procedure never set this parameter\r
+                // or if the dynamic results were processed by JDBC (EmbedStatement).\r
+                if (drs == null)\r
+                    continue;\r
+                \r
+                if (jdbcContext == null)\r
+                    jdbcContext = (ConnectionContext)\r
+                   lcc.getContextManager().getContext(ConnectionContext.CONTEXT_ID);\r
+               \r
+                try {\r
+                    \r
+                    // Is this a valid, open dynamic result set for this connection?\r
+                    if (!jdbcContext.processInaccessibleDynamicResult(drs))\r
+                    {\r
+                        // If not just ignore it, not Derby's problem.\r
+                        continue;\r
+                    }\r
+                    \r
+                    drs.close();\r
+                    \r
+                } catch (SQLException e) {\r
+                    \r
+                    // Just report the first error\r
+                    if (errorOnClose == null)\r
+                    {\r
+                        StandardException se = StandardException.plainWrapException(e);\r
+                        errorOnClose = se;\r
+                    }\r
+                }\r
+                finally {\r
+                    // Remove any reference to the ResultSet to allow\r
+                    // it and any associated resources to be garbage collected.\r
+                    param[0] = null;\r
+                }\r
+            }\r
+            \r
+            if (errorOnClose != null)\r
+                throw errorOnClose;\r
+        }       \r
+    }\r
+\r
+       /**\r
+        * @see org.apache.derby.iapi.sql.ResultSet#cleanUp\r
+        */\r
+       public void     cleanUp() throws StandardException\r
+       {\r
+                       close();\r
+       }\r
+}\r