Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / derby-10.3.2.1 / java / engine / org / apache / derby / iapi / sql / dictionary / SPSDescriptor.java
diff --git a/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java b/JMCR-Stable/real-world application/derby-10.3.2.1/java/engine/org/apache/derby/iapi/sql/dictionary/SPSDescriptor.java
new file mode 100644 (file)
index 0000000..d9f4d0a
--- /dev/null
@@ -0,0 +1,1138 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.iapi.sql.dictionary.SPSDescriptor\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.iapi.sql.dictionary;\r
+\r
+import java.sql.Timestamp;\r
+import java.util.Enumeration;\r
+import java.util.Vector;\r
+\r
+import org.apache.derby.catalog.Dependable;\r
+import org.apache.derby.catalog.DependableFinder;\r
+import org.apache.derby.catalog.UUID;\r
+import org.apache.derby.iapi.error.StandardException;\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+import org.apache.derby.iapi.services.context.ContextService;\r
+import org.apache.derby.iapi.services.io.StoredFormatIds;\r
+import org.apache.derby.iapi.services.monitor.Monitor;\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+import org.apache.derby.iapi.services.uuid.UUIDFactory;\r
+import org.apache.derby.iapi.sql.Statement;\r
+import org.apache.derby.iapi.sql.StorablePreparedStatement;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.Dependent;\r
+import org.apache.derby.iapi.sql.depend.Provider;\r
+import org.apache.derby.iapi.sql.depend.ProviderInfo;\r
+import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;\r
+import org.apache.derby.iapi.store.access.TransactionController;\r
+import org.apache.derby.iapi.types.DataTypeDescriptor;\r
+\r
+/**\r
+ * A SPSDescriptor describes a Stored Prepared Statement.\r
+ * It correlates to a row in SYS.SYSSTATEMENTS.\r
+ *\r
+ * <B>SYNCHRONIZATION</B>: Stored prepared statements\r
+ * may be cached.  Thus they may be shared by multiple\r
+ * threads.  It is very hard for two threads to try\r
+ * to muck with an sps simultaeously because all ddl\r
+ * (including sps recompilation) clears out the sps\r
+ * cache and invalidates whatever statement held a\r
+ * cached sps.  But it is possible for two statements\r
+ * to do a prepare execute statment <x> at the exact\r
+ * same time, so both try to do an sps.prepare() at the \r
+ * same time during code generation, so we synchronize\r
+ * most everything except getters on immutable objects\r
+ * just to be on the safe side.\r
+ *\r
+ *\r
+ */\r
+public class SPSDescriptor extends TupleDescriptor\r
+       implements UniqueSQLObjectDescriptor, Dependent, Provider\r
+{\r
+       /**\r
+        * Statement types.  \r
+        * <UL>\r
+        * <LI> SPS_TYPE_TRIGGER        - trigger (<B>NOT IMPLEMENTED</B>) </LI>\r
+        * <LI> SPS_TYPE_EXPLAIN        - explain (<B>NOT IMPLEMENTED</B>) </LI>\r
+        * <LI> SPS_TYPE_REGULAR        - catchall</LI>\r
+        * </UL>\r
+        */\r
+       public static final char SPS_TYPE_TRIGGER       = 'T';\r
+       public static final char SPS_TYPE_REGULAR       = 'S';\r
+       public static final char SPS_TYPE_EXPLAIN       = 'X';\r
+\r
+       /**\r
+          interface to this class is:\r
+          <ol>\r
+          <li>public void prepare() throws StandardException;\r
+          <li>public void prepareAndRelease(LanguageConnectionContext lcc) \r
+          throws StandardException;\r
+          <li>public void prepareAndRelease(...);\r
+          <li>public String    getQualifiedName();\r
+          <li>public char      getType();\r
+          <li>public String getTypeAsString();\r
+          <li>public boolean isValid();\r
+          <li>public boolean initiallyCompilable();\r
+          <li>public java.sql.Timestamp getCompileTime();\r
+          <li>public void setCompileTime();\r
+          <li>public String getText();\r
+          <li>public String getUsingText();\r
+          <li>public void setUsingText(String usingText);\r
+          <li>public void      setUUID(UUID uuid);\r
+          <li>public DataTypeDescriptor[] getParams() throws StandardException;\r
+          <li>public void setParams(DataTypeDescriptor[] params);\r
+          <li>Object[] getParameterDefaults()  throws StandardException;\r
+          <li>void setParameterDefaults(Object[] values);\r
+          <li>public UUID getCompSchemaId();\r
+          <li>public ExecPreparedStatement getPreparedStatement()\r
+          throws StandardException;\r
+          <li>public ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid)\r
+          throws StandardException;\r
+          <li>public void revalidate(LanguageConnectionContext lcc)\r
+                       throws StandardException;\r
+                       </ol>\r
+       */\r
+\r
+       private static final int RECOMPILE = 1;\r
+       private static final int INVALIDATE = 0;\r
+\r
+               \r
+       // Class contents\r
+       private SchemaDescriptor                sd;\r
+       private String                                  name;\r
+       private UUID                                    uuid;\r
+       private UUID                                    compSchemaId;\r
+       private char                                    type;\r
+       private boolean                                 valid;\r
+       private String                                  text;\r
+       private String                                  usingText;\r
+       private ExecPreparedStatement   preparedStatement;\r
+       private DataTypeDescriptor              params[];\r
+       private Timestamp                               compileTime;\r
+       /**\r
+        * Old code - never used.\r
+        */\r
+       private Object                  paramDefaults[];\r
+       private boolean                                 initiallyCompilable;\r
+       private boolean                                 lookedUpParams;\r
+       \r
+       private UUIDFactory                             uuidFactory;\r
+\r
+\r
+       // constructors\r
+       /**\r
+        * Constructor for a SPS Descriptor\r
+        *\r
+        * @param dataDictionary                The data dictionary that this descriptor lives in\r
+        * @param       name    the SPS name\r
+        * @param       uuid    the UUID\r
+        * @param       suuid   the schema UUID\r
+        * @param       compSchemaUUID  the schema UUID at compilation time\r
+        * @param       type    type\r
+        * @param       valid   is the sps valid\r
+        * @param       text    the text for this statement\r
+        * @param       initiallyCompilable     is the statement initially compilable?\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public SPSDescriptor\r
+                               (DataDictionary         dataDictionary,\r
+                               String                          name,\r
+                               UUID                            uuid,\r
+                               UUID                            suuid,\r
+                               UUID                            compSchemaUUID,\r
+                               char                            type,\r
+                               boolean                         valid,\r
+                               String                          text,\r
+                               boolean                         initiallyCompilable ) throws StandardException\r
+       {\r
+               this( dataDictionary, name, uuid, suuid, compSchemaUUID,\r
+                               type, valid, text, (String) null, null, null, initiallyCompilable );\r
+       }\r
+\r
+       /**\r
+        * Constructor for a SPS Descriptor.  Used when\r
+        * constructing an SPS descriptor from a row\r
+        * in SYSSTATEMENTS.\r
+        *\r
+        * @param       dataDictionary          The data dictionary that this descriptor lives in\r
+        * @param       name    the SPS name\r
+        * @param       uuid    the UUID\r
+        * @param       suuid   the schema UUID\r
+        * @param       compSchemaUUID  the schema UUID at compilation time\r
+        * @param       type    type\r
+        * @param       valid   is the sps valid\r
+        * @param       text    the text for this statement\r
+        * @param       usingText       the text for the USING clause supplied to\r
+        *                                      CREATE or ALTER STATEMENT\r
+        * @param       compileTime     the time this was compiled\r
+        * @param       preparedStatement       the PreparedStatement\r
+        * @param       initiallyCompilable     is the statement initially compilable?\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public SPSDescriptor\r
+                               (DataDictionary dataDictionary,\r
+                               String          name,\r
+                               UUID            uuid,\r
+                               UUID            suuid,\r
+                               UUID            compSchemaUUID,\r
+                               char            type,\r
+                               boolean         valid,\r
+                               String          text,\r
+                               String          usingText,\r
+                               Timestamp       compileTime,\r
+                               ExecPreparedStatement   preparedStatement,\r
+                               boolean         initiallyCompilable ) throws StandardException\r
+       {\r
+               super( dataDictionary );\r
+\r
+               this.name = name;\r
+               this.uuid = uuid; \r
+               this.type = type;\r
+               this.text = text;\r
+               this.usingText = usingText;\r
+               this.valid = valid;\r
+               this.compileTime = compileTime;\r
+               this.sd = dataDictionary.getSchemaDescriptor(suuid, null);\r
+               this.preparedStatement = preparedStatement;\r
+               this.compSchemaId = compSchemaUUID;\r
+               this.initiallyCompilable = initiallyCompilable;\r
+       }\r
+\r
+       /**\r
+        * FOR TRIGGERS ONLY\r
+        * <p>\r
+        * Generate the class for this SPS and immediately\r
+        * release it.  This is useful for cases where we\r
+        * don't want to immediately execute the statement \r
+        * corresponding to this sps (e.g. CREATE STATEMENT).\r
+        * <p>\r
+        * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS \r
+        * with the prepared statement dependency info.\r
+        * \r
+        * @param lcc the language connection context\r
+        * @param triggerTable the table descriptor to bind against.  Had\r
+        *      better be null if this isn't a trigger sps.\r
+        * @param tc the transaction controller\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized void prepareAndRelease\r
+       (\r
+               LanguageConnectionContext       lcc, \r
+               TableDescriptor                         triggerTable,\r
+               TransactionController       tc\r
+       ) throws StandardException\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       if (triggerTable != null)\r
+                       {\r
+                               SanityManager.ASSERT(type == SPS_TYPE_TRIGGER, "only expect a table descriptor when we have a trigger");\r
+                       }\r
+               }\r
+               \r
+               compileStatement(lcc, triggerTable, tc);\r
+       \r
+               preparedStatement.makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);\r
+       }\r
+       \r
+       /**\r
+        * FOR TRIGGERS ONLY\r
+        * <p>\r
+        * Generate the class for this SPS and immediately\r
+        * release it.  This is useful for cases where we\r
+        * don't want to immediately execute the statement \r
+        * corresponding to this sps (e.g. CREATE STATEMENT).\r
+        * <p>\r
+        * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS \r
+        * with the prepared statement dependency info.\r
+        * \r
+        * @param lcc the language connection context\r
+        * @param triggerTable the table descriptor to bind against.  Had\r
+        *      better be null if this isn't a trigger sps.\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized void prepareAndRelease\r
+       (\r
+               LanguageConnectionContext       lcc, \r
+               TableDescriptor                         triggerTable\r
+       ) throws StandardException\r
+       {\r
+               prepareAndRelease(lcc, triggerTable, (TransactionController)null);\r
+       }\r
+\r
+       /**\r
+        * Generate the class for this SPS and immediately\r
+        * release it.  This is useful for cases where we\r
+        * don't want to immediately execute the statement \r
+        * corresponding to this sps (e.g. CREATE STATEMENT).\r
+        * <p>\r
+        * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS \r
+        * with the prepared statement dependency info.\r
+        *\r
+        * @param lcc the language connection context\r
+        * \r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized void prepareAndRelease(LanguageConnectionContext lcc) throws StandardException\r
+       {\r
+               prepareAndRelease(lcc, (TableDescriptor)null, (TransactionController)null);\r
+       }\r
+\r
+       private void compileStatement\r
+       (\r
+               LanguageConnectionContext       lcc,\r
+               TableDescriptor                         triggerTable,\r
+               TransactionController       tc\r
+       )\r
+               throws StandardException\r
+       {\r
+               ContextManager cm = lcc.getContextManager();\r
+               DependencyManager dm;\r
+               ProviderInfo[] providerInfo;\r
+\r
+               LanguageConnectionFactory       lcf = lcc.getLanguageConnectionFactory();\r
+\r
+               DataDictionary dd = getDataDictionary();\r
+\r
+\r
+               /*\r
+               ** If we are a trigger, then we have to go ahead\r
+               ** and locate the trigger's table descriptor and\r
+               ** push it on the lcc.  This is expensive, but\r
+               ** pretty atypical since trigger actions aren't\r
+               ** likely to be invalidated too often.  Also, when\r
+               ** possible, we already have the triggerTable.\r
+               */\r
+               if (type == SPS_TYPE_TRIGGER && triggerTable == null)\r
+               {\r
+                       String uuidStr = name.substring(49);\r
+                       triggerTable = dd.getTableDescriptor(recreateUUID(uuidStr));\r
+                       if (SanityManager.DEBUG)\r
+                       {\r
+                               if (triggerTable == null)\r
+                               {\r
+                                       SanityManager.THROWASSERT("couldn't find trigger table for trigger sps "+name);\r
+                               }\r
+                       }\r
+               }\r
+\r
+               if (triggerTable != null)\r
+               {\r
+                       lcc.pushTriggerTable(triggerTable);\r
+               }\r
+\r
+               // stored statements always stored as unicode.\r
+               Statement                       stmt = lcf.getStatement(dd.getSchemaDescriptor(compSchemaId, null), text, true);\r
+\r
+               try\r
+               {\r
+                       preparedStatement = (ExecPreparedStatement) stmt.prepareStorable(\r
+                                                               lcc,\r
+                                                               preparedStatement, \r
+                                                               getParameterDefaults(),\r
+                                                               getSchemaDescriptor(),\r
+                                                               type == SPS_TYPE_TRIGGER);\r
+               }\r
+               finally\r
+               {\r
+                       if (triggerTable != null)\r
+                       {\r
+                               lcc.popTriggerTable(triggerTable);\r
+                       }\r
+               }\r
+\r
+               //If this references a SESSION schema table (temporary or permanent), then throw an exception\r
+               //This is if EXECUTE STATEMENT executing a statement that was created with NOCOMPILE. Because\r
+               //of NOCOMPILE, we could not catch SESSION schema table reference by the statement at\r
+               //CREATE STATEMENT time. And hence need to catch such statements at EXECUTE STATEMENT time\r
+               //when the query is getting compiled.\r
+               if (preparedStatement.referencesSessionSchema())\r
+                       throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);\r
+      \r
+               setCompileTime();\r
+               setParams(preparedStatement.getParameterTypes());\r
+\r
+               if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade) {\r
+\r
+                       /*\r
+                       ** Indicate that we are going to write the data\r
+                       ** dictionary.  We have probably already done this\r
+                       ** but it is ok to call startWriting more than once.\r
+                       */\r
+                       dd.startWriting(lcc);\r
+\r
+                       dm = dd.getDependencyManager();\r
+                       /*\r
+                       ** Clear out all the dependencies that exist\r
+                       ** before we recreate them so we don't grow\r
+                       ** SYS.SYSDEPENDS forever.\r
+                       */\r
+                       dm.clearDependencies(lcc, this, tc);\r
+\r
+                       /*\r
+                       ** Copy over all the dependencies to me\r
+                       */\r
+                       dm.copyDependencies(preparedStatement,  // from\r
+                                                                                       this,   // to\r
+                                                                                       false,  // persistent only\r
+                                                                                       cm,\r
+                                                                                       tc);\r
+               }\r
+\r
+               // mark it as valid\r
+               valid = true;\r
+       }\r
+\r
+       /**\r
+        * Gets the name of the sps.\r
+        *\r
+        * @return      A String containing the name of the statement.\r
+        */\r
+       public final String     getName()\r
+       {\r
+               return name;\r
+       }\r
+\r
+       /**\r
+        * Gets the full, qualified name of the statement.\r
+        *\r
+        * @return      A String containing the name of the statement.\r
+        */\r
+       public final String     getQualifiedName()\r
+       {\r
+               return sd.getSchemaName() + "." + name;\r
+       }\r
+\r
+       /**\r
+        * Gets the SchemaDescriptor for this SPS Descriptor.\r
+        *\r
+        * @return SchemaDescriptor     The SchemaDescriptor.\r
+        */\r
+       public final SchemaDescriptor getSchemaDescriptor()\r
+       {\r
+               return sd;\r
+       }\r
+\r
+       /**\r
+        * Gets an identifier telling what type of table this is.\r
+        * Types match final ints in this interface.  Currently\r
+        * returns SPS_TYPE_REGULAR or SPS_TYPE_TRIGGER.\r
+        *\r
+        * @return      An identifier telling what type of statement\r
+        * we are.\r
+        */\r
+       public final char getType()\r
+       {\r
+               return type;\r
+       }       \r
+\r
+       /**\r
+        * Simple little helper function to convert your type\r
+        * to a string, which is easier to use.\r
+        *\r
+        * @return type as a string\r
+        */     \r
+       public final String getTypeAsString()\r
+       {\r
+               char[] charArray = new char[1];\r
+               charArray[0] = type;\r
+               return new String(charArray);\r
+       }\r
+\r
+       /**\r
+        * Is the statement initially compilable?  \r
+        *\r
+        * @return      false if statement was created with the NOCOMPILE flag\r
+        *                      true otherwise\r
+        */\r
+       public boolean initiallyCompilable() { return initiallyCompilable; }\r
+       \r
+       /**\r
+        * Validate the type. <B>NOTE</B>: Only SPS_TYPE_REGULAR\r
+        * and SPS_TYPE_TRIGGER are currently valid.\r
+        *\r
+        * @param type the type\r
+        *\r
+        * @return true/false   \r
+        */\r
+       public final static boolean validType(char type)\r
+       {\r
+               return (type == SPSDescriptor.SPS_TYPE_REGULAR) || \r
+                               (type == SPSDescriptor.SPS_TYPE_TRIGGER);\r
+       }\r
+\r
+       /**\r
+        * The time this prepared statement was compiled\r
+        *\r
+        * @return the time this class was last compiled\r
+        */\r
+       public final synchronized Timestamp getCompileTime()\r
+       {\r
+               return compileTime;\r
+       }\r
+\r
+       /**\r
+        * Set the compile time to now\r
+        *\r
+        */\r
+       public final synchronized void setCompileTime()\r
+       {\r
+               compileTime = new Timestamp(System.currentTimeMillis());\r
+       }\r
+        \r
+       /**\r
+        * Get the text used to create this statement.\r
+        * Returns original text in a cleartext string.\r
+        *\r
+        * @return The text\r
+        */\r
+       public final String getText()\r
+       {\r
+               return text;\r
+       }\r
+\r
+       /**\r
+        * Get the text of the USING clause used on CREATE\r
+        * or ALTER statement.\r
+        *\r
+        * @return The text\r
+        */\r
+       public final synchronized String getUsingText()\r
+       {\r
+               return usingText;\r
+       }\r
+\r
+       /**\r
+        * Sets the UUID of the SPS.\r
+        *\r
+        * @param uuid  The UUID of the SPS to be set in the descriptor\r
+        */\r
+       public final synchronized void setUUID(UUID uuid)\r
+       {\r
+               this.uuid = uuid;\r
+       }\r
+\r
+       /**\r
+        * Gets the UUID of the SPS.\r
+        *\r
+        * @return      the uuid\r
+        */\r
+       public final UUID       getUUID()\r
+       {\r
+               return uuid;\r
+       }\r
+       \r
+       /**\r
+        * Get the array of date type descriptors for\r
+        * this statement.  Currently, we do a lookup\r
+        * if we don't already have the parameters saved.\r
+        * When SPSes are cached, the parameters should\r
+        * be set up when the sps is constructed.\r
+        *\r
+        * @return the array of data type descriptors\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized DataTypeDescriptor[] getParams()\r
+               throws StandardException\r
+       {\r
+               if (params == null && !lookedUpParams)\r
+               {\r
+                       Vector v = new Vector();\r
+                       params = getDataDictionary().getSPSParams(this, v);\r
+                       paramDefaults = new Object[v.size()];   \r
+                       Enumeration iterator = v.elements();\r
+                       for (int i = 0; iterator.hasMoreElements(); i++)\r
+                       {\r
+                               paramDefaults[i] = iterator.nextElement();\r
+                       }\r
+\r
+                       lookedUpParams = true;\r
+               }\r
+\r
+               return params;\r
+       }\r
+\r
+       /**\r
+        * Set the list of parameters for this statement\r
+        *\r
+        * @param params        the parameter list\r
+        */\r
+       public final synchronized void setParams(DataTypeDescriptor params[])\r
+       {\r
+               this.params = params;\r
+       }\r
+\r
+       /**\r
+        * Get the default parameter values for this \r
+        * statement.  Default parameter values are\r
+        * supplied by a USING clause on either a\r
+        * CREATE or ALTER STATEMENT statement.\r
+        *\r
+        * @return the default parameter values\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized Object[] getParameterDefaults()\r
+               throws StandardException\r
+       {\r
+               if (paramDefaults == null)\r
+                       getParams();\r
+\r
+               return paramDefaults;\r
+       }\r
+\r
+       /**\r
+        * Set the parameter defaults for this statement.\r
+        *\r
+        * @param values        the parameter defaults\r
+        */\r
+       public final synchronized void setParameterDefaults(Object[] values)\r
+       {\r
+               this.paramDefaults = values;\r
+       }\r
+       \r
+       /**\r
+        * Get the constant action for this statement\r
+        *\r
+        * @return the constant action\r
+        */\r
+       //public final synchronized ConstantAction getConstantAction()\r
+       //{\r
+       //      return preparedStatement.getConstantAction();\r
+       //}\r
+       \r
+       /**\r
+        * Get the preparedStatement for this statement.\r
+        * If stmt is invalid or hasn't been compiled yet,\r
+        * it will be recompiled.\r
+        *\r
+        * @return the preparedStatement\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final ExecPreparedStatement getPreparedStatement()\r
+               throws StandardException\r
+       {\r
+               return getPreparedStatement(true);\r
+       }\r
+\r
+       /**\r
+        * Get the preparedStatement for this statement.\r
+        * Expects the prepared statement to have already\r
+        * been added to SYS.SYSSTATEMENTS.\r
+        * <p>\r
+        * Side Effects: will update SYS.SYSSTATEMENTS with\r
+        * the new plan if it needs to be recompiled.\r
+        *\r
+        * @param recompIfInvalid if false, never recompile even\r
+        *      if statement is invalid\r
+        *\r
+        * @return the preparedStatement\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid)\r
+               throws StandardException\r
+       {\r
+               //System.out.println("preparedStatement = " + preparedStatement);\r
+               /*\r
+               ** Recompile if we are invalid, we don't have\r
+               ** a prepared statement, or the statements activation\r
+               ** has been cleared and cannot be reconstituted.\r
+               */\r
+               if (recompIfInvalid &&\r
+                       (!valid ||\r
+                        (preparedStatement == null)))\r
+               {\r
+                       ContextManager cm = ContextService.getFactory().getCurrentContextManager();\r
+\r
+                       /*\r
+                       ** Find the language connection context.  Get\r
+                       ** it each time in case a connection is dropped.\r
+                       */\r
+                       LanguageConnectionContext lcc = (LanguageConnectionContext)\r
+                                       cm.getContext(LanguageConnectionContext.CONTEXT_ID);\r
+                       \r
+\r
+\r
+                       if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) (lcc.getDataDictionary())).readOnlyUpgrade) {\r
+\r
+                               //bug 4821 - First try compiling on a nested transaction so we can release\r
+                               //the locks after the compilation. But if we get lock time out on the\r
+                               //nested transaction, then go ahead and do the compilation on the user\r
+                               //transaction. When doing the compilation on user transaction, the locks\r
+                               //acquired for recompilation will be released at the end of the user transaction.\r
+                               TransactionController nestedTC;\r
+                               try\r
+                               {\r
+                                       nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false);\r
+                               }\r
+                               catch (StandardException se)\r
+                               {\r
+                                       // If I cannot start a Nested User Transaction use the parent\r
+                                       // transaction to do all the work.\r
+                                       nestedTC = null;\r
+                               }\r
+\r
+                               // DERBY-2584: If the first attempt to compile the query fails,\r
+                               // we need to reset initiallyCompilable to make sure the\r
+                               // prepared plan is fully stored to disk. Save the initial\r
+                               // value here.\r
+                               final boolean compilable = initiallyCompilable;\r
+\r
+                               try\r
+                               {\r
+                                       prepareAndRelease(lcc, null, nestedTC);\r
+                                       updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC);\r
+                               }\r
+                               catch (StandardException se)\r
+                               {\r
+                                       if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT))\r
+                                       {\r
+                                               if (nestedTC != null)\r
+                                               {\r
+                                               nestedTC.commit();\r
+                                               nestedTC.destroy();\r
+                                               nestedTC = null;\r
+                                               }\r
+                                               // if we couldn't do this with a nested xaction, retry with\r
+                                               // parent-- we need to wait this time!\r
+                                               initiallyCompilable = compilable;\r
+                                               prepareAndRelease(lcc, null, null);\r
+                                               updateSYSSTATEMENTS(lcc, RECOMPILE, null);\r
+                                       }\r
+                                       else throw se;\r
+                               }\r
+                               finally\r
+                               {\r
+                                       // no matter what, commit the nested transaction; if something\r
+                                       // bad happened in the child xaction lets not abort the parent\r
+                                       // here.\r
+                                       if (nestedTC != null)\r
+                                       {\r
+                                               nestedTC.commit();\r
+                                               nestedTC.destroy();\r
+                                       }\r
+                               } \r
+                       }\r
+               }\r
+\r
+               return preparedStatement;\r
+       }\r
+\r
+       /**\r
+        * Get the compilation type schema id when this view\r
+        * was first bound.\r
+        *\r
+        * @return the schema UUID\r
+        */\r
+       public final UUID getCompSchemaId()\r
+       {\r
+               return compSchemaId;\r
+       }\r
+\r
+       /**\r
+        * Prints the contents of the TableDescriptor\r
+        *\r
+        * @return The contents as a String\r
+        */\r
+       public final String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return "SPSDescriptor:\n"+\r
+                               "\tname: "+sd.getSchemaName()+"."+name+"\n"+\r
+                               "\tuuid: "+uuid+"\n"+\r
+                               "\ttext: "+text+"\n"+\r
+                               "\tvalid: "+((valid) ? "TRUE" : "FALSE")+"\n" +\r
+                               "\tpreparedStatement: "+preparedStatement+"\n";\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+\r
+       //////////////////////////////////////////////////////\r
+       //\r
+       // PROVIDER INTERFACE\r
+       //\r
+       //////////////////////////////////////////////////////\r
+\r
+       /**             \r
+        * Return the stored form of this provider\r
+        *\r
+        * @see Dependable#getDependableFinder\r
+        */\r
+       public final DependableFinder getDependableFinder()\r
+       {\r
+           return      getDependableFinder(StoredFormatIds.SPS_DESCRIPTOR_FINDER_V01_ID);\r
+       }\r
+\r
+       /**\r
+        * Return the name of this Provider.  (Useful for errors.)\r
+        *\r
+        * @return String       The name of this provider.\r
+        */\r
+       public final String getObjectName()\r
+       {\r
+               return name;\r
+       }\r
+\r
+       /**\r
+        * Get the provider's UUID \r
+        *\r
+        * @return String       The provider's UUID\r
+        */\r
+       public final UUID getObjectID()\r
+       {\r
+               return uuid;\r
+       }\r
+\r
+       /**\r
+        * Get the provider's type.\r
+        *\r
+        * @return String The provider's type.\r
+        */\r
+       public final String getClassType()\r
+       {\r
+               return Dependable.STORED_PREPARED_STATEMENT;\r
+       }\r
+\r
+       //////////////////////////////////////////////////////\r
+       //\r
+       // DEPENDENT INTERFACE\r
+       //\r
+       //////////////////////////////////////////////////////\r
+       /**\r
+        * Check that all of the dependent's dependencies are valid.\r
+        *\r
+        * @return true if the dependent is currently valid\r
+        */\r
+       public final synchronized boolean isValid()\r
+       {\r
+               return valid;\r
+       }\r
+\r
+       /**\r
+        * Prepare to mark the dependent as invalid (due to at least one of\r
+        * its dependencies being invalid).\r
+        *\r
+        * @param action        The action causing the invalidation\r
+        * @param p             the provider\r
+        *\r
+        * @exception StandardException thrown if unable to make it invalid\r
+        */\r
+       public final synchronized void prepareToInvalidate(\r
+                                                                       Provider p, int action,\r
+                                                                       LanguageConnectionContext lcc) \r
+               throws StandardException\r
+       {\r
+               switch (action)\r
+               {\r
+                       /*\r
+                       ** Things that don't affect us\r
+                       */\r
+                   case DependencyManager.CREATE_VIEW:\r
+       \r
+                       /*\r
+                       ** Things that force a recompile, but are\r
+                       ** allowed.\r
+                       */\r
+                       case DependencyManager.CREATE_INDEX:\r
+                       case DependencyManager.CREATE_CONSTRAINT:\r
+                       case DependencyManager.DROP_CONSTRAINT:\r
+                       case DependencyManager.DROP_INDEX:\r
+                       case DependencyManager.DROP_TABLE:\r
+                       case DependencyManager.DROP_VIEW: \r
+                       case DependencyManager.DROP_METHOD_ALIAS:\r
+                       case DependencyManager.DROP_SYNONYM:\r
+                       case DependencyManager.ALTER_TABLE:\r
+                       case DependencyManager.RENAME:\r
+                       case DependencyManager.RENAME_INDEX:\r
+                       case DependencyManager.PREPARED_STATEMENT_RELEASE:\r
+                       case DependencyManager.USER_RECOMPILE_REQUEST:\r
+                       case DependencyManager.CHANGED_CURSOR:\r
+                       case DependencyManager.BULK_INSERT:\r
+                       case DependencyManager.COMPRESS_TABLE:\r
+                       case DependencyManager.SET_CONSTRAINTS_ENABLE:\r
+                       case DependencyManager.SET_CONSTRAINTS_DISABLE:\r
+                       case DependencyManager.SET_TRIGGERS_ENABLE:\r
+                       case DependencyManager.SET_TRIGGERS_DISABLE:\r
+                       case DependencyManager.ROLLBACK:\r
+                       case DependencyManager.INTERNAL_RECOMPILE_REQUEST:\r
+                       case DependencyManager.CREATE_TRIGGER:\r
+                       case DependencyManager.DROP_TRIGGER:\r
+                       case DependencyManager.DROP_COLUMN:\r
+                       case DependencyManager.DROP_COLUMN_RESTRICT:\r
+                   case DependencyManager.UPDATE_STATISTICS:\r
+                   case DependencyManager.DROP_STATISTICS:\r
+               case DependencyManager.TRUNCATE_TABLE:\r
+                               break;\r
+\r
+                       /*\r
+                       ** The rest are errors\r
+                       */\r
+                   default:\r
+\r
+                               DependencyManager dm;\r
+\r
+                               dm = getDataDictionary().getDependencyManager();\r
+                               throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_S_P_S, \r
+                                       dm.getActionString(action), \r
+                                       p.getObjectName(), name);\r
+\r
+               }\r
+       }\r
+\r
+       /**\r
+        * Mark the dependent as invalid (due to at least one of\r
+        * its dependencies being invalid).\r
+        *\r
+        * @param       action  The action causing the invalidation\r
+        *\r
+        * @exception StandardException thrown if unable to make it invalid\r
+        */\r
+       public final synchronized void makeInvalid(int action,\r
+                                                                                          LanguageConnectionContext lcc) \r
+               throws StandardException\r
+       {\r
+               DependencyManager dm;\r
+\r
+               dm = getDataDictionary().getDependencyManager();\r
+\r
+               switch (action)\r
+               {\r
+                       /*\r
+                       ** Some things that don't affect stored prepared\r
+                       ** statements.\r
+                       */\r
+                       case DependencyManager.PREPARED_STATEMENT_RELEASE:\r
+                   case DependencyManager.CREATE_VIEW:\r
+                               break;\r
+\r
+                       /*\r
+                       ** Things that can invalidate a stored\r
+                       ** prepared statement.\r
+                       */\r
+                       case DependencyManager.CREATE_INDEX:\r
+                       case DependencyManager.CREATE_CONSTRAINT:\r
+                       case DependencyManager.DROP_CONSTRAINT:\r
+                       case DependencyManager.DROP_TABLE:\r
+                       case DependencyManager.DROP_INDEX:\r
+                       case DependencyManager.DROP_VIEW: \r
+                       case DependencyManager.DROP_METHOD_ALIAS:\r
+                       case DependencyManager.DROP_SYNONYM:\r
+                       case DependencyManager.ALTER_TABLE:\r
+                       case DependencyManager.RENAME:\r
+                       case DependencyManager.RENAME_INDEX:\r
+                       case DependencyManager.USER_RECOMPILE_REQUEST:\r
+                       case DependencyManager.CHANGED_CURSOR:\r
+                       case DependencyManager.BULK_INSERT:\r
+                       case DependencyManager.COMPRESS_TABLE:\r
+                       case DependencyManager.SET_CONSTRAINTS_ENABLE:\r
+                       case DependencyManager.SET_CONSTRAINTS_DISABLE:\r
+                       case DependencyManager.SET_TRIGGERS_ENABLE:\r
+                       case DependencyManager.SET_TRIGGERS_DISABLE:\r
+                       case DependencyManager.ROLLBACK:\r
+                       case DependencyManager.INTERNAL_RECOMPILE_REQUEST:\r
+                       case DependencyManager.CREATE_TRIGGER:\r
+                       case DependencyManager.DROP_TRIGGER:\r
+                       case DependencyManager.DROP_COLUMN:\r
+                       case DependencyManager.DROP_COLUMN_RESTRICT:\r
+                   case DependencyManager.UPDATE_STATISTICS:\r
+                   case DependencyManager.DROP_STATISTICS:\r
+                       case DependencyManager.TRUNCATE_TABLE:\r
+                               /*\r
+                               ** If we are already invalid, don't write ourselves\r
+                               ** out.  Just to be safe, we'll send out an invalidate\r
+                               ** to our dependents either way.\r
+                               */\r
+                               if (valid == true)\r
+                               {\r
+                                       valid = false;\r
+                                       updateSYSSTATEMENTS(lcc, INVALIDATE, null);\r
+                               }\r
+                               dm.invalidateFor(this, dm.USER_RECOMPILE_REQUEST, lcc);\r
+                               break;\r
+                       case DependencyManager.DROP_SPS:\r
+                               //System.out.println("SPSD " + preparedStatement);\r
+                               dm.clearDependencies(lcc, this);\r
+                               break;\r
+       \r
+                   default:\r
+\r
+                               /* \r
+                               ** We should never get here, since we can't have dangling references \r
+                               */\r
+                               if (SanityManager.DEBUG)\r
+                               {\r
+                                       SanityManager.THROWASSERT("makeInvalid("+\r
+                                               dm.getActionString(action)+\r
+                                               ") not expected to get called; should have failed in "+\r
+                                               "prepareToInvalidate()");\r
+                               }\r
+                               break;\r
+\r
+               }\r
+\r
+       }\r
+\r
+       /**\r
+        * Invalidate and revalidate.  The functional equivalent\r
+        * of calling makeInvalid() and makeValid(), except it\r
+        * is optimized.\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public final synchronized void revalidate(LanguageConnectionContext lcc)\r
+               throws StandardException\r
+       {\r
+               /*\r
+               ** Mark it as invalid first to ensure that\r
+               ** we don't write SYSSTATEMENTS 2x.\r
+               */\r
+               valid = false;\r
+               makeInvalid(DependencyManager.USER_RECOMPILE_REQUEST, lcc);\r
+               prepareAndRelease(lcc);\r
+               updateSYSSTATEMENTS(lcc, RECOMPILE, null);\r
+       }\r
+\r
+       /**\r
+        * Load the underlying generatd class.  This is not expected\r
+        * to be used outside of the datadictionary package.  It\r
+        * is used for optimizing class loading for sps\r
+        * cacheing.\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public void loadGeneratedClass() throws StandardException\r
+       {\r
+               /*\r
+               ** On upgrade, we null out the statement body,\r
+               ** so handle that here.\r
+               */\r
+               if (preparedStatement != null)\r
+               {\r
+                       ((StorablePreparedStatement)preparedStatement).loadGeneratedClass();\r
+               }\r
+       }\r
+\r
+       /*\r
+       ** Update SYSSTATEMENTS with the changed the descriptor.  \r
+       ** Always done in the user XACT.\r
+       ** <p>\r
+       ** Ideally, the changes to SYSSTATEMENTS would be made \r
+       ** in a separate xact as the current user xact, but this\r
+       ** is painful (you'ld need to get a new ContextManager\r
+       ** and then push all of the usual langauge contexts\r
+       ** onto it and THEN call AccessManager.getTransaction()),\r
+       ** and it wont work, because the xact is in a different\r
+       ** compatibility space and will self deadlock (e.g.\r
+       ** in the process of call DependencyManager.makeInvalid() \r
+       ** we first did a DDdependableFinder.getDependable()\r
+       ** which called DataDictionaryImpl.getSPSDescriptor()\r
+       ** so we hold a lock on SYS.SYSSTATEMENTS by the\r
+       ** time we get a 2nd xact and try to drop the statement).\r
+       */\r
+       private void updateSYSSTATEMENTS(LanguageConnectionContext lcc, int mode, TransactionController tc)\r
+               throws StandardException\r
+       {\r
+               int[]                                   colsToUpdate;\r
+               boolean                                 updateSYSCOLUMNS,  recompile;\r
+               //bug 4821 - we want to wait for locks if updating sysstatements on parent transaction\r
+               boolean wait = false;\r
+               boolean firstCompilation = false;\r
+               if (mode == RECOMPILE)\r
+               {\r
+                       recompile = true;\r
+                       updateSYSCOLUMNS = true;\r
+                       if(!initiallyCompilable)\r
+                       {\r
+                               firstCompilation = true;\r
+                               initiallyCompilable = true;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       recompile = false;\r
+                       updateSYSCOLUMNS = false;\r
+               }\r
+\r
+               DataDictionary dd = getDataDictionary();\r
+\r
+               if (((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade)\r
+                       return;\r
+\r
+\r
+               /*\r
+               ** Get busy time\r
+               */\r
+               dd.startWriting(lcc);   \r
+\r
+               if (tc == null) { //bug 4821 - tc will passed null if we want to use the user transaction\r
+                       tc = lcc.getTransactionExecute();\r
+                       wait = true;\r
+               }\r
+\r
+               dd.updateSPS(this,\r
+                                        tc, \r
+                                        recompile,\r
+                                        updateSYSCOLUMNS,\r
+                                        wait,\r
+                                        firstCompilation);\r
+       }\r
+\r
+       /**\r
+        * Get the UUID for the given string\r
+        *\r
+        * @param idString      the string\r
+        *\r
+        * @return the UUID\r
+        */\r
+       private UUID recreateUUID(String idString)\r
+       {\r
+               if (uuidFactory == null)\r
+               {\r
+                       uuidFactory = Monitor.getMonitor().getUUIDFactory();\r
+               }\r
+               return uuidFactory.recreateUUID(idString);\r
+       }\r
+\r
+       /** @see TupleDescriptor#getDescriptorType */\r
+       public String getDescriptorType() { return "Statement"; }\r
+\r
+       /** @see TupleDescriptor#getDescriptorName */\r
+       // RESOLVE: some descriptors have getName.  some descriptors have\r
+       // getTableName, getColumnName whatever! try and unify all of this to one\r
+       // getDescriptorName! \r
+       public String getDescriptorName() { return name; }\r
+       \r
+}\r
+\r