EMMA Coverage Report (generated Wed Jun 28 22:15:27 PDT 2006)
[all classes][org.apache.derby.iapi.sql.dictionary]

COVERAGE SUMMARY FOR SOURCE FILE [SPSDescriptor.java]

nameclass, %method, %block, %line, %
SPSDescriptor.java100% (1/1)80%  (33/41)74%  (498/669)78%  (133.4/170)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class SPSDescriptor100% (1/1)80%  (33/41)74%  (498/669)78%  (133.4/170)
SPSDescriptor (DataDictionary, String, UUID, UUID, UUID, char, boolean, Strin... 100% (1/1)100% (18/18)100% (3/3)
SPSDescriptor (DataDictionary, String, UUID, UUID, UUID, char, boolean, Strin... 100% (1/1)100% (40/40)100% (13/13)
compileStatement (LanguageConnectionContext, TableDescriptor): void 100% (1/1)90%  (112/125)92%  (23/25)
getClassType (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getCompSchemaId (): UUID 100% (1/1)100% (3/3)100% (1/1)
getCompileTime (): Timestamp 100% (1/1)100% (3/3)100% (1/1)
getDependableFinder (): DependableFinder 100% (1/1)100% (4/4)100% (1/1)
getDescriptorName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getDescriptorType (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getName (): String 100% (1/1)100% (3/3)100% (1/1)
getObjectID (): UUID 100% (1/1)100% (3/3)100% (1/1)
getObjectName (): String 0%   (0/1)0%   (0/3)0%   (0/1)
getParameterDefaults (): Object [] 100% (1/1)100% (9/9)100% (3/3)
getParams (): DataTypeDescriptor [] 100% (1/1)82%  (36/44)86%  (7.8/9)
getPreparedStatement (): ExecPreparedStatement 100% (1/1)100% (4/4)100% (1/1)
getPreparedStatement (boolean): ExecPreparedStatement 100% (1/1)61%  (48/79)52%  (12.9/25)
getQualifiedName (): String 100% (1/1)100% (14/14)100% (1/1)
getSchemaDescriptor (): SchemaDescriptor 100% (1/1)100% (3/3)100% (1/1)
getText (): String 100% (1/1)100% (3/3)100% (1/1)
getType (): char 100% (1/1)100% (3/3)100% (1/1)
getTypeAsString (): String 100% (1/1)100% (13/13)100% (3/3)
getUUID (): UUID 100% (1/1)100% (3/3)100% (1/1)
getUsingText (): String 100% (1/1)100% (3/3)100% (1/1)
initiallyCompilable (): boolean 100% (1/1)100% (3/3)100% (1/1)
isValid (): boolean 100% (1/1)100% (3/3)100% (1/1)
loadGeneratedClass (): void 100% (1/1)100% (8/8)100% (3/3)
makeInvalid (int, LanguageConnectionContext): void 100% (1/1)56%  (27/48)67%  (8/12)
makeValid (LanguageConnectionContext): void 0%   (0/1)0%   (0/13)0%   (0/5)
prepareAndRelease (LanguageConnectionContext): void 100% (1/1)100% (6/6)100% (2/2)
prepareAndRelease (LanguageConnectionContext, TableDescriptor): void 100% (1/1)95%  (20/21)98%  (4.9/5)
prepareToInvalidate (Provider, int, LanguageConnectionContext): void 100% (1/1)22%  (4/18)60%  (3/5)
recreateUUID (String): UUID 100% (1/1)100% (12/12)100% (3/3)
revalidate (LanguageConnectionContext): void 100% (1/1)100% (16/16)100% (5/5)
setCompileTime (): void 100% (1/1)100% (7/7)100% (2/2)
setParameterDefaults (Object []): void 100% (1/1)100% (4/4)100% (2/2)
setParams (DataTypeDescriptor []): void 100% (1/1)100% (4/4)100% (2/2)
setUUID (UUID): void 0%   (0/1)0%   (0/4)0%   (0/2)
setUsingText (String): void 0%   (0/1)0%   (0/4)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/50)0%   (0/1)
updateSYSSTATEMENTS (LanguageConnectionContext, int, TransactionController): ... 100% (1/1)98%  (50/51)95%  (18/19)
validType (char): boolean 100% (1/1)90%  (9/10)90%  (0.9/1)

1/*
2 
3   Derby - Class org.apache.derby.iapi.sql.dictionary.SPSDescriptor
4 
5   Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable.
6 
7   Licensed under the Apache License, Version 2.0 (the "License");
8   you may not use this file except in compliance with the License.
9   You may obtain a copy of the License at
10 
11      http://www.apache.org/licenses/LICENSE-2.0
12 
13   Unless required by applicable law or agreed to in writing, software
14   distributed under the License is distributed on an "AS IS" BASIS,
15   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   See the License for the specific language governing permissions and
17   limitations under the License.
18 
19 */
20 
21package org.apache.derby.iapi.sql.dictionary;
22 
23import org.apache.derby.iapi.services.io.StoredFormatIds;
24 
25import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
26import org.apache.derby.iapi.sql.conn.LanguageConnectionFactory;
27import org.apache.derby.iapi.sql.conn.StatementContext;
28 
29import org.apache.derby.iapi.store.access.TransactionController;
30 
31import org.apache.derby.iapi.sql.dictionary.DataDictionary;
32import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
33import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
34 
35import org.apache.derby.iapi.sql.execute.ConstantAction;
36import org.apache.derby.iapi.sql.execute.ExecutionContext;
37 
38import org.apache.derby.iapi.sql.compile.CompilerContext;
39 
40import org.apache.derby.iapi.types.DataTypeDescriptor;
41import org.apache.derby.iapi.sql.Statement;
42import org.apache.derby.iapi.sql.StorablePreparedStatement;
43 
44import org.apache.derby.iapi.error.StandardException;
45import org.apache.derby.iapi.reference.SQLState;
46 
47import org.apache.derby.iapi.services.context.ContextManager;
48import org.apache.derby.iapi.services.loader.ClassFactory;
49import org.apache.derby.iapi.services.context.ContextService;
50import org.apache.derby.iapi.services.monitor.Monitor;
51 
52import org.apache.derby.iapi.sql.depend.DependencyManager;
53import org.apache.derby.iapi.sql.depend.Dependent;
54import org.apache.derby.iapi.sql.depend.Dependency;
55import org.apache.derby.iapi.sql.depend.Provider;
56import org.apache.derby.iapi.sql.depend.ProviderInfo;
57 
58import org.apache.derby.iapi.types.DataValueFactory;
59 
60import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
61 
62import org.apache.derby.iapi.services.sanity.SanityManager;
63import org.apache.derby.iapi.services.loader.GeneratedClass;
64 
65import org.apache.derby.catalog.UUID;
66import org.apache.derby.catalog.Dependable;
67import org.apache.derby.catalog.DependableFinder;
68import org.apache.derby.iapi.services.uuid.UUIDFactory;
69 
70import java.util.Enumeration;
71import java.util.Vector;
72import java.sql.Timestamp;
73 
74/**
75 * A SPSDescriptor describes a Stored Prepared Statement.
76 * It correlates to a row in SYS.SYSSTATEMENTS.
77 *
78 * <B>SYNCHRONIZATION</B>: Stored prepared statements
79 * may be cached.  Thus they may be shared by multiple
80 * threads.  It is very hard for two threads to try
81 * to muck with an sps simultaeously because all ddl
82 * (including sps recompilation) clears out the sps
83 * cache and invalidates whatever statement held a
84 * cached sps.  But it is possible for two statements
85 * to do a prepare execute statment <x> at the exact
86 * same time, so both try to do an sps.prepare() at the 
87 * same time during code generation, so we synchronize
88 * most everything except getters on immutable objects
89 * just to be on the safe side.
90 *
91 *
92 * @author jamie
93 */
94public class SPSDescriptor extends TupleDescriptor
95        implements UniqueSQLObjectDescriptor, Dependent, Provider
96{
97        /**
98         * Statement types.  
99         * <UL>
100         * <LI> SPS_TYPE_TRIGGER        - trigger (<B>NOT IMPLEMENTED</B>) </LI>
101         * <LI> SPS_TYPE_EXPLAIN        - explain (<B>NOT IMPLEMENTED</B>) </LI>
102         * <LI> SPS_TYPE_REGULAR        - catchall</LI>
103         * </UL>
104         */
105        public static final char SPS_TYPE_TRIGGER        = 'T';
106        public static final char SPS_TYPE_REGULAR        = 'S';
107        public static final char SPS_TYPE_EXPLAIN        = 'X';
108 
109        /**
110           interface to this class is:
111           <ol>
112           <li>public void prepare() throws StandardException;
113           <li>public void prepareAndRelease(LanguageConnectionContext lcc) 
114           throws StandardException;
115           <li>public void prepareAndRelease(...);
116           <li>public String        getQualifiedName();
117           <li>public char        getType();
118           <li>public String getTypeAsString();
119           <li>public boolean isValid();
120           <li>public boolean initiallyCompilable();
121           <li>public java.sql.Timestamp getCompileTime();
122           <li>public void setCompileTime();
123           <li>public String getText();
124           <li>public String getUsingText();
125           <li>public void setUsingText(String usingText);
126           <li>public void        setUUID(UUID uuid);
127           <li>public DataTypeDescriptor[] getParams() throws StandardException;
128           <li>public void setParams(DataTypeDescriptor[] params);
129           <li>Object[] getParameterDefaults()        throws StandardException;
130           <li>void setParameterDefaults(Object[] values);
131           <li>public UUID getCompSchemaId();
132           <li>public ExecPreparedStatement getPreparedStatement()
133           throws StandardException;
134           <li>public ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid)
135           throws StandardException;
136           <li>public void revalidate(LanguageConnectionContext lcc)
137                        throws StandardException;
138                        </ol>
139        */
140 
141        private static final int RECOMPILE = 1;
142        private static final int INVALIDATE = 0;
143 
144                
145        // Class contents
146        private SchemaDescriptor                sd;
147        private String                                        name;
148        private UUID                                        uuid;
149        private UUID                                        compSchemaId;
150        private char                                        type;
151        private        boolean                                        valid;
152        private        String                                        text;
153        private        String                                        usingText;
154        private        ExecPreparedStatement        preparedStatement;
155        private        DataTypeDescriptor                params[];
156        private        Timestamp                                compileTime;
157        private        Object                                        paramDefaults[];
158        private        boolean                                        initiallyCompilable;
159        private        boolean                                        lookedUpParams;
160        
161        private UUIDFactory                                uuidFactory;
162 
163 
164        // constructors
165        /**
166         * Constructor for a SPS Descriptor
167         *
168         * @param dataDictionary                The data dictionary that this descriptor lives in
169         * @param         name         the SPS name
170         * @param         uuid        the UUID
171         * @param         suuid        the schema UUID
172         * @param         compSchemaUUID        the schema UUID at compilation time
173         * @param        type        type
174         * @param         valid        is the sps valid
175         * @param         text        the text for this statement
176         * @param         usingText        the text for the USING clause supplied to
177         *                                        CREATE or ALTER STATEMENT
178         * @param        paramDefaults        default values for the parameters (if
179         *                                        any) in this statement.  Generated by a USING
180         *                                        clause, for use by the optimizer.
181         * @param        initiallyCompilable        is the statement initially compilable?
182         *
183         * @exception StandardException on error
184         */
185        public SPSDescriptor
186                                (DataDictionary                dataDictionary,
187                                String                                name,
188                                   UUID                                uuid,
189                                   UUID                                suuid,
190                                UUID                                compSchemaUUID,
191                                char                                type,
192                                   boolean                                valid,
193                                   String                                text,
194                                String                                usingText,
195                                Object[]                        paramDefaults,
196                                boolean                                initiallyCompilable ) throws StandardException
197        {
198                this( dataDictionary, name, uuid, suuid, compSchemaUUID, type, valid, text, usingText, null, null, initiallyCompilable );
199                this.paramDefaults = paramDefaults;
200        }
201 
202        /**
203         * Constructor for a SPS Descriptor.  Used when
204         * constructing an SPS descriptor from a row
205         * in SYSSTATEMENTS.
206         *
207         * @param        dataDictionary                The data dictionary that this descriptor lives in
208         * @param         name         the SPS name
209         * @param         uuid        the UUID
210         * @param         suuid        the schema UUID
211         * @param         compSchemaUUID        the schema UUID at compilation time
212         * @param        type        type
213         * @param         valid        is the sps valid
214         * @param         text        the text for this statement
215         * @param         usingText        the text for the USING clause supplied to
216         *                                        CREATE or ALTER STATEMENT
217         * @param         compileTime        the time this was compiled
218         * @param         preparedStatement        the PreparedStatement
219         * @param        initiallyCompilable        is the statement initially compilable?
220         *
221         * @exception StandardException on error
222         */
223        public SPSDescriptor
224                                (DataDictionary        dataDictionary,
225                                String                name,
226                                   UUID                uuid,
227                                UUID                suuid,
228                                UUID                compSchemaUUID,
229                                char                type,
230                                   boolean                valid,
231                                   String                text,
232                                String                 usingText,
233                                   Timestamp        compileTime,
234                                   ExecPreparedStatement        preparedStatement,
235                                boolean                initiallyCompilable ) throws StandardException
236        {
237                super( dataDictionary );
238 
239                this.name = name;
240                this.uuid = uuid; 
241                this.type = type;
242                this.text = text;
243                this.usingText = usingText;
244                this.valid = valid;
245                this.compileTime = compileTime;
246                this.sd = dataDictionary.getSchemaDescriptor(suuid, null);
247                this.preparedStatement = preparedStatement;
248                this.compSchemaId = compSchemaUUID;
249                this.initiallyCompilable = initiallyCompilable;
250        }
251 
252        /**
253         * FOR TRIGGERS ONLY
254         * <p>
255         * Generate the class for this SPS and immediately
256         * release it.  This is useful for cases where we
257         * don't want to immediately execute the statement 
258         * corresponding to this sps (e.g. CREATE STATEMENT).
259          * <p>
260         * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS 
261         * with the prepared statement dependency info.
262          * 
263         * @param lcc the language connection context
264         * @param triggerTable the table descriptor to bind against.  Had
265         *         better be null if this isn't a trigger sps.
266         *
267         * @exception StandardException on error
268         */
269        public final synchronized void prepareAndRelease
270        (
271                LanguageConnectionContext        lcc, 
272                TableDescriptor                                triggerTable
273        ) throws StandardException
274        {
275                if (SanityManager.DEBUG)
276                {
277                        if (triggerTable != null)
278                        {
279                                SanityManager.ASSERT(type == SPS_TYPE_TRIGGER, "only expect a table descriptor when we have a trigger");
280                        }
281                }
282                
283                compileStatement(lcc, triggerTable);
284        
285                preparedStatement.makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
286        }
287 
288        /**
289         * Generate the class for this SPS and immediately
290         * release it.  This is useful for cases where we
291         * don't want to immediately execute the statement 
292         * corresponding to this sps (e.g. CREATE STATEMENT).
293          * <p>
294         * <I>SIDE EFFECTS</I>: will update and SYSDEPENDS 
295         * with the prepared statement dependency info.
296         *
297         * @param lcc the language connection context
298          * 
299         * @exception StandardException on error
300         */
301        public final synchronized void prepareAndRelease(LanguageConnectionContext lcc) throws StandardException
302        {
303                prepareAndRelease(lcc, (TableDescriptor)null);
304        }
305 
306        private void compileStatement
307        (
308                LanguageConnectionContext        lcc,
309                TableDescriptor                                triggerTable
310        )
311                throws StandardException
312        {
313                ContextManager cm = lcc.getContextManager();
314                DependencyManager dm;
315                ProviderInfo[] providerInfo;
316 
317                LanguageConnectionFactory        lcf = lcc.getLanguageConnectionFactory();
318 
319                DataDictionary dd = getDataDictionary();
320 
321 
322                /*
323                ** If we are a trigger, then we have to go ahead
324                ** and locate the trigger's table descriptor and
325                ** push it on the lcc.  This is expensive, but
326                ** pretty atypical since trigger actions aren't
327                ** likely to be invalidated too often.  Also, when
328                ** possible, we already have the triggerTable.
329                */
330                if (type == SPS_TYPE_TRIGGER && triggerTable == null)
331                {
332                        String uuidStr = name.substring(49);
333                        triggerTable = dd.getTableDescriptor(recreateUUID(uuidStr));
334                        if (SanityManager.DEBUG)
335                        {
336                                if (triggerTable == null)
337                                {
338                                        SanityManager.THROWASSERT("couldn't find trigger table for trigger sps "+name);
339                                }
340                        }
341                }
342 
343                if (triggerTable != null)
344                {
345                        lcc.pushTriggerTable(triggerTable);
346                }
347 
348                // stored statements always stored as unicode.
349                Statement                         stmt = lcf.getStatement(dd.getSchemaDescriptor(compSchemaId, null), text, true);
350 
351                try
352                {
353                        preparedStatement = (ExecPreparedStatement) stmt.prepareStorable(
354                                                                lcc,
355                                                                preparedStatement, 
356                                                                getParameterDefaults(),
357                                                                getSchemaDescriptor(),
358                                                                type == SPS_TYPE_TRIGGER);
359                }
360                finally
361                {
362                        if (triggerTable != null)
363                        {
364                                lcc.popTriggerTable(triggerTable);
365                        }
366                }
367 
368                //If this references a SESSION schema table (temporary or permanent), then throw an exception
369                //This is if EXECUTE STATEMENT executing a statement that was created with NOCOMPILE. Because
370                //of NOCOMPILE, we could not catch SESSION schema table reference by the statement at
371                //CREATE STATEMENT time. And hence need to catch such statements at EXECUTE STATEMENT time
372                //when the query is getting compiled.
373                if (preparedStatement.referencesSessionSchema())
374                        throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
375      
376                setCompileTime();
377                setParams(preparedStatement.getParameterTypes());
378 
379                if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade) {
380 
381                        /*
382                        ** Indicate that we are going to write the data
383                        ** dictionary.  We have probably already done this
384                        ** but it is ok to call startWriting more than once.
385                        */
386                        dd.startWriting(lcc);
387 
388                        dm = dd.getDependencyManager();
389                        /*
390                        ** Clear out all the dependencies that exist
391                        ** before we recreate them so we don't grow
392                        ** SYS.SYSDEPENDS forever.
393                        */
394                        dm.clearDependencies(lcc, this);
395 
396                        /*
397                        ** Copy over all the dependencies to me
398                        */
399                        dm.copyDependencies(preparedStatement,         // from
400                                                                                        this,         // to
401                                                                                        false,        // persistent only
402                                                                                        cm);
403                }
404 
405                // mark it as valid
406                valid = true;
407        }
408 
409        /**
410         * Gets the name of the sps.
411         *
412         * @return        A String containing the name of the statement.
413         */
414        public final String        getName()
415        {
416                return name;
417        }
418 
419        /**
420         * Gets the full, qualified name of the statement.
421         *
422         * @return        A String containing the name of the statement.
423         */
424        public final String        getQualifiedName()
425        {
426                return sd.getSchemaName() + "." + name;
427        }
428 
429        /**
430         * Gets the SchemaDescriptor for this SPS Descriptor.
431         *
432         * @return SchemaDescriptor        The SchemaDescriptor.
433         */
434        public final SchemaDescriptor getSchemaDescriptor()
435        {
436                return sd;
437        }
438 
439        /**
440         * Gets an identifier telling what type of table this is.
441         * Types match final ints in this interface.  Currently
442         * returns SPS_TYPE_REGULAR or SPS_TYPE_TRIGGER.
443         *
444         * @return        An identifier telling what type of statement
445          * we are.
446         */
447        public final char getType()
448        {
449                return type;
450        }        
451 
452        /**
453         * Simple little helper function to convert your type
454         * to a string, which is easier to use.
455         *
456         * @return type as a string
457         */        
458        public final String getTypeAsString()
459        {
460                char[] charArray = new char[1];
461                charArray[0] = type;
462                return new String(charArray);
463        }
464 
465        /**
466         * Is the statement initially compilable?  
467         *
468         * @return        false if statement was created with the NOCOMPILE flag
469         *                        true otherwise
470         */
471        public boolean initiallyCompilable() { return initiallyCompilable; }
472        
473        /**
474         * Validate the type. <B>NOTE</B>: Only SPS_TYPE_REGULAR
475         * and SPS_TYPE_TRIGGER are currently valid.
476         *
477         * @param type the type
478         *
479         * @return true/false        
480         */
481        public final static boolean validType(char type)
482        {
483                return (type == SPSDescriptor.SPS_TYPE_REGULAR) || 
484                                (type == SPSDescriptor.SPS_TYPE_TRIGGER);
485        }
486 
487        /**
488         * The time this prepared statement was compiled
489         *
490         * @return the time this class was last compiled
491         */
492        public final synchronized Timestamp getCompileTime()
493        {
494                return compileTime;
495        }
496 
497        /**
498         * Set the compile time to now
499         *
500         */
501        public final synchronized void setCompileTime()
502        {
503                compileTime = new Timestamp(System.currentTimeMillis());
504        }
505         
506        /**
507         * Get the text used to create this statement.
508         * Returns original text in a cleartext string.
509         *
510         * @return The text
511         */
512        public final String getText()
513        {
514                return text;
515        }
516 
517        /**
518         * Get the text of the USING clause used on CREATE
519         * or ALTER statement.
520         *
521         * @return The text
522         */
523        public final synchronized String getUsingText()
524        {
525                return usingText;
526        }
527 
528        /**
529         * Set the text of the USING clause. Used by
530         * ALTER statement.
531         *
532         * @param usingText        the new value for the USING text
533         */
534        public final synchronized void setUsingText(String usingText)
535        {
536                this.usingText = usingText;
537        }
538 
539        /**
540         * Sets the UUID of the SPS.
541         *
542         * @param uuid        The UUID of the SPS to be set in the descriptor
543         */
544        public final synchronized void setUUID(UUID uuid)
545        {
546                this.uuid = uuid;
547        }
548 
549        /**
550         * Gets the UUID of the SPS.
551         *
552         * @return        the uuid
553         */
554        public final UUID        getUUID()
555        {
556                return uuid;
557        }
558        
559        /**
560         * Get the array of date type descriptors for
561         * this statement.  Currently, we do a lookup
562         * if we don't already have the parameters saved.
563         * When SPSes are cached, the parameters should
564         * be set up when the sps is constructed.
565         *
566         * @return the array of data type descriptors
567         *
568         * @exception StandardException on error
569         */
570        public final synchronized DataTypeDescriptor[] getParams()
571                throws StandardException
572        {
573                if (params == null && !lookedUpParams)
574                {
575                        Vector v = new Vector();
576                        params = getDataDictionary().getSPSParams(this, v);
577                        paramDefaults = new Object[v.size()];        
578                        Enumeration iterator = v.elements();
579                        for (int i = 0; iterator.hasMoreElements(); i++)
580                        {
581                                paramDefaults[i] = iterator.nextElement();
582                        }
583 
584                        lookedUpParams = true;
585                }
586 
587                return params;
588        }
589 
590        /**
591         * Set the list of parameters for this statement
592         *
593         * @param params        the parameter list
594         */
595        public final synchronized void setParams(DataTypeDescriptor params[])
596        {
597                this.params = params;
598        }
599 
600        /**
601         * Get the default parameter values for this 
602         * statement.  Default parameter values are
603         * supplied by a USING clause on either a
604         * CREATE or ALTER STATEMENT statement.
605         *
606         * @return the default parameter values
607          *
608         * @exception StandardException on error
609         */
610        public final synchronized Object[] getParameterDefaults()
611                throws StandardException
612        {
613                if (paramDefaults == null)
614                        getParams();
615 
616                return paramDefaults;
617        }
618 
619        /**
620         * Set the parameter defaults for this statement.
621         *
622         * @param values        the parameter defaults
623         */
624        public final synchronized void setParameterDefaults(Object[] values)
625        {
626                this.paramDefaults = values;
627        }
628        
629        /**
630         * Get the constant action for this statement
631         *
632         * @return the constant action
633         */
634        //public final synchronized ConstantAction getConstantAction()
635        //{
636        //        return preparedStatement.getConstantAction();
637        //}
638        
639        /**
640         * Get the preparedStatement for this statement.
641         * If stmt is invalid or hasn't been compiled yet,
642         * it will be recompiled.
643         *
644         * @return the preparedStatement
645          *
646         * @exception StandardException on error
647         */
648        public final ExecPreparedStatement getPreparedStatement()
649                throws StandardException
650        {
651                return getPreparedStatement(true);
652        }
653 
654        /**
655         * Get the preparedStatement for this statement.
656         * Expects the prepared statement to have already
657         * been added to SYS.SYSSTATEMENTS.
658         * <p>
659         * Side Effects: will update SYS.SYSSTATEMENTS with
660         * the new plan if it needs to be recompiled.
661         *
662         * @param recompIfInvalid if false, never recompile even
663         *        if statement is invalid
664         *
665         * @return the preparedStatement
666          *
667         * @exception StandardException on error
668         */
669        public final synchronized ExecPreparedStatement getPreparedStatement(boolean recompIfInvalid)
670                throws StandardException
671        {
672                //System.out.println("preparedStatement = " + preparedStatement);
673                /*
674                ** Recompile if we are invalid, we don't have
675                ** a prepared statement, or the statements activation
676                ** has been cleared and cannot be reconstituted.
677                */
678                if (recompIfInvalid &&
679                        (!valid ||
680                         (preparedStatement == null)))
681                {
682                        ContextManager cm = ContextService.getFactory().getCurrentContextManager();
683 
684                        /*
685                        ** Find the language connection context.  Get
686                        ** it each time in case a connection is dropped.
687                        */
688                        LanguageConnectionContext lcc = (LanguageConnectionContext)
689                                        cm.getContext(LanguageConnectionContext.CONTEXT_ID);
690                        prepareAndRelease(lcc);
691 
692 
693                        if (!((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) (lcc.getDataDictionary())).readOnlyUpgrade) {
694 
695                                //bug 4821 - First try compiling on a nested transaction so we can release
696                                //the locks after the compilation. But if we get lock time out on the
697                                //nested transaction, then go ahead and do the compilation on the user
698                                //transaction. When doing the compilation on user transaction, the locks
699                                //acquired for recompilation will be released at the end of the user transaction.
700                                TransactionController nestedTC;
701                                try
702                                {
703                                        nestedTC = lcc.getTransactionCompile().startNestedUserTransaction(false);
704                                }
705                                catch (StandardException se)
706                                {
707                                        // If I cannot start a Nested User Transaction use the parent
708                                        // transaction to do all the work.
709                                        nestedTC = null;
710                                }
711 
712                                try
713                                {
714                                        updateSYSSTATEMENTS(lcc, RECOMPILE, nestedTC);
715                                }
716                                catch (StandardException se)
717                                {
718                                        if (se.getMessageId().equals(SQLState.LOCK_TIMEOUT))
719                                        {
720                                                if (nestedTC != null)
721                                                {
722                                                nestedTC.commit();
723                                                nestedTC.destroy();
724                                                nestedTC = null;
725                                                }
726                                                // if we couldn't do this with a nested xaction, retry with
727                                                // parent-- we need to wait this time!
728                                                updateSYSSTATEMENTS(lcc, RECOMPILE, null);
729                                        }
730                                        else throw se;
731                                }
732                                finally
733                                {
734                                        // no matter what, commit the nested transaction; if something
735                                        // bad happened in the child xaction lets not abort the parent
736                                        // here.
737                                        if (nestedTC != null)
738                                        {
739                                                nestedTC.commit();
740                                                nestedTC.destroy();
741                                        }
742                                } 
743                        }
744                }
745 
746                return preparedStatement;
747        }
748 
749        /**
750         * Get the compilation type schema id when this view
751         * was first bound.
752         *
753         * @return the schema UUID
754         */
755        public final UUID getCompSchemaId()
756        {
757                return compSchemaId;
758        }
759 
760        /**
761         * Prints the contents of the TableDescriptor
762         *
763         * @return The contents as a String
764         */
765        public final String toString()
766        {
767                if (SanityManager.DEBUG)
768                {
769                        return "SPSDescriptor:\n"+
770                                "\tname: "+sd.getSchemaName()+"."+name+"\n"+
771                                "\tuuid: "+uuid+"\n"+
772                                "\ttext: "+text+"\n"+
773                                "\tvalid: "+((valid) ? "TRUE" : "FALSE")+"\n" +
774                                "\tpreparedStatement: "+preparedStatement+"\n";
775                }
776                else
777                {
778                        return "";
779                }
780        }
781 
782        //////////////////////////////////////////////////////
783        //
784        // PROVIDER INTERFACE
785        //
786        //////////////////////////////////////////////////////
787 
788        /**                
789         * Return the stored form of this provider
790         *
791         * @see Dependable#getDependableFinder
792         */
793        public final DependableFinder getDependableFinder()
794        {
795            return        getDependableFinder(StoredFormatIds.SPS_DESCRIPTOR_FINDER_V01_ID);
796        }
797 
798        /**
799         * Return the name of this Provider.  (Useful for errors.)
800         *
801         * @return String        The name of this provider.
802         */
803        public final String getObjectName()
804        {
805                return name;
806        }
807 
808        /**
809         * Get the provider's UUID 
810         *
811         * @return String        The provider's UUID
812         */
813        public final UUID getObjectID()
814        {
815                return uuid;
816        }
817 
818        /**
819         * Get the provider's type.
820         *
821         * @return String The provider's type.
822         */
823        public final String getClassType()
824        {
825                return Dependable.STORED_PREPARED_STATEMENT;
826        }
827 
828        //////////////////////////////////////////////////////
829        //
830        // DEPENDENT INTERFACE
831        //
832        //////////////////////////////////////////////////////
833        /**
834         * Check that all of the dependent's dependencies are valid.
835         *
836         * @return true if the dependent is currently valid
837         */
838        public final synchronized boolean isValid()
839        {
840                return valid;
841        }
842 
843        /**
844         * Prepare to mark the dependent as invalid (due to at least one of
845         * its dependencies being invalid).
846         *
847         * @param action        The action causing the invalidation
848         * @param p                the provider
849         *
850         * @exception StandardException thrown if unable to make it invalid
851         */
852        public final synchronized void prepareToInvalidate(
853                                                                        Provider p, int action,
854                                                                        LanguageConnectionContext lcc) 
855                throws StandardException
856        {
857                switch (action)
858                {
859                        /*
860                        ** Things that don't affect us
861                        */
862                    case DependencyManager.CREATE_VIEW:
863        
864                        /*
865                        ** Things that force a recompile, but are
866                        ** allowed.
867                        */
868                        case DependencyManager.CREATE_INDEX:
869                        case DependencyManager.CREATE_CONSTRAINT:
870                        case DependencyManager.DROP_CONSTRAINT:
871                        case DependencyManager.DROP_INDEX:
872                        case DependencyManager.DROP_TABLE:
873                        case DependencyManager.DROP_VIEW: 
874                        case DependencyManager.DROP_METHOD_ALIAS:
875                        case DependencyManager.DROP_SYNONYM:
876                        case DependencyManager.ALTER_TABLE:
877                        case DependencyManager.RENAME:
878                        case DependencyManager.RENAME_INDEX:
879                        case DependencyManager.PREPARED_STATEMENT_RELEASE:
880                        case DependencyManager.USER_RECOMPILE_REQUEST:
881                        case DependencyManager.CHANGED_CURSOR:
882                        case DependencyManager.BULK_INSERT:
883                        case DependencyManager.COMPRESS_TABLE:
884                        case DependencyManager.SET_CONSTRAINTS_ENABLE:
885                        case DependencyManager.SET_CONSTRAINTS_DISABLE:
886                        case DependencyManager.SET_TRIGGERS_ENABLE:
887                        case DependencyManager.SET_TRIGGERS_DISABLE:
888                        case DependencyManager.ROLLBACK:
889                        case DependencyManager.INTERNAL_RECOMPILE_REQUEST:
890                        case DependencyManager.CREATE_TRIGGER:
891                        case DependencyManager.DROP_TRIGGER:
892                        case DependencyManager.DROP_COLUMN:
893                    case DependencyManager.UPDATE_STATISTICS:
894                    case DependencyManager.DROP_STATISTICS:
895                    case DependencyManager.TRUNCATE_TABLE:
896                                break;
897 
898                        /*
899                        ** The rest are errors
900                        */
901                    default:
902 
903                                DependencyManager dm;
904 
905                                dm = getDataDictionary().getDependencyManager();
906                                throw StandardException.newException(SQLState.LANG_PROVIDER_HAS_DEPENDENT_S_P_S, 
907                                        dm.getActionString(action), 
908                                        p.getObjectName(), name);
909 
910                }
911        }
912 
913        /**
914         * Mark the dependent as invalid (due to at least one of
915         * its dependencies being invalid).
916         *
917         * @param        action        The action causing the invalidation
918         *
919         * @exception StandardException thrown if unable to make it invalid
920         */
921        public final synchronized void makeInvalid(int action,
922                                                                                           LanguageConnectionContext lcc) 
923                throws StandardException
924        {
925                DependencyManager dm;
926 
927                dm = getDataDictionary().getDependencyManager();
928 
929                switch (action)
930                {
931                        /*
932                        ** Some things that don't affect stored prepared
933                         ** statements.
934                        */
935                        case DependencyManager.PREPARED_STATEMENT_RELEASE:
936                    case DependencyManager.CREATE_VIEW:
937                                break;
938 
939                        /*
940                         ** Things that can invalidate a stored
941                        ** prepared statement.
942                        */
943                        case DependencyManager.CREATE_INDEX:
944                        case DependencyManager.CREATE_CONSTRAINT:
945                        case DependencyManager.DROP_CONSTRAINT:
946                        case DependencyManager.DROP_TABLE:
947                        case DependencyManager.DROP_INDEX:
948                        case DependencyManager.DROP_VIEW: 
949                        case DependencyManager.DROP_METHOD_ALIAS:
950                        case DependencyManager.DROP_SYNONYM:
951                        case DependencyManager.ALTER_TABLE:
952                        case DependencyManager.RENAME:
953                        case DependencyManager.RENAME_INDEX:
954                        case DependencyManager.USER_RECOMPILE_REQUEST:
955                        case DependencyManager.CHANGED_CURSOR:
956                        case DependencyManager.BULK_INSERT:
957                        case DependencyManager.COMPRESS_TABLE:
958                        case DependencyManager.SET_CONSTRAINTS_ENABLE:
959                        case DependencyManager.SET_CONSTRAINTS_DISABLE:
960                        case DependencyManager.SET_TRIGGERS_ENABLE:
961                        case DependencyManager.SET_TRIGGERS_DISABLE:
962                        case DependencyManager.ROLLBACK:
963                        case DependencyManager.INTERNAL_RECOMPILE_REQUEST:
964                        case DependencyManager.CREATE_TRIGGER:
965                        case DependencyManager.DROP_TRIGGER:
966                        case DependencyManager.DROP_COLUMN:
967                    case DependencyManager.UPDATE_STATISTICS:
968                    case DependencyManager.DROP_STATISTICS:
969                        case DependencyManager.TRUNCATE_TABLE:
970                                /*
971                                ** If we are already invalid, don't write ourselves
972                                ** out.  Just to be safe, we'll send out an invalidate
973                                ** to our dependents either way.
974                                */
975                                if (valid == true)
976                                {
977                                        valid = false;
978                                        updateSYSSTATEMENTS(lcc, INVALIDATE, null);
979                                }
980                                dm.invalidateFor(this, dm.USER_RECOMPILE_REQUEST, lcc);
981                                break;
982                        case DependencyManager.DROP_SPS:
983                                //System.out.println("SPSD " + preparedStatement);
984                                dm.clearDependencies(lcc, this);
985                                break;
986        
987                    default:
988 
989                                /* 
990                                ** We should never get here, since we can't have dangling references 
991                                */
992                                if (SanityManager.DEBUG)
993                                {
994                                        SanityManager.THROWASSERT("makeInvalid("+
995                                                dm.getActionString(action)+
996                                                ") not expected to get called; should have failed in "+
997                                                "prepareToInvalidate()");
998                                }
999                                break;
1000 
1001                }
1002 
1003        }
1004 
1005        /**
1006     * Attempt to revalidate the dependent. For prepared statements,
1007         * this could go through its dependencies and check that they
1008         * are up to date; if not, it would recompile the statement.
1009         * Any failure during this attempt should throw
1010         * StandardException.unableToRevalidate().
1011         *
1012         * @exception StandardException thrown if unable to make it valid
1013         */
1014        public final synchronized void makeValid(LanguageConnectionContext lcc) 
1015                throws StandardException
1016        {
1017                if (valid)
1018                {
1019                        return;
1020                }
1021                prepareAndRelease(lcc);
1022 
1023                updateSYSSTATEMENTS(lcc, RECOMPILE, null);
1024                
1025        }
1026 
1027        /**
1028         * Invalidate and revalidate.  The functional equivalent
1029         * of calling makeInvalid() and makeValid(), except it
1030         * is optimized.
1031         *
1032         * @exception StandardException on error
1033         */
1034        public final synchronized void revalidate(LanguageConnectionContext lcc)
1035                throws StandardException
1036        {
1037                /*
1038                ** Mark it as invalid first to ensure that
1039                ** we don't write SYSSTATEMENTS 2x.
1040                */
1041                valid = false;
1042                makeInvalid(DependencyManager.USER_RECOMPILE_REQUEST, lcc);
1043                prepareAndRelease(lcc);
1044                updateSYSSTATEMENTS(lcc, RECOMPILE, null);
1045        }
1046 
1047        /**
1048         * Load the underlying generatd class.  This is not expected
1049         * to be used outside of the datadictionary package.  It
1050         * is used for optimizing class loading for sps
1051         * cacheing.
1052         *
1053         * @exception StandardException on error
1054         */
1055        public void loadGeneratedClass() throws StandardException
1056        {
1057                /*
1058                ** On upgrade, we null out the statement body,
1059                ** so handle that here.
1060                */
1061                if (preparedStatement != null)
1062                {
1063                        ((StorablePreparedStatement)preparedStatement).loadGeneratedClass();
1064                }
1065        }
1066 
1067        /*
1068        ** Update SYSSTATEMENTS with the changed the descriptor.  
1069        ** Always done in the user XACT.
1070        ** <p>
1071        ** Ideally, the changes to SYSSTATEMENTS would be made 
1072        ** in a separate xact as the current user xact, but this
1073        ** is painful (you'ld need to get a new ContextManager
1074        ** and then push all of the usual langauge contexts
1075        ** onto it and THEN call AccessManager.getTransaction()),
1076        ** and it wont work, because the xact is in a different
1077        ** compatibility space and will self deadlock (e.g.
1078        ** in the process of call DependencyManager.makeInvalid() 
1079        ** we first did a DDdependableFinder.getDependable()
1080        ** which called DataDictionaryImpl.getSPSDescriptor()
1081        ** so we hold a lock on SYS.SYSSTATEMENTS by the
1082        ** time we get a 2nd xact and try to drop the statement).
1083        */
1084        private void updateSYSSTATEMENTS(LanguageConnectionContext lcc, int mode, TransactionController tc)
1085                throws StandardException
1086        {
1087                int[]                                         colsToUpdate;
1088                boolean                                        updateSYSCOLUMNS,  recompile;
1089                //bug 4821 - we want to wait for locks if updating sysstatements on parent transaction
1090                boolean wait = false;
1091                boolean firstCompilation = false;
1092                if (mode == RECOMPILE)
1093                {
1094                        recompile = true;
1095                        updateSYSCOLUMNS = true;
1096                        if(!initiallyCompilable)
1097                        {
1098                                firstCompilation = true;
1099                                initiallyCompilable = true;
1100                        }
1101                }
1102                else
1103                {
1104                        recompile = false;
1105                        updateSYSCOLUMNS = false;
1106                }
1107 
1108                DataDictionary dd = getDataDictionary();
1109 
1110                if (((org.apache.derby.impl.sql.catalog.DataDictionaryImpl) dd).readOnlyUpgrade)
1111                        return;
1112 
1113 
1114                /*
1115                ** Get busy time
1116                */
1117                dd.startWriting(lcc);        
1118 
1119                if (tc == null) { //bug 4821 - tc will passed null if we want to use the user transaction
1120                        tc = lcc.getTransactionExecute();
1121                        wait = true;
1122                }
1123 
1124                dd.updateSPS(this,
1125                                         tc, 
1126                                         recompile,
1127                                         updateSYSCOLUMNS,
1128                                         wait,
1129                                         firstCompilation);
1130        }
1131 
1132        /**
1133         * Get the UUID for the given string
1134         *
1135         * @param idString        the string
1136         *
1137         * @return the UUID
1138         */
1139        private UUID recreateUUID(String idString)
1140        {
1141                if (uuidFactory == null)
1142                {
1143                        uuidFactory = Monitor.getMonitor().getUUIDFactory();
1144                }
1145                return uuidFactory.recreateUUID(idString);
1146        }
1147 
1148        /** @see TupleDescriptor#getDescriptorType */
1149        public String getDescriptorType() { return "Statement"; }
1150 
1151        /** @see TupleDescriptor#getDescriptorName */
1152        // RESOLVE: some descriptors have getName.  some descriptors have
1153        // getTableName, getColumnName whatever! try and unify all of this to one
1154        // getDescriptorName! 
1155        public String getDescriptorName() { return name; }
1156        
1157}
1158 

[all classes][org.apache.derby.iapi.sql.dictionary]
EMMA 2.0.5312 (C) Vladimir Roubtsov