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

COVERAGE SUMMARY FOR SOURCE FILE [GenericPreparedStatement.java]

nameclass, %method, %block, %line, %
GenericPreparedStatement.java100% (1/1)94%  (58/62)87%  (759/877)90%  (215.2/238)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class GenericPreparedStatement100% (1/1)94%  (58/62)87%  (759/877)90%  (215.2/238)
GenericPreparedStatement (): void 100% (1/1)100% (18/18)100% (6/6)
GenericPreparedStatement (Statement): void 100% (1/1)100% (6/6)100% (3/3)
completeCompile (QueryTreeNode): void 100% (1/1)100% (52/52)100% (16/16)
execute (Activation, boolean, boolean, boolean): ResultSet 100% (1/1)98%  (174/178)98%  (39/40)
execute (LanguageConnectionContext, boolean): ResultSet 100% (1/1)100% (14/14)100% (3/3)
finish (LanguageConnectionContext): void 100% (1/1)63%  (31/49)72%  (9.4/13)
getActivation (LanguageConnectionContext, boolean): Activation 100% (1/1)69%  (24/35)67%  (6/9)
getActivationClass (): GeneratedClass 100% (1/1)100% (3/3)100% (1/1)
getBeginCompileTimestamp (): Timestamp 100% (1/1)100% (3/3)100% (1/1)
getBindTimeInMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getByteCodeSaver (): ByteArray 100% (1/1)100% (2/2)100% (1/1)
getClassType (): String 0%   (0/1)0%   (0/2)0%   (0/1)
getClone (): ExecPreparedStatement 100% (1/1)100% (76/76)100% (19/19)
getCompileTimeInMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getCompileTimeWarnings (): SQLWarning 100% (1/1)100% (3/3)100% (1/1)
getConstantAction (): ConstantAction 100% (1/1)100% (3/3)100% (1/1)
getCursorInfo (): Object 100% (1/1)100% (12/12)100% (1/1)
getDependableFinder (): DependableFinder 0%   (0/1)0%   (0/2)0%   (0/1)
getEndCompileTimestamp (): Timestamp 100% (1/1)100% (3/3)100% (1/1)
getGenerateTimeInMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getObjectID (): UUID 100% (1/1)100% (3/3)100% (1/1)
getObjectName (): String 100% (1/1)100% (3/3)100% (1/1)
getOptimizeTimeInMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getParameterTypes (): DataTypeDescriptor [] 100% (1/1)100% (3/3)100% (1/1)
getParseTimeInMillis (): long 100% (1/1)100% (3/3)100% (1/1)
getResultDescription (): ResultDescription 100% (1/1)100% (3/3)100% (1/1)
getSPSName (): String 100% (1/1)100% (3/3)100% (1/1)
getSavedObject (int): Object 100% (1/1)39%  (12/31)67%  (2/3)
getSavedObjects (): Object [] 100% (1/1)100% (3/3)100% (1/1)
getSource (): String 100% (1/1)87%  (13/15)86%  (0.9/1)
getTargetColumns (): ResultColumnDescriptor [] 0%   (0/1)0%   (0/3)0%   (0/1)
getTargetTable (): ExecCursorTableReference 100% (1/1)91%  (10/11)95%  (1.9/2)
getUpdateColumns (): String [] 100% (1/1)100% (3/3)100% (1/1)
getUpdateMode (): int 100% (1/1)100% (3/3)100% (1/1)
isAtomic (): boolean 100% (1/1)100% (3/3)100% (1/1)
isPersistent (): boolean 100% (1/1)100% (2/2)100% (1/1)
isStorable (): boolean 100% (1/1)100% (2/2)100% (1/1)
isValid (): boolean 100% (1/1)100% (3/3)100% (1/1)
makeInvalid (int, LanguageConnectionContext): void 100% (1/1)61%  (60/99)73%  (18.2/25)
makeValid (LanguageConnectionContext): void 100% (1/1)93%  (13/14)97%  (2.9/3)
needsSavepoint (): boolean 100% (1/1)100% (3/3)100% (1/1)
prepareToInvalidate (Provider, int, LanguageConnectionContext): void 100% (1/1)100% (10/10)100% (4/4)
rePrepare (LanguageConnectionContext): void 100% (1/1)100% (7/7)100% (3/3)
referencesSessionSchema (): boolean 100% (1/1)100% (3/3)100% (1/1)
referencesSessionSchema (QueryTreeNode): boolean 100% (1/1)100% (7/7)100% (2/2)
setActivationClass (GeneratedClass): void 100% (1/1)100% (4/4)100% (2/2)
setCacheHolder (Cacheable): void 100% (1/1)67%  (26/39)75%  (9/12)
setCompileTimeMillis (long, long, long, long, long, Timestamp, Timestamp): void 100% (1/1)100% (22/22)100% (8/8)
setCompileTimeWarnings (SQLWarning): void 100% (1/1)100% (4/4)100% (2/2)
setConstantAction (ConstantAction): void 100% (1/1)100% (4/4)100% (2/2)
setCursorInfo (CursorInfo): void 100% (1/1)100% (19/19)100% (6/6)
setExecuteStatementNameAndSchema (String, String): void 100% (1/1)100% (7/7)100% (3/3)
setIsAtomic (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setNeedsSavepoint (boolean): void 100% (1/1)100% (4/4)100% (2/2)
setParams (ParameterValueSet): void 100% (1/1)100% (4/4)100% (2/2)
setSPSAction (): void 100% (1/1)100% (4/4)100% (2/2)
setSPSName (String): void 100% (1/1)100% (4/4)100% (2/2)
setSavedObjects (Object []): void 100% (1/1)100% (4/4)100% (2/2)
setSource (String): void 100% (1/1)100% (4/4)100% (2/2)
setValid (): void 100% (1/1)100% (4/4)100% (2/2)
toString (): String 0%   (0/1)0%   (0/3)0%   (0/1)
upToDate (): boolean 100% (1/1)100% (30/30)100% (5/5)

1/*
2 
3   Derby - Class org.apache.derby.impl.sql.GenericPreparedStatement
4 
5   Copyright 1997, 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.impl.sql;
22 
23import        org.apache.derby.catalog.Dependable;
24import        org.apache.derby.catalog.DependableFinder;
25 
26import org.apache.derby.iapi.services.context.ContextService;
27import org.apache.derby.iapi.services.context.ContextManager;
28 
29import org.apache.derby.iapi.services.monitor.Monitor;
30 
31import org.apache.derby.iapi.services.sanity.SanityManager;
32 
33import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
34import org.apache.derby.iapi.services.cache.Cacheable;
35 
36import org.apache.derby.catalog.UUID;
37import org.apache.derby.iapi.services.uuid.UUIDFactory;
38import org.apache.derby.iapi.util.ByteArray;
39 
40import org.apache.derby.iapi.sql.dictionary.DataDictionary;
41import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
42import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
43 
44import org.apache.derby.iapi.sql.ParameterValueSet;
45import org.apache.derby.iapi.sql.PreparedStatement;
46import org.apache.derby.iapi.sql.Statement;
47import org.apache.derby.iapi.types.DataTypeDescriptor;
48import org.apache.derby.iapi.sql.ResultColumnDescriptor;
49import org.apache.derby.iapi.sql.ResultDescription;
50import org.apache.derby.iapi.sql.ResultSet;
51import org.apache.derby.iapi.sql.Activation;
52 
53import org.apache.derby.iapi.sql.execute.ConstantAction;
54import org.apache.derby.iapi.sql.execute.ExecCursorTableReference;
55import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
56 
57import org.apache.derby.iapi.sql.depend.DependencyManager;
58import org.apache.derby.iapi.sql.depend.Provider;
59 
60import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
61import org.apache.derby.iapi.sql.conn.StatementContext;
62 
63import org.apache.derby.impl.sql.compile.QueryTreeNode;
64import org.apache.derby.impl.sql.compile.CursorNode;
65 
66import org.apache.derby.iapi.error.StandardException;
67 
68import org.apache.derby.iapi.reference.SQLState;
69 
70import org.apache.derby.iapi.services.loader.GeneratedClass;
71 
72import java.sql.Timestamp;
73import java.sql.SQLWarning;
74import java.util.List;
75 
76/**
77 * Basic implementation of prepared statement.
78 * relies on implementation of ResultDescription and Statement that
79 * are also in this package.
80 * <p>
81 * These are both dependents (of the schema objects and prepared statements
82 * they depend on) and providers.  Prepared statements that are providers
83 * are cursors that end up being used in positioned delete and update
84 * statements (at present).
85 * <p>
86 * This is impl with the regular prepared statements; they will never
87 * have the cursor info fields set.
88 * <p>
89 * Stored prepared statements extend this implementation
90 *
91 * @author ames
92 */
93public class GenericPreparedStatement
94        implements ExecPreparedStatement
95{
96        ///////////////////////////////////////////////
97        //
98        // WARNING: when adding members to this class, be
99        // sure to do the right thing in getClone(): if
100        // it is PreparedStatement specific like finished,
101        // then it shouldn't be copied, but stuff like parameters 
102        // must be copied.        
103        //
104        ////////////////////////////////////////////////
105 
106        ////////////////////////////////////////////////
107        // STATE that is copied by getClone()
108        ////////////////////////////////////////////////
109        public Statement statement;
110        protected GeneratedClass activationClass; // satisfies Activation
111        protected ResultDescription resultDesc;
112        protected DataTypeDescriptor[] paramTypeDescriptors;
113        private String                        spsName;
114        private SQLWarning                warnings;
115 
116        //If the query node for this statement references SESSION schema tables, mark it so in the boolean below
117        //This information will be used by EXECUTE STATEMENT if it is executing a statement that was created with NOCOMPILE. Because
118        //of NOCOMPILE, we could not catch SESSION schema table reference by the statement at CREATE STATEMENT time. Need to catch
119        //such statements at EXECUTE STATEMENT time when the query is getting compiled.
120        //This information will also be used to decide if the statement should be cached or not. Any statement referencing SESSION
121        //schema tables will not be cached.
122        private boolean                referencesSessionSchema;
123 
124        // fields used for cursors
125        protected ExecCursorTableReference        targetTable; 
126        protected ResultColumnDescriptor[]        targetColumns; 
127        protected String[]                                         updateColumns; 
128        protected int                                                 updateMode;
129 
130        protected ConstantAction        executionConstants;
131        protected Object[]        savedObjects;
132        protected List requiredPermissionsList;
133 
134        // fields for dependency tracking
135        protected String UUIDString;
136        protected UUID   UUIDValue;
137 
138        private boolean needsSavepoint;
139 
140        private String execStmtName;
141        private String execSchemaName;
142        protected boolean isAtomic;
143        protected String sourceTxt;
144 
145        private int inUseCount;
146 
147        // true if the statement is being compiled.
148        boolean compilingStatement;
149 
150 
151        ////////////////////////////////////////////////
152        // STATE that is not copied by getClone()
153        ////////////////////////////////////////////////
154        // fields for run time stats
155        protected long parseTime;
156        protected long bindTime;
157        protected long optimizeTime;
158        protected long generateTime;
159        protected long compileTime;
160        protected Timestamp beginCompileTimestamp;
161        protected Timestamp endCompileTimestamp;
162 
163        //private boolean finished;
164        protected boolean isValid;
165        protected boolean spsAction;
166 
167        // state for caching.
168        /**
169                If non-null then this object is the cacheable
170                that holds us in the cache.
171        */
172        private Cacheable cacheHolder;
173 
174        //
175        // constructors
176        //
177 
178        GenericPreparedStatement() {
179                /* Get the UUID for this prepared statement */
180                UUIDFactory uuidFactory = 
181                        Monitor.getMonitor().getUUIDFactory();
182 
183                UUIDValue = uuidFactory.createUUID();
184                UUIDString = UUIDValue.toString();
185                spsAction = false;
186        }
187 
188        /**
189         */
190        public GenericPreparedStatement(Statement st)
191        {
192                this();
193 
194                statement = st;
195        }
196 
197        //
198        // PreparedStatement interface
199        //
200        public synchronized boolean        upToDate()
201                throws StandardException
202        {
203                return  isValid && (activationClass != null) && !compilingStatement;
204        }
205 
206        public void rePrepare(LanguageConnectionContext lcc) 
207                throws StandardException {
208                if (!upToDate())
209                    makeValid(lcc);
210        }
211 
212        /**
213         * Get a new activation instance.
214         *
215         * @exception StandardException thrown if finished.
216         */
217        public synchronized Activation        getActivation(LanguageConnectionContext lcc, boolean scrollable) throws StandardException 
218        {
219                GeneratedClass gc = getActivationClass();
220 
221                if (gc == null) {
222                        rePrepare(lcc);
223                        gc = getActivationClass();
224                }
225 
226                Activation ac = new GenericActivationHolder(lcc, gc, this, scrollable);
227 
228                inUseCount++;
229 
230                return ac;
231        }
232 
233    public ResultSet execute(LanguageConnectionContext lcc,
234                             boolean rollbackParentContext,
235                             long timeoutMillis)
236                throws StandardException
237        {
238                Activation a = getActivation(lcc, false);
239                a.setSingleExecution();
240                return execute(a, rollbackParentContext, timeoutMillis);
241        }
242 
243        /**
244          *        The guts of execution.
245          *
246          *        @param        activation                                        the activation to run.
247          * @param rollbackParentContext True if 1) the statement context is
248          *  NOT a top-level context, AND 2) in the event of a statement-level
249          *         exception, the parent context needs to be rolled back, too.
250      * @param timeoutMillis timeout value in milliseconds.
251          *        @return        the result set to be pawed through
252          *
253          *        @exception        StandardException thrown on error
254          */
255 
256    public ResultSet execute(Activation activation,
257                             boolean rollbackParentContext,
258                             long timeoutMillis)
259        throws
260            StandardException 
261        {
262                boolean                                needToClearSavePoint = false;
263 
264                if (activation == null || activation.getPreparedStatement() != this)
265                {
266                        throw StandardException.newException(SQLState.LANG_WRONG_ACTIVATION, "execute");
267                }
268 
269recompileOutOfDatePlan:
270                while (true) {
271                        // verify the activation is for me--somehow.  NOTE: This is
272                        // different from the above check for whether the activation is
273                        // associated with the right PreparedStatement - it's conceivable
274                        // that someone could construct an activation of the wrong type
275                        // that points to the right PreparedStatement.
276                        //
277                        //SanityManager.ASSERT(activation instanceof activationClass, "executing wrong activation");
278 
279                        /* This is where we set and clear savepoints around each individual
280                         * statement which needs one.  We don't set savepoints for cursors because
281                         * they're not needed and they wouldn't work in a read only database.
282                         * We can't set savepoints for commit/rollback because they'll get
283                         * blown away before we try to clear them.
284                         */
285 
286                        LanguageConnectionContext lccToUse = activation.getLanguageConnectionContext();
287 
288                         if (lccToUse.getLogStatementText())
289                        {
290                                HeaderPrintWriter istream = Monitor.getStream();
291                                String xactId = lccToUse.getTransactionExecute().getActiveStateTxIdString();
292                                String pvsString = "";
293                                ParameterValueSet pvs = activation.getParameterValueSet();
294                                if (pvs != null && pvs.getParameterCount() > 0)
295                                {
296                                        pvsString = " with " + pvs.getParameterCount() +
297                                                        " parameters " + pvs.toString();
298                                }
299                                istream.printlnWithHeader(LanguageConnectionContext.xidStr + 
300                                                                                  xactId + 
301                                                                                  "), " +
302                                                                                  LanguageConnectionContext.lccStr +
303                                                                                  lccToUse.getInstanceNumber() +
304                                                                                  "), " +
305                                                                                  LanguageConnectionContext.dbnameStr +
306                                                                                  lccToUse.getDbname() +
307                                                                                  "), " +
308                                                                                  LanguageConnectionContext.drdaStr +
309                                                                                  lccToUse.getDrdaID() +
310                                                                                  "), Executing prepared statement: " +
311                                                                                  getSource() +
312                                                                                  " :End prepared statement" +
313                                                                                  pvsString);
314                        }
315 
316                        ParameterValueSet pvs = activation.getParameterValueSet();
317 
318                        /* put it in try block to unlock the PS in any case
319                         */
320                        if (!spsAction) {
321                        // only re-prepare if this isn't an SPS for a trigger-action;
322                        // if it _is_ an SPS for a trigger action, then we can't just
323                        // do a regular prepare because the statement might contain
324                        // internal SQL that isn't allowed in other statements (such as a
325                        // static method call to get the trigger context for retrieval
326                        // of "new row" or "old row" values).  So in that case we
327                        // skip the call to 'rePrepare' and if the statement is out
328                        // of date, we'll get a NEEDS_COMPILE exception when we try
329                        // to execute.  That exception will be caught by the executeSPS()
330                        // method of the GenericTriggerExecutor class, and at that time
331                        // the SPS action will be recompiled correctly.
332                                rePrepare(lccToUse);
333                        }
334 
335                        StatementContext statementContext = lccToUse.pushStatementContext(
336                                isAtomic, updateMode==CursorNode.READ_ONLY, getSource(), pvs, rollbackParentContext, timeoutMillis);
337 
338                        if (needsSavepoint())
339                        {
340                                /* Mark this position in the log so that a statement
341                                * rollback will undo any changes.
342                                */
343                                statementContext.setSavePoint();
344                                needToClearSavePoint = true;
345                        }
346 
347                        if (executionConstants != null)
348                        {
349                                lccToUse.validateStmtExecution(executionConstants);
350                        }
351 
352                        ResultSet resultSet = null;
353                        try {
354        
355                                resultSet = activation.execute();
356 
357                                resultSet.open();
358                        } catch (StandardException se) {
359                                /* Cann't handle recompiling SPS action recompile here */
360                                if (!se.getMessageId().equals(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE)
361                                                 || spsAction)
362                                        throw se;
363                                statementContext.cleanupOnError(se);
364                                continue recompileOutOfDatePlan;
365 
366                        }
367 
368 
369                        if (needToClearSavePoint)
370                        {
371                                /* We're done with our updates */
372                                statementContext.clearSavePoint();
373                        }
374 
375                        lccToUse.popStatementContext(statementContext, null);                                        
376 
377                        if (activation.isSingleExecution() && resultSet.isClosed())
378                        {
379                                // if the result set is 'done', i.e. not openable,
380                                // then we can also release the activation.
381                                // Note that a result set with output parameters 
382                                // or rows to return is explicitly finished 
383                                // by the user.
384                                activation.close();
385                        }
386 
387                        return resultSet;
388                        
389                }
390        }
391 
392        public ResultDescription        getResultDescription()        {
393                return resultDesc;
394        }
395 
396        public DataTypeDescriptor[]        getParameterTypes()        {
397                return paramTypeDescriptors;
398        }
399 
400        public String getSource() {
401                return (sourceTxt != null) ?
402                        sourceTxt : 
403                        (statement == null) ? 
404                                "null" : 
405                                statement.getSource();
406        }
407 
408        public void setSource(String text)
409        {
410                sourceTxt = text;
411        }
412 
413        public final void setSPSName(String name) {
414                spsName = name;
415        }
416 
417        public String getSPSName() {
418                return spsName;
419        }
420 
421 
422        /**
423         * Get the total compile time for the associated query in milliseconds.
424         * Compile time can be divided into parse, bind, optimize and generate times.
425         * 
426         * @return long                The total compile time for the associated query in milliseconds.
427         */
428        public long getCompileTimeInMillis()
429        {
430                return compileTime;
431        }
432 
433        /**
434         * Get the parse time for the associated query in milliseconds.
435         * 
436         * @return long                The parse time for the associated query in milliseconds.
437         */
438        public long getParseTimeInMillis()
439        {
440                return parseTime;
441        }
442 
443        /**
444         * Get the bind time for the associated query in milliseconds.
445         * 
446         * @return long                The bind time for the associated query in milliseconds.
447         */
448        public long getBindTimeInMillis()
449        {
450                return bindTime;
451        }
452 
453        /**
454         * Get the optimize time for the associated query in milliseconds.
455         * 
456         * @return long                The optimize time for the associated query in milliseconds.
457         */
458        public long getOptimizeTimeInMillis()
459        {
460                return optimizeTime;
461        }
462 
463        /**
464         * Get the generate time for the associated query in milliseconds.
465         * 
466         * @return long                The generate time for the associated query in milliseconds.
467         */
468        public long getGenerateTimeInMillis()
469        {
470                return generateTime;
471        }
472 
473        /**
474         * Get the timestamp for the beginning of compilation
475         *
476         * @return Timestamp        The timestamp for the beginning of compilation.
477         */
478        public Timestamp getBeginCompileTimestamp()
479        {
480                return beginCompileTimestamp;
481        }
482 
483        /**
484         * Get the timestamp for the end of compilation
485         *
486         * @return Timestamp        The timestamp for the end of compilation.
487         */
488        public Timestamp getEndCompileTimestamp()
489        {
490                return endCompileTimestamp;
491        }
492 
493        void setCompileTimeWarnings(SQLWarning warnings) {
494                this.warnings = warnings;
495        }
496 
497        public final SQLWarning getCompileTimeWarnings() {
498                return warnings;
499        }
500 
501        /**
502         * Set the compile time for this prepared statement.
503         *
504         * @param compileTime        The compile time
505         */
506        protected void setCompileTimeMillis(long parseTime, long bindTime,
507                                                                                long optimizeTime, 
508                                                                                long generateTime,
509                                                                                long compileTime,
510                                                                                Timestamp beginCompileTimestamp,
511                                                                                Timestamp endCompileTimestamp)
512        {
513                this.parseTime = parseTime;
514                this.bindTime = bindTime;
515                this.optimizeTime = optimizeTime;
516                this.generateTime = generateTime;
517                this.compileTime = compileTime;
518                this.beginCompileTimestamp = beginCompileTimestamp;
519                this.endCompileTimestamp = endCompileTimestamp;
520        }
521 
522 
523        /**
524                Finish marks a statement as totally unusable.
525         */
526        public void finish(LanguageConnectionContext lcc) {
527 
528                synchronized (this) {
529                        inUseCount--;
530 
531                        if (cacheHolder != null)
532                                return;
533 
534                        if (inUseCount != 0) {
535                                //if (SanityManager.DEBUG) {
536                                //        if (inUseCount < 0)
537                                //                SanityManager.THROWASSERT("inUseCount is negative " + inUseCount + " for " + this);
538                                //}
539                                return; 
540                        }
541                }
542                        
543                // invalidate any prepared statements that
544                // depended on this statement (including this one)
545                // prepareToInvalidate(this, DependencyManager.PREPARED_STATEMENT_INVALID);
546                try
547                {
548                        /* NOTE: Since we are non-persistent, we "know" that no exception
549                         * will be thrown under us.
550                         */
551                        makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
552                }
553                catch (StandardException se)
554                {
555                        if (SanityManager.DEBUG)
556                        {
557                                se.printStackTrace(System.out);
558                                SanityManager.THROWASSERT(
559                                        "Unexpected exception - " + se);
560                        }
561                }
562        }
563 
564        /**
565         *        Set the Execution constants. This routine is called as we Prepare the
566         *        statement.
567         *
568         *        @param constantAction The big structure enclosing the Execution constants.
569         */
570        final void        setConstantAction( ConstantAction constantAction )
571        {
572                executionConstants = constantAction;
573        }
574 
575 
576        /**
577         *        Get the Execution constants. This routine is called at Execution time.
578         *
579         *        @return        ConstantAction        The big structure enclosing the Execution constants.
580         */
581        public        final ConstantAction        getConstantAction()
582        {
583                return        executionConstants;
584        }
585 
586        /**
587         *        Set the saved objects. Called when compilation completes.
588         *
589         *        @param        objects        The objects to save from compilation
590         */
591        final void        setSavedObjects( Object[] objects )
592        {
593                savedObjects = objects;
594        }
595 
596        /**
597         *        Get the specified saved object.
598         *
599         *        @param        objectNum        The object to get.
600         *        @return        the requested saved object.
601         */
602        public final Object        getSavedObject(int objectNum)
603        {
604                if (SanityManager.DEBUG) {
605                        if (!(objectNum>=0 && objectNum<savedObjects.length))
606                        SanityManager.THROWASSERT(
607                                "request for savedObject entry "+objectNum+" invalid; "+
608                                "savedObjects has "+savedObjects.length+" entries");
609                }
610                return        savedObjects[objectNum];
611        }
612 
613        /**
614         *        Get the saved objects.
615         *
616         *        @return all the saved objects
617         */
618        public        final Object[]        getSavedObjects()
619        {
620                return        savedObjects;
621        }
622 
623        //
624        // Dependent interface
625        //
626        /**
627                Check that all of the dependent's dependencies are valid.
628 
629                @return true if the dependent is currently valid
630         */
631        public boolean isValid() {
632                return isValid;
633        }
634 
635        /**
636         * set this prepared statement to be valid, currently used by
637         * GenericTriggerExecutor.
638         */
639        public void setValid()
640        {
641                isValid = true;
642        }
643 
644        /**
645         * Indicate this prepared statement is an SPS action, currently used
646         * by GenericTriggerExecutor.
647         */
648        public void setSPSAction()
649        {
650                spsAction = true;
651        }
652 
653        /**
654                Prepare to mark the dependent as invalid (due to at least one of
655                its dependencies being invalid).
656 
657                @param        action        The action causing the invalidation
658                @param        p                the provider
659 
660                @exception StandardException thrown if unable to make it invalid
661         */
662        public void prepareToInvalidate(Provider p, int action, 
663                                                                        LanguageConnectionContext lcc) 
664                throws StandardException {
665 
666                /*
667                        this statement can have other open result sets
668                        if another one is closing without any problems.
669 
670                        It is not a problem to create an index when there is an open
671                        result set, since it doesn't invalidate the access path that was
672                        chosen for the result set.
673                */
674                switch (action) {
675                case DependencyManager.CHANGED_CURSOR:
676                case DependencyManager.CREATE_INDEX:
677                        return;
678                }
679 
680                /* Verify that there are no activations with open result sets
681                 * on this prepared statement.
682                 */
683                lcc.verifyNoOpenResultSets(this, p, action);
684        }
685 
686 
687        /**
688                Mark the dependent as invalid (due to at least one of
689                its dependencies being invalid).
690 
691                @param        action        The action causing the invalidation
692 
693                 @exception StandardException Standard Cloudscape error policy.
694         */
695        public void makeInvalid(int action, LanguageConnectionContext lcc)
696                 throws StandardException
697        {
698 
699                boolean alreadyInvalid;
700                
701                synchronized (this) {
702 
703                        if (compilingStatement)
704                                return;
705 
706                        alreadyInvalid = !isValid;
707                
708                        // make ourseleves invalid
709                        isValid = false;
710 
711                        // block compiles while we are invalidating
712                        compilingStatement = true;
713                }
714 
715                try {
716 
717                        DependencyManager dm = lcc.getDataDictionary().getDependencyManager();
718 
719                        if (!alreadyInvalid)
720                        {
721                                dm.invalidateFor(this, action, lcc);
722                        }
723 
724                        /* Clear out the old dependencies on this statement as we
725                         * will build the new set during the reprepare in makeValid().
726                         */
727                        dm.clearDependencies(lcc, this);
728 
729                        /*
730                        ** If we are invalidating an EXECUTE STATEMENT because of a stale
731                        ** plan, we also need to invalidate the stored prepared statement.
732                        */
733                        if (execStmtName != null) {
734                                switch (action) {
735                                case DependencyManager.INTERNAL_RECOMPILE_REQUEST:
736                                case DependencyManager.CHANGED_CURSOR:
737                                {
738                                        /*
739                                        ** Get the DataDictionary, so we can get the descriptor for
740                                        ** the SPP to invalidate it.
741                                        */
742                                        DataDictionary dd = lcc.getDataDictionary();
743                                                
744                                        SchemaDescriptor sd = dd.getSchemaDescriptor(execSchemaName, lcc.getTransactionCompile(), true);
745                                        SPSDescriptor spsd = dd.getSPSDescriptor(execStmtName, sd);
746                                        spsd.makeInvalid(action, lcc);
747                                        break;
748                                }
749                                }
750                        }
751                } finally {
752                        synchronized (this) {
753                                compilingStatement = false;
754                                notifyAll();
755                        }
756                }
757        }
758 
759        /**
760                Attempt to revalidate the dependent. For prepared statements,
761                this could go through its dependencies and check that they
762                are up to date; if not, it would recompile the statement.
763                Any failure during this attempt should throw
764                StandardException.unableToRevalidate().
765 
766                @exception StandardException thrown if unable to make it valid
767         */
768        public void makeValid(LanguageConnectionContext lcc) 
769                throws StandardException 
770        {
771                PreparedStatement ps;
772 
773                // REMIND: will want to go through dependency list
774                // and check if we can make it valid just on faith,
775                // i.e. when it was marked 'possibly invalid' due
776                // to a rollback or some similar action.
777 
778                // this ends up calling makeValid(qt, ac) below:
779                ps = statement.prepare(lcc);
780                if (SanityManager.DEBUG)
781                        SanityManager.ASSERT(ps == this, "ps != this");
782        }
783 
784        /**
785         * Is this dependent persistent?  A stored dependency will be required
786         * if both the dependent and provider are persistent.
787         *
788         * @return boolean                Whether or not this dependent is persistent.
789         */
790        public boolean isPersistent()
791        {
792                /* Non-stored prepared statements are not persistent */
793                return false;
794        }
795 
796        //
797        // Dependable interface
798        //
799 
800        /**                
801                @return the stored form of this Dependable
802 
803                @see Dependable#getDependableFinder
804         */
805        public DependableFinder getDependableFinder()
806        {
807            return null;
808        }
809 
810        /**
811         * Return the name of this Dependable.  (Useful for errors.)
812         *
813         * @return String        The name of this Dependable..
814         */
815        public String getObjectName()
816        {
817                return UUIDString;
818        }
819 
820        /**
821         * Get the Dependable's UUID String.
822         *
823         * @return String        The Dependable's UUID String.
824         */
825        public UUID getObjectID()
826        {
827                return UUIDValue;
828        }
829 
830        /**
831         * Get the Dependable's class type.
832         *
833         * @return String                Classname that this Dependable belongs to.
834         */
835        public String getClassType()
836        {
837                return Dependable.PREPARED_STATEMENT;
838        }
839 
840        /**
841         * Return true if the query node for this statement references SESSION schema
842         * tables/views.
843         * This method gets called at the very beginning of the compile phase of any statement.
844         * If the statement which needs to be compiled is already found in cache, then there is
845         * no need to compile it again except the case when the statement is referencing SESSION
846         * schema objects. There is a small window where such a statement might get cached 
847         * temporarily (a statement referencing SESSION schema object will be removed from the
848         * cache after the bind phase is over because that is when we know for sure that the 
849         * statement is referencing SESSION schema objects.)
850         *
851         * @return        true if references SESSION schema tables, else false
852         */
853        public boolean referencesSessionSchema()
854        {
855                return referencesSessionSchema;
856        }
857        
858        /**
859         * Return true if the QueryTreeNode references SESSION schema tables/views.
860         * The return value is also saved in the local field because it will be 
861         * used by referencesSessionSchema() method. 
862         * This method gets called when the statement is not found in cache and 
863         * hence it is getting compiled.
864         * At the beginning of compilation for any statement, first we check if
865         * the statement's plan already exist in the cache. If not, then we add
866         * the statement to the cache and continue with the parsing and binding.
867         * At the end of the binding, this method gets called to see if the 
868         * QueryTreeNode references a SESSION schema object. If it does, then
869         * we want to remove it from the cache, since any statements referencing
870         * SESSION schema objects should never get cached.  
871         *
872         * @return        true if references SESSION schema tables/views, else false
873         */
874        public boolean referencesSessionSchema(QueryTreeNode qt)
875        throws StandardException {
876                //If the query references a SESSION schema table (temporary or permanent), then
877                // mark so in this statement
878                referencesSessionSchema = qt.referencesSessionSchema();
879                return(referencesSessionSchema);
880        }
881 
882        //
883        // class interface
884        //
885 
886        /**
887                Makes the prepared statement valid, assigning
888                values for its query tree, generated class,
889                and associated information.
890 
891                @param qt the query tree for this statement
892 
893                @exception StandardException thrown on failure.
894         */
895        void completeCompile(QueryTreeNode qt)
896                                                throws StandardException {
897                //if (finished)
898                //        throw StandardException.newException(SQLState.LANG_STATEMENT_CLOSED, "completeCompile()");
899 
900                paramTypeDescriptors = qt.getParameterTypes();
901 
902                // erase cursor info in case statement text changed
903                if (targetTable!=null) {
904                        targetTable = null;
905                        updateMode = 0;
906                        updateColumns = null;
907                        targetColumns = null;
908                }
909 
910                // get the result description (null for non-cursor statements)
911                // would we want to reuse an old resultDesc?
912                // or do we need to always replace in case this was select *?
913                resultDesc = qt.makeResultDescription();
914 
915                // would look at resultDesc.getStatementType() but it
916                // doesn't call out cursors as such, so we check
917                // the root node type instead.
918 
919                if (resultDesc != null)
920                {
921                        /*
922                                For cursors, we carry around some extra information.
923                         */
924                        CursorInfo cursorInfo = (CursorInfo)qt.getCursorInfo();
925                        if (cursorInfo != null)
926                        {
927                                targetTable = cursorInfo.targetTable;
928                                targetColumns = cursorInfo.targetColumns;
929                                updateColumns = cursorInfo.updateColumns;
930                                updateMode = cursorInfo.updateMode;
931                        }
932                }
933                isValid = true;
934 
935                return;
936        }
937 
938        public GeneratedClass getActivationClass()
939                throws StandardException
940        {
941                return activationClass;
942        }
943 
944        void setActivationClass(GeneratedClass ac)
945        {
946                activationClass = ac;
947        }
948 
949        //
950        // ExecPreparedStatement
951        //
952 
953        /**
954         * the update mode of the cursor
955         *
956         * @return        The update mode of the cursor
957         */
958        public int        getUpdateMode() {
959                return updateMode;
960        }
961 
962        /**
963         * the target table of the cursor
964         *
965         * @return        target table of the cursor
966         */
967        public ExecCursorTableReference getTargetTable() 
968        {
969                if (SanityManager.DEBUG)
970                {
971                        SanityManager.ASSERT(targetTable!=null, "Not a cursor, no target table");
972                }
973                return targetTable;
974        }
975 
976        /**
977         * the target columns of the cursor as a result column list
978         *
979         * @return        target columns of the cursor as a result column list
980         */
981        public ResultColumnDescriptor[]        getTargetColumns() {
982                return targetColumns;
983        }
984 
985        /**
986         * the update columns of the cursor as a update column list
987         *
988         * @return        update columns of the cursor as a array of strings
989         */
990        public String[]        getUpdateColumns() 
991        {
992                return updateColumns;
993        }
994 
995        /**
996         * Return the cursor info in a single chunk.  Used
997         * by StrorablePreparedStatement
998         */
999        public Object getCursorInfo()
1000        {
1001                return new CursorInfo(
1002                        updateMode,
1003                        targetTable, 
1004                        targetColumns,
1005                        updateColumns);
1006        }
1007 
1008        void setCursorInfo(CursorInfo cursorInfo)
1009        {
1010                if (cursorInfo != null)
1011                {
1012                        updateMode = cursorInfo.updateMode;
1013                        targetTable = cursorInfo.targetTable;
1014                        targetColumns = cursorInfo.targetColumns;
1015                        updateColumns = cursorInfo.updateColumns;
1016                }
1017        }
1018 
1019 
1020        //
1021        // class implementation
1022        //
1023 
1024        /**
1025         * Get the byte code saver for this statement.
1026         * Overridden for StorablePreparedStatement.  We
1027         * don't want to save anything
1028         *
1029         * @return a byte code saver (null for us)
1030         */
1031        ByteArray getByteCodeSaver()
1032        {
1033                return null;
1034        }
1035 
1036        /**
1037         * Does this statement need a savepoint?  
1038         * 
1039         * @return true if this statement needs a savepoint.
1040         */
1041        public boolean needsSavepoint()
1042        {
1043                return needsSavepoint;
1044        }
1045 
1046        /**
1047         * Set the stmts 'needsSavepoint' state.  Used
1048         * by an SPS to convey whether the underlying stmt
1049         * needs a savepoint or not.
1050         * 
1051         * @param needsSavepoint true if this statement needs a savepoint.
1052         */
1053        void setNeedsSavepoint(boolean needsSavepoint)
1054        {
1055                 this.needsSavepoint = needsSavepoint;
1056        }
1057 
1058        /**
1059         * Set the stmts 'isAtomic' state.  
1060         * 
1061         * @param isAtomic true if this statement must be atomic
1062         * (i.e. it is not ok to do a commit/rollback in the middle)
1063         */
1064        void setIsAtomic(boolean isAtomic)
1065        {
1066                 this.isAtomic = isAtomic;
1067        }
1068 
1069        /**
1070         * Returns whether or not this Statement requires should
1071         * behave atomically -- i.e. whether a user is permitted
1072         * to do a commit/rollback during the execution of this
1073         * statement.
1074         *
1075         * @return boolean        Whether or not this Statement is atomic
1076         */
1077        public boolean isAtomic()
1078        {
1079                return isAtomic;
1080        }
1081 
1082        /**
1083         * Set the name of the statement and schema for an "execute statement"
1084         * command.
1085         */
1086        void setExecuteStatementNameAndSchema(String execStmtName,
1087                                                                                                 String execSchemaName)
1088        {
1089                this.execStmtName = execStmtName;
1090                this.execSchemaName = execSchemaName;
1091        }
1092 
1093        /**
1094         * Get a new prepared statement that is a shallow copy
1095         * of the current one.
1096         *
1097         * @return a new prepared statement
1098         * 
1099         * @exception StandardException on error
1100         */
1101        public ExecPreparedStatement getClone() throws StandardException
1102        {
1103 
1104                GenericPreparedStatement clone = new GenericPreparedStatement(statement);
1105 
1106                clone.activationClass = getActivationClass();
1107                clone.resultDesc = resultDesc;
1108                clone.paramTypeDescriptors = paramTypeDescriptors;
1109                clone.executionConstants = executionConstants;
1110                clone.UUIDString = UUIDString;
1111                clone.UUIDValue = UUIDValue;
1112                clone.savedObjects = savedObjects;
1113                clone.execStmtName = execStmtName;
1114                clone.execSchemaName = execSchemaName;
1115                clone.isAtomic = isAtomic;
1116                clone.sourceTxt = sourceTxt;
1117                clone.targetTable = targetTable;
1118                clone.targetColumns = targetColumns;
1119                clone.updateColumns = updateColumns;
1120                clone.updateMode = updateMode;        
1121                clone.needsSavepoint = needsSavepoint;
1122 
1123                return clone;
1124        }
1125 
1126        // cache holder stuff.
1127        public void setCacheHolder(Cacheable cacheHolder) {
1128 
1129                this.cacheHolder = cacheHolder;
1130 
1131                if (cacheHolder == null) {
1132 
1133                        // need to invalidate the statement
1134                        if (!isValid || (inUseCount != 0))
1135                                return;
1136 
1137                        ContextManager cm = ContextService.getFactory().getCurrentContextManager();
1138                        LanguageConnectionContext lcc = 
1139                                (LanguageConnectionContext) 
1140                                (cm.getContext(LanguageConnectionContext.CONTEXT_ID));
1141 
1142                        // invalidate any prepared statements that
1143                        // depended on this statement (including this one)
1144                        // prepareToInvalidate(this, DependencyManager.PREPARED_STATEMENT_INVALID);
1145                        try
1146                        {
1147                                /* NOTE: Since we are non-persistent, we "know" that no exception
1148                                 * will be thrown under us.
1149                                 */
1150                                makeInvalid(DependencyManager.PREPARED_STATEMENT_RELEASE, lcc);
1151                        }
1152                        catch (StandardException se)
1153                        {
1154                                if (SanityManager.DEBUG)
1155                                {
1156                                        se.printStackTrace(System.out);
1157                                        SanityManager.THROWASSERT(
1158                                                "Unexpected exception - " + se);
1159                                }
1160                        }
1161                }
1162        }
1163 
1164        public String toString() {
1165                return getObjectName();
1166        }
1167 
1168        public boolean isStorable() {
1169                return false;
1170        }
1171 
1172        public void setRequiredPermissionsList( List requiredPermissionsList)
1173        {
1174                this.requiredPermissionsList = requiredPermissionsList;
1175        }
1176 
1177        public List getRequiredPermissionsList()
1178        {
1179                return requiredPermissionsList;
1180        }
1181}

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