Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / impl / sql / conn / GenericStatementContext.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/impl/sql/conn/GenericStatementContext.java
new file mode 100644 (file)
index 0000000..d412e89
--- /dev/null
@@ -0,0 +1,747 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.conn.GenericStatementContext\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.conn;\r
+\r
+import org.apache.derby.iapi.services.context.Context;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+\r
+import org.apache.derby.iapi.services.timer.TimerFactory;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.conn.StatementContext;\r
+\r
+import org.apache.derby.iapi.sql.depend.Dependency;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+\r
+import org.apache.derby.iapi.sql.execute.NoPutResultSet;\r
+\r
+import org.apache.derby.iapi.sql.ResultSet;\r
+import org.apache.derby.iapi.sql.ParameterValueSet;\r
+\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+\r
+import org.apache.derby.iapi.services.context.ContextImpl;\r
+\r
+import org.apache.derby.iapi.error.ExceptionSeverity;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import java.util.ArrayList;\r
+import java.util.Iterator;\r
+import java.util.Timer;\r
+import java.util.TimerTask;\r
+import java.sql.SQLException;\r
+\r
+/**\r
+ * GenericStatementContext is pushed/popped around a statement prepare and execute\r
+ * so that any statement specific clean up can be performed.\r
+ *\r
+ *\r
+ */\r
+final class GenericStatementContext \r
+       extends ContextImpl implements StatementContext\r
+{\r
+       private boolean         setSavePoint;\r
+       private String          internalSavePointName;\r
+       private ResultSet       topResultSet;\r
+       private ArrayList               dependencies;\r
+       private NoPutResultSet[] subqueryTrackingArray;\r
+       private NoPutResultSet[] materializedSubqueries;\r
+       private final LanguageConnectionContext lcc;\r
+       private boolean         inUse = true;\r
+\r
+    // This flag satisfies all the conditions\r
+    // for using volatile instead of synchronized.\r
+    // (Source: Doug Lea, Concurrent Programming in Java, Second Edition,\r
+    // section 2.2.7.4, page 97)\r
+    // true if statement has been cancelled\r
+    private volatile boolean cancellationFlag = false;\r
+\r
+    // Reference to the TimerTask that will time out this statement.\r
+    // Needed for stopping the task when execution completes before timeout.\r
+    private CancelQueryTask cancelTask = null;\r
+        \r
+    private    boolean         parentInTrigger;        // whetherparent started with a trigger on stack\r
+    private    boolean         isForReadOnly = false;  \r
+    private    boolean         isAtomic;       \r
+       private boolean         isSystemCode;\r
+       private boolean         rollbackParentContext;\r
+    private    String          stmtText;\r
+    private    ParameterValueSet                       pvs;\r
+\r
+       /**\r
+               Set to one of RoutineAliasInfo.{MODIFIES_SQL_DATA, READS_SQL_DATA, CONTAINS_SQL, NO_SQL}\r
+       */\r
+       private short                   sqlAllowed = -1;\r
+\r
+       /*\r
+          constructor\r
+               @param tc transaction\r
+       */\r
+       GenericStatementContext(LanguageConnectionContext lcc) \r
+       {\r
+               super(lcc.getContextManager(), org.apache.derby.iapi.reference.ContextId.LANG_STATEMENT);\r
+               this.lcc = lcc;\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT((lcc != null),\r
+                                       "Failed to get language connection context");\r
+               }\r
+\r
+        internalSavePointName = lcc.getUniqueSavepointName();\r
+       }\r
+\r
+    /**\r
+     * This is a TimerTask that is responsible for timing out statements,\r
+     * typically when an application has called Statement.setQueryTimeout().\r
+     *\r
+     * When the application invokes execute() on a statement object, or\r
+     * fetches data on a ResultSet, a StatementContext object is allocated\r
+     * for the duration of the execution in the engine (until control is\r
+     * returned to the application).\r
+     *\r
+     * When the StatementContext object is assigned with setInUse(),\r
+     * a CancelQueryTask is scheduled if a timeout > 0 has been set.\r
+     */\r
+    private static class CancelQueryTask\r
+        extends\r
+            TimerTask\r
+    {\r
+        /**\r
+         * Reference to the StatementContext for the executing statement\r
+         * which might time out.\r
+         */\r
+        private StatementContext statementContext;\r
+\r
+        /**\r
+         * Initializes a new task for timing out a statement's execution.\r
+         * This does not schedule it for execution, the caller is\r
+         * responsible for calling Timer.schedule() with this object\r
+         * as parameter.\r
+         */\r
+        public CancelQueryTask(StatementContext ctx)\r
+        {\r
+            statementContext = ctx;\r
+        }\r
+\r
+        /**\r
+         * Invoked by a Timer class to cancel an executing statement.\r
+         * This method just sets a volatile flag in the associated\r
+         * StatementContext object by calling StatementContext.cancel();\r
+         * it is the responsibility of the thread executing the statement\r
+         * to check this flag regularly.\r
+         */\r
+        public void run()\r
+        {\r
+            synchronized (this) {\r
+                if (statementContext != null) {\r
+                    statementContext.cancel();\r
+                }\r
+            }\r
+        }\r
+\r
+        /**\r
+         * Stops this task and prevents it from cancelling a statement.\r
+         * Guarantees that after this method returns, the associated\r
+         * StatementContext object will not be tampered with by this task.\r
+         * Thus, the StatementContext object may safely be allocated to\r
+         * other executing statements.\r
+         */\r
+        public void forgetContext() {\r
+            boolean mayStillRun = !cancel();\r
+            if (mayStillRun) {\r
+                synchronized (this) {\r
+                    statementContext = null;\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+       // StatementContext Interface\r
+\r
+       public void setInUse\r
+       ( \r
+               boolean parentInTrigger,\r
+               boolean isAtomic, \r
+                boolean isForReadOnly,\r
+               String stmtText,\r
+               ParameterValueSet pvs,\r
+        long timeoutMillis\r
+       ) \r
+       {\r
+               inUse = true;\r
+\r
+               this.parentInTrigger = parentInTrigger;\r
+               this.isForReadOnly = isForReadOnly;\r
+               this.isAtomic = isAtomic;\r
+               this.stmtText = stmtText;\r
+               this.pvs = pvs;\r
+               rollbackParentContext = false;\r
+        if (timeoutMillis > 0) {\r
+            TimerFactory factory = Monitor.getMonitor().getTimerFactory();\r
+            Timer timer = factory.getCancellationTimer();\r
+            cancelTask = new CancelQueryTask(this);\r
+            timer.schedule(cancelTask, timeoutMillis);\r
+        }\r
+       }\r
+\r
+       public void clearInUse() {\r
+               /* We must clear out the current top ResultSet to prepare for\r
+                * reusing a StatementContext.\r
+                */\r
+               stuffTopResultSet( null, null );\r
+               inUse = false;\r
+\r
+               parentInTrigger = false;\r
+               isAtomic = false;\r
+               isForReadOnly = false;\r
+               this.stmtText = null;\r
+               sqlAllowed = -1;\r
+               isSystemCode = false;\r
+               rollbackParentContext = false;\r
+\r
+        if (cancelTask != null) {\r
+            cancelTask.forgetContext();\r
+            cancelTask = null;\r
+        }\r
+        cancellationFlag = false;\r
+       }\r
+\r
+       /**\r
+        * @see StatementContext#setSavePoint\r
+        * @exception StandardException Thrown on error\r
+        */\r
+       public void setSavePoint() throws StandardException {\r
+               \r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (SanityManager.DEBUG_ON("traceSavepoints"))\r
+                       {\r
+                               SanityManager.DEBUG_PRINT(\r
+                                                                       "GenericStatementContext.setSavePoint()",\r
+                                                                       internalSavePointName);\r
+                       }\r
+               }\r
+                       \r
+               pleaseBeOnStack();\r
+               \r
+\r
+               lcc.getTransactionExecute().setSavePoint(internalSavePointName, null);\r
+               setSavePoint = true;\r
+       }\r
+\r
+       /**\r
+        * Resets the savepoint to the current spot if it is\r
+        * set, otherwise, noop.  Used when a commit is\r
+        * done on a nested connection.\r
+        *\r
+        * @see StatementContext#resetSavePoint\r
+        * @exception StandardException Thrown on error\r
+        */\r
+       public void resetSavePoint() throws StandardException {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (SanityManager.DEBUG_ON("traceSavepoints"))\r
+                       {\r
+                               SanityManager.DEBUG_PRINT(\r
+                                       "GenericStatementContext.resetSavePoint()",\r
+                                       internalSavePointName);\r
+                       }\r
+               }\r
+                       \r
+               if (inUse && setSavePoint)\r
+               {               \r
+                       // RESOLVE PLUGIN ???. For the plugin, there will be no transaction controller\r
+                       lcc.getTransactionExecute().setSavePoint(internalSavePointName, null);\r
+                       // stage buffer management\r
+               }\r
+       }\r
+\r
+       /**\r
+        * @see StatementContext#clearSavePoint\r
+        * @exception StandardException Thrown on error\r
+        */\r
+       public void clearSavePoint() throws StandardException {\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (SanityManager.DEBUG_ON("traceSavepoints"))\r
+                       {\r
+                               SanityManager.DEBUG_PRINT("GenericStatementContext.clearSavePoint()",\r
+                                                                                 internalSavePointName);\r
+                       }\r
+               }\r
+\r
+               pleaseBeOnStack();\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(setSavePoint, "setSavePoint is expected to be true");\r
+               }\r
+\r
+               // RESOLVE PLUGIN ???. For the plugin, there will be no transaction controller\r
+               lcc.getTransactionExecute().releaseSavePoint(internalSavePointName, null);\r
+               setSavePoint = false;\r
+       }\r
+\r
+       /**\r
+        * Set the top ResultSet in the ResultSet tree for close down on\r
+        * an error.\r
+        *\r
+        * @exception StandardException thrown on error.\r
+        */\r
+       public void setTopResultSet(ResultSet topResultSet, \r
+                                                           NoPutResultSet[] subqueryTrackingArray)\r
+                throws StandardException\r
+       {\r
+               pleaseBeOnStack();\r
+\r
+               /* We have to handle both materialize and non-materialized subqueries.\r
+                * Materialized subqueries are attached before the top result set is \r
+                * set.  If there are any, then we must copy them into the new\r
+                * subqueryTrackingArray.\r
+                */\r
+               if (materializedSubqueries != null)\r
+               {\r
+                       // Do the merging into the passed in array.\r
+                       if (subqueryTrackingArray != null)\r
+                       {\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       if (this.materializedSubqueries.length != subqueryTrackingArray.length)\r
+                                       {\r
+                                               SanityManager.THROWASSERT(\r
+                                                       "this.ms.length (" + this.materializedSubqueries.length +\r
+                                                       ") expected to = sta.length(" + subqueryTrackingArray.length +\r
+                                                       ")");\r
+                                       }\r
+                               }\r
+                               for (int index = 0; index < subqueryTrackingArray.length; index++)\r
+                               {\r
+                                       if (this.subqueryTrackingArray[index] != null)\r
+                                       {\r
+                                               subqueryTrackingArray[index] = this.materializedSubqueries[index];\r
+                                       }\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               subqueryTrackingArray = this.materializedSubqueries;\r
+                       }\r
+                       materializedSubqueries = null;\r
+               }\r
+\r
+               stuffTopResultSet( topResultSet, subqueryTrackingArray );\r
+       }\r
+\r
+       /**\r
+         *     Private minion of setTopResultSet() and clearInUse()\r
+         *\r
+         *     @param  topResultSet    make this the top result set\r
+         *     @param  subqueryTrackingArray   where to keep track of subqueries in this statement\r
+         */\r
+       private void    stuffTopResultSet(ResultSet topResultSet, \r
+                                                                         NoPutResultSet[] subqueryTrackingArray)\r
+       {\r
+               this.topResultSet = topResultSet;\r
+               this.subqueryTrackingArray = subqueryTrackingArray;\r
+               dependencies = null;\r
+       }\r
+\r
+\r
+       /**\r
+        * Set the appropriate entry in the subquery tracking array for\r
+        * the specified subquery.\r
+        * Useful for closing down open subqueries on an exception.\r
+        *\r
+        * @param subqueryNumber        The subquery # for this subquery\r
+        * @param subqueryResultSet     The ResultSet at the top of the subquery\r
+        * @param numSubqueries         The total # of subqueries in the entire query\r
+        *\r
+        * @exception StandardException thrown on error.\r
+        */\r
+       public void setSubqueryResultSet(int subqueryNumber,\r
+                                                                        NoPutResultSet subqueryResultSet,\r
+                                                                        int numSubqueries)\r
+               throws StandardException\r
+       {\r
+               pleaseBeOnStack();\r
+               \r
+               /* NOTE: In degenerate cases, it is possible that there is no top\r
+                * result set.  For example:\r
+                *              call (select 1 from systables).valueOf('111');\r
+                * In that case, we allocate our own subquery tracking array on\r
+                * each call. (Gross!)\r
+                * (Trust me, this is only done in degenerate cases.  The tests passed,\r
+                * except for the degenerate cases, before making this change, so we\r
+                * know that the top result set and array reuse is working for\r
+                * the non-degenerate cases.)\r
+                */\r
+               if (subqueryTrackingArray == null)\r
+               {\r
+                       if (topResultSet == null)\r
+                       {\r
+                               subqueryTrackingArray = new NoPutResultSet[numSubqueries];\r
+                               materializedSubqueries = new NoPutResultSet[numSubqueries];\r
+                       }\r
+                       else\r
+                       {\r
+                               subqueryTrackingArray = \r
+                                       topResultSet.getSubqueryTrackingArray(numSubqueries);\r
+                       }\r
+               }\r
+               subqueryTrackingArray[subqueryNumber] = subqueryResultSet;\r
+               if (materializedSubqueries != null)\r
+               {\r
+                       materializedSubqueries[subqueryNumber] = subqueryResultSet;\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Get the subquery tracking array for this query.\r
+        * (Useful for runtime statistics.)\r
+        *\r
+        * @return NoPutResultSet[]     The     (sparse) array of tops of subquery ResultSet trees\r
+        * @exception StandardException thrown on error.\r
+        */\r
+       public NoPutResultSet[] getSubqueryTrackingArray()\r
+               throws StandardException\r
+       {\r
+               pleaseBeOnStack();\r
+               \r
+               return subqueryTrackingArray;\r
+       }\r
+\r
+       /**\r
+        * Track a Dependency within this StatementContext.\r
+        * (We need to clear any dependencies added within this\r
+        * context on an error.\r
+        *\r
+        * @param dy    The dependency to track.\r
+        *\r
+        * @exception StandardException thrown on error.\r
+        */\r
+       public void addDependency(Dependency dy)\r
+               throws StandardException\r
+       {\r
+               pleaseBeOnStack();\r
+               \r
+               if (dependencies == null)\r
+               {\r
+                       dependencies = new ArrayList();\r
+               }\r
+               dependencies.add(dy);\r
+       }\r
+\r
+       /**\r
+        * Returns whether we started from within the context of a trigger\r
+        * or not.\r
+        *\r
+        * @return      true if we are in a trigger context\r
+        */\r
+       public  boolean inTrigger()\r
+       {\r
+               return  parentInTrigger;\r
+       }\r
+\r
+       //\r
+       // Context interface\r
+       //\r
+       /**\r
+        * Close down the top ResultSet, if relevant, and rollback to the\r
+        * internal savepoint, if one was set.\r
+        *\r
+        * @exception StandardException thrown on error. REVISIT: don't want\r
+        * cleanupOnError's to throw exceptions.\r
+        */\r
+       public void cleanupOnError(Throwable error) throws StandardException\r
+       {\r
+\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (SanityManager.DEBUG_ON("traceSavepoints"))\r
+                       {\r
+                               SanityManager.DEBUG_PRINT(\r
+                                               "GenericStatementContext.cleanupOnError()",\r
+                                               String.valueOf( hashCode() ) );\r
+                       }\r
+               }\r
+\r
+               /*\r
+               ** If it isn't a StandardException, then assume\r
+               ** session severity.  It is probably an unexpected\r
+               ** java error somewhere in the language.\r
+        ** Store layer treats JVM error as session severity, \r
+        ** hence to be consistent and to avoid getting rawstore\r
+        ** protocol violation errors, we treat java errors here\r
+        ** to be of session severity.  \r
+        */\r
+               int severity = (error instanceof StandardException) ?\r
+                       ((StandardException) error).getSeverity() :\r
+                       ExceptionSeverity.SESSION_SEVERITY;\r
+\r
+\r
+               /**\r
+                * Don't clean up this statement context if it's not in use.\r
+                * This can happen if you get an error while calling one of\r
+                * the JDBC getxxxx() methods on a ResultSet, since no statement\r
+                * context is pushed when those calls occur.\r
+                */\r
+               if (! inUse)\r
+               {\r
+                       return;\r
+               }\r
+\r
+               /* Clean up the ResultSet, if one exists */\r
+               if (topResultSet != null)\r
+               {\r
+                       topResultSet.cleanUp();\r
+               }\r
+\r
+               /* Close down any open subqueries */\r
+               if (subqueryTrackingArray != null)\r
+               {\r
+                       for (int index = 0; index < subqueryTrackingArray.length; index++)\r
+                       {\r
+                               /* Remember, the array is sparse, so only check\r
+                                * non-null entries.\r
+                                */\r
+                               if (subqueryTrackingArray[index] != null)\r
+                               {\r
+                                       subqueryTrackingArray[index].cleanUp();\r
+                               }\r
+                       }\r
+               }\r
+\r
+               /* Clean up any dependencies */\r
+               if (dependencies != null)\r
+               {\r
+                       DependencyManager dmgr = lcc.getDataDictionary().getDependencyManager();\r
+\r
+                       for (Iterator iterator = dependencies.iterator(); iterator.hasNext(); ) \r
+                       {\r
+                               Dependency dy = (Dependency) iterator.next();\r
+                               dmgr.clearInMemoryDependency(dy);\r
+                       }\r
+\r
+                       dependencies = null;\r
+               }\r
+\r
+               if (severity <= ExceptionSeverity.STATEMENT_SEVERITY\r
+                       && setSavePoint)\r
+               {\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if (SanityManager.DEBUG_ON("traceSavepoints"))\r
+                               {\r
+                                       SanityManager.DEBUG_PRINT(\r
+                                               "GenericStatementContext.cleanupOnError",\r
+                                               "rolling back to: " + internalSavePointName);\r
+                               }\r
+                       }\r
+\r
+                       lcc.internalRollbackToSavepoint( internalSavePointName, false, null);\r
+\r
+                       clearSavePoint();\r
+               }\r
+\r
+               if (severity >= ExceptionSeverity.TRANSACTION_SEVERITY )\r
+               {\r
+                       // transaction severity errors roll back the transaction.\r
+\r
+                       /*\r
+                       ** We call clearSavePoint() above only for statement errors.\r
+                       ** We don't call clearSavePoint() for transaction errors because\r
+                       ** the savepoint will be rolled back anyway.  So in this case,\r
+                       ** we need to indicate that the savepoint is not set.\r
+                       */\r
+                       setSavePoint = false;\r
+               }\r
+\r
+               /* Pop the context */\r
+               lcc.popStatementContext(this, error);\r
+       }\r
+\r
+       /**\r
+        * @see Context#isLastHandler\r
+        */\r
+       public boolean isLastHandler(int severity)\r
+       {\r
+        // For JVM errors, severity gets mapped to \r
+        // ExceptionSeverity.NO_APPLICABLE_SEVERITY\r
+        // in ContextManager.cleanupOnError. It is necessary to \r
+        // let outer contexts take corrective action for jvm errors, so \r
+        // return false as this will not be the last handler for such \r
+        // errors.\r
+               return inUse && !rollbackParentContext && \r
+            ( severity == ExceptionSeverity.STATEMENT_SEVERITY );\r
+       }\r
+\r
+       /**\r
+         *     Reports whether this StatementContext is on the context stack.\r
+         *\r
+         *     @return true if this StatementContext is on the context stack. false otherwise.\r
+         */\r
+    public     boolean onStack() { return inUse; }\r
+\r
+       /**\r
+        * Indicates whether the statement needs to be executed atomically\r
+        * or not, i.e., whether a commit/rollback is permitted by a\r
+        * connection nested in this statement.\r
+        *\r
+        * @return true if needs to be atomic\r
+        */\r
+       public boolean isAtomic()\r
+       {\r
+               return isAtomic;\r
+       }\r
+\r
+       /**\r
+        * Return the text of the current statement.\r
+        * Note that this may be null.  It is currently\r
+        * not set up correctly for ResultSets that aren't\r
+        * single row result sets (e.g SELECT), replication,\r
+        * and setXXXX/getXXXX jdbc methods.\r
+        *\r
+        * @return the statement text\r
+        */\r
+       public String getStatementText()\r
+       {\r
+               return stmtText;\r
+       }\r
+\r
+       //\r
+       // class implementation\r
+       //\r
+\r
+       /**\r
+         *     Raise an exception if this Context is not in use, that is, on the\r
+         * Context Stack.\r
+         *\r
+         * @exception StandardException thrown on error.\r
+         */\r
+       private void    pleaseBeOnStack() throws StandardException\r
+       {\r
+               if ( !inUse ) { throw StandardException.newException(SQLState.LANG_DEAD_STATEMENT); }\r
+       }\r
+\r
+       public boolean inUse()\r
+       {\r
+               return inUse;\r
+       }\r
+    public boolean isForReadOnly()\r
+    {\r
+       return isForReadOnly;\r
+    }\r
+        \r
+    /**\r
+     * Tests whether the statement which has allocated this StatementContext\r
+     * object has been cancelled. This method is typically called from the\r
+     * thread which is executing the statement, to test whether execution\r
+     * should continue or stop.\r
+     *\r
+     * @return whether the statement which has allocated this StatementContext\r
+     *  object has been cancelled.\r
+     */\r
+    public boolean isCancelled()\r
+    {\r
+        return cancellationFlag;\r
+    }\r
+\r
+    /**\r
+     * Cancels the statement which has allocated this StatementContext object.\r
+     * This is done by setting a flag in the StatementContext object. For\r
+     * this to have any effect, it is the responsibility of the executing\r
+     * statement to check this flag regularly.\r
+     */\r
+    public void cancel()\r
+    {\r
+        cancellationFlag = true;\r
+    }\r
+\r
+       public void setSQLAllowed(short allow, boolean force) {\r
+\r
+               // cannot override a stricter setting.\r
+               // -1 is no routine restriction in place\r
+               // 0 is least restrictive\r
+               // 4 is most\r
+               if (force || (allow > sqlAllowed))\r
+                       sqlAllowed = allow;\r
+\r
+       }\r
+       public short getSQLAllowed() {\r
+               if (!inUse)\r
+                       return org.apache.derby.catalog.types.RoutineAliasInfo.NO_SQL;\r
+\r
+               return sqlAllowed;\r
+       }\r
+\r
+       /**\r
+        * Indicate that, in the event of a statement-level exception,\r
+        * this context is NOT the last one that needs to be rolled\r
+        * back--rather, it is nested within some other statement\r
+        * context, and that other context needs to be rolled back,\r
+        * too.\r
+       */\r
+       public void setParentRollback() {\r
+               rollbackParentContext = true;\r
+       }\r
+\r
+       /**\r
+               Set to indicate statement is system code.\r
+               For example a system procedure, view, function etc.\r
+       */\r
+       public void setSystemCode() {\r
+               isSystemCode = true;\r
+       }\r
+\r
+       /**\r
+               Return true if this statement is system code.\r
+       */\r
+       public boolean getSystemCode() {\r
+               return isSystemCode;\r
+       }\r
+\r
+       public StringBuffer appendErrorInfo() {\r
+\r
+               StringBuffer sb = ((ContextImpl) lcc).appendErrorInfo();\r
+               if (sb != null) {\r
+\r
+                       sb.append("Failed Statement is: ");\r
+\r
+                       sb.append(getStatementText());\r
+\r
+                       if ((pvs != null) && pvs.getParameterCount() > 0)\r
+                       {\r
+                               String pvsString = " with " + pvs.getParameterCount() +\r
+                                               " parameters " + pvs.toString();\r
+                               sb.append(pvsString);\r
+                       }\r
+               }\r
+               return sb;\r
+\r
+       }\r
+}\r