KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > BaseActivation


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.BaseActivation
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.sql.execute;
23
24 import org.apache.derby.iapi.services.context.ContextManager;
25 import org.apache.derby.iapi.services.context.Context;
26
27
28 import org.apache.derby.iapi.jdbc.ConnectionContext;
29
30 import org.apache.derby.iapi.sql.Activation;
31
32 import org.apache.derby.iapi.sql.execute.CursorResultSet;
33 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
34 import org.apache.derby.iapi.sql.execute.CursorActivation;
35 import org.apache.derby.iapi.sql.ResultSet;
36 import org.apache.derby.iapi.sql.execute.ExecRow;
37 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
38 import org.apache.derby.iapi.sql.ParameterValueSet;
39 import org.apache.derby.iapi.sql.ResultDescription;
40
41 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
42
43 import org.apache.derby.iapi.reference.SQLState;
44 import org.apache.derby.iapi.error.StandardException;
45
46 import org.apache.derby.iapi.sql.execute.ExecutionContext;
47 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
48 import org.apache.derby.iapi.sql.execute.ResultSetFactory;
49 import org.apache.derby.iapi.sql.execute.ConstantAction;
50
51 import org.apache.derby.iapi.types.DataValueFactory;
52 import org.apache.derby.iapi.types.DataValueDescriptor;
53 import org.apache.derby.iapi.types.NumberDataValue;
54 import org.apache.derby.iapi.types.RowLocation;
55
56 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
57 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
58 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
59 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
60
61 import org.apache.derby.iapi.sql.depend.DependencyManager;
62
63 import org.apache.derby.iapi.store.access.Qualifier;
64 import org.apache.derby.iapi.store.access.ConglomerateController;
65 import org.apache.derby.iapi.store.access.ScanController;
66 import org.apache.derby.iapi.store.access.TransactionController;
67 import org.apache.derby.iapi.types.DataTypeDescriptor;
68
69
70 import org.apache.derby.iapi.services.sanity.SanityManager;
71
72 import org.apache.derby.iapi.services.context.ContextService;
73
74 import org.apache.derby.iapi.services.loader.GeneratedClass;
75 import org.apache.derby.iapi.services.loader.GeneratedByteCode;
76 import org.apache.derby.iapi.services.loader.GeneratedMethod;
77
78 import org.apache.derby.iapi.services.loader.ClassFactory;
79 import org.apache.derby.iapi.services.monitor.Monitor;
80
81 import org.apache.derby.iapi.services.property.PropertyUtil;
82 import org.apache.derby.iapi.sql.compile.Optimizer;
83
84 import org.apache.derby.iapi.reference.Property;
85 import org.apache.derby.iapi.services.io.FormatableBitSet;
86
87 import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
88
89 import java.sql.Connection JavaDoc;
90 import java.sql.SQLException JavaDoc;
91 import java.sql.SQLWarning JavaDoc;
92
93 import java.util.ArrayList JavaDoc;
94 import java.util.Enumeration JavaDoc;
95 import java.util.Vector JavaDoc;
96 import java.util.Hashtable JavaDoc;
97 import java.util.HashSet JavaDoc;
98 import org.apache.derby.iapi.util.ReuseFactory;
99 import org.apache.derby.iapi.sql.execute.TemporaryRowHolder;
100
101 /**
102  * BaseActivation
103  * provides the fundamental support we expect all activations to have.
104  * Doesn't actually implement any of the activation interface,
105  * expects the subclasses to do that.
106  */

107 public abstract class BaseActivation implements CursorActivation, GeneratedByteCode
108
109 {
110
111     protected ResultSetFactory rsFactory;
112     protected ExecutionFactory exFactory;
113     protected DataValueFactory dvFactory;
114     protected LanguageConnectionContext lcc;
115     protected ContextManager cm;
116     protected /*private*/ ExecutionContext ec;
117
118
119     protected ExecPreparedStatement preStmt;
120     protected ResultSet resultSet;
121     protected ResultDescription resultDescription;
122     protected boolean closed;
123     private String JavaDoc cursorName;
124     
125     protected int numSubqueries;
126
127     private boolean singleExecution;
128
129     // This flag is declared volatile to ensure it is
130
// visible when it has been modified by the finalizer thread.
131
private volatile boolean inUse;
132
133     private java.sql.ResultSet JavaDoc targetVTI;
134     private SQLWarning JavaDoc warnings;
135
136     private GeneratedClass gc; // my Generated class object.
137

138     private boolean checkRowCounts;
139     private HashSet JavaDoc rowCountsCheckedThisExecution = new HashSet JavaDoc(4, 0.9f);
140
141     private static final long MAX_SQRT = (long) Math.sqrt(Long.MAX_VALUE);
142
143     // When the row count exceeds this number, we should recompile if
144
// the difference in row counts is greater than 10%. If it's less
145
// than this number, we use an entirely different technique to check
146
// for recompilation. See comments below, in informOfRowCount()
147
private static final int TEN_PERCENT_THRESHOLD = 400;
148
149     /* Performance optimization for update/delete - only
150      * open heap ConglomerateController once when doing
151      * index row to base row on search
152      */

153     private ConglomerateController updateHeapCC;
154     private ScanController indexSC;
155     private long indexConglomerateNumber = -1;
156
157     private TableDescriptor ddlTableDescriptor;
158
159     private int maxRows = -1;
160     private boolean forCreateTable;
161
162     private boolean scrollable;
163
164     private boolean resultSetHoldability;
165
166     //beetle 3865: updateable cursor using index. A way of communication
167
//between cursor activation and update activation.
168
private CursorResultSet forUpdateIndexScan;
169
170     //Following three are used for JDBC3.0 auto-generated keys feature.
171
//autoGeneratedKeysResultSetMode will be set true if at the time of statement execution,
172
//either Statement.RETURN_GENERATED_KEYS was passed or an array of (column positions or
173
//column names) was passed
174
private boolean autoGeneratedKeysResultSetMode;
175     private int[] autoGeneratedKeysColumnIndexes ;
176     private String JavaDoc[] autoGeneratedKeysColumnNames ;
177
178     //Following is the position of the session table names list in savedObjects in compiler context
179
//This is updated to be the correct value at cursor generate time if the cursor references any session table names.
180
//If the cursor does not reference any session table names, this will stay negative
181
protected int indexOfSessionTableNamesInSavedObjects = -1;
182
183     // WARNING: these fields are accessed by code generated in the
184
// ExpressionClassBuilder: don't change them unless you
185
// make the appropriate changes there.
186
protected ExecRow[] row;
187     protected ParameterValueSet pvs;
188
189     //
190
// constructors
191
//
192

193     protected BaseActivation()
194     {
195         super();
196     }
197
198     public final void initFromContext(Context context)
199         throws StandardException {
200
201         if (SanityManager.DEBUG)
202         {
203             SanityManager.ASSERT(context!=null, "NULL context passed to BaseActivation.initFromContext");
204         }
205         this.cm = context.getContextManager();
206
207         lcc = (LanguageConnectionContext) cm.getContext(LanguageConnectionContext.CONTEXT_ID);
208
209         if (SanityManager.DEBUG) {
210             if (lcc == null)
211                 SanityManager.THROWASSERT("lcc is null in activation type " + getClass());
212         }
213
214         dvFactory = lcc.getDataValueFactory();
215         if (SanityManager.DEBUG)
216         {
217             SanityManager.ASSERT(dvFactory != null,
218                                  "No data value factory in getDataValueFactory");
219         }
220
221         ec = lcc.getExecutionContext();
222
223         // look for the execution context and
224
// get our result set factory from it.
225
rsFactory = ec.getResultSetFactory();
226         if (SanityManager.DEBUG)
227         {
228             SanityManager.ASSERT(rsFactory!=null, "Unable to find ResultSetFactory");
229         }
230
231         exFactory = ec.getExecutionFactory();
232         if (SanityManager.DEBUG)
233         {
234             SanityManager.ASSERT(exFactory!=null, "Unable to find ExecutionFactory");
235         }
236
237         // mark in use
238
inUse = true;
239         
240         // add this activation to the pool for the connection.
241
lcc.addActivation(this);
242     }
243
244
245     //
246
// Activation interface
247
//
248

249     public final ExecPreparedStatement getPreparedStatement() {
250         return preStmt;
251     }
252
253     public ConstantAction getConstantAction() {
254         return preStmt.getConstantAction();
255     }
256
257
258     public final void checkStatementValidity() throws StandardException {
259
260         if (preStmt == null)
261             return;
262
263         synchronized (preStmt) {
264
265             if ((gc == preStmt.getActivationClass()) && preStmt.upToDate())
266                 return;
267         }
268
269         StandardException se = StandardException.newException(SQLState.LANG_STATEMENT_NEEDS_RECOMPILE);
270         se.setReport(StandardException.REPORT_NEVER);
271         throw se;
272     }
273
274     /**
275         Link this activation with its PreparedStatement.
276         It can be called with null to break the link with the
277         PreparedStatement.
278
279     */

280     public final void setupActivation(ExecPreparedStatement ps, boolean scrollable) {
281         preStmt = ps;
282                 
283         if (ps != null) {
284             // get the result set description
285
resultDescription = ps.getResultDescription();
286             this.scrollable = scrollable;
287             
288             // Initialize the parameter set to have allocated
289
// DataValueDescriptor objects for each parameter.
290
if (pvs != null && pvs.getParameterCount() != 0)
291                 pvs.initialize(ps.getParameterTypes());
292
293         } else {
294             resultDescription = null;
295             this.scrollable = false;
296         }
297     }
298
299     public ResultSet getResultSet() {
300         return resultSet;
301     }
302
303     public void clearResultSet() {
304         resultSet = null;
305     }
306
307     /**
308         Get the saved RowLocation.
309
310         @param itemNumber The saved item number.
311
312         @return A RowLocation template for the conglomerate
313      */

314     public RowLocation getRowLocationTemplate(int itemNumber)
315     {
316         if (SanityManager.DEBUG)
317         {
318             SanityManager.ASSERT(itemNumber >= 0,
319                 "itemNumber expected to be >= 0");
320             if (! (getPreparedStatement().getSavedObject(itemNumber) instanceof RowLocation))
321             {
322                 SanityManager.THROWASSERT(
323                     "getPreparedStatement().getSavedObject(itemNumber) expected to be " +
324                     "instance of RowLocation, not " +
325                     getPreparedStatement().getSavedObject(itemNumber).getClass().getName() +
326                     ", query is " + getPreparedStatement().getSource());
327             }
328             RowLocation rl = (RowLocation) getPreparedStatement().getSavedObject(itemNumber);
329             if (! (rl.cloneObject() instanceof RowLocation))
330             {
331                 SanityManager.THROWASSERT(
332                     "rl.cloneObject() expected to be " +
333                     "instance of RowLocation, not " +
334                     rl.getClass().getName() +
335                     ", query is " + getPreparedStatement().getSource());
336             }
337         }
338         /* We have to return a clone of the saved RowLocation due
339          * to the shared cache of SPSs.
340          */

341         return (RowLocation)
342             ((RowLocation)(getPreparedStatement().getSavedObject(itemNumber))).cloneObject();
343     }
344
345     /*
346      */

347     public ResultDescription getResultDescription() {
348         if (SanityManager.DEBUG)
349             SanityManager.ASSERT(resultDescription != null, "Must have a result description");
350             return resultDescription;
351     }
352
353     /**
354         This is a partial implementation of reset.
355         Subclasses will want to reset information
356         they are aware of, such as parameters.
357         <p>
358         All subclasses must call super.reset() and
359         then do their cleanup.
360         <p>
361         The execute call must set the resultSet field
362         to be the resultSet that it has returned.
363
364         @exception StandardException on error
365      */

366     public void reset() throws StandardException
367     {
368         // if resultset holdability after commit is false, close it
369
if (resultSet != null) {
370             if (!resultSetHoldability || !resultSet.returnsRows()) {
371                 // would really like to check if it is open,
372
// this is as close as we can approximate that.
373
resultSet.close();
374                 resultSet = null; // forget about it, prepare for next exec.
375
} else if (resultSet.returnsRows()) {
376                 resultSet.clearCurrentRow();
377             }
378         }
379         updateHeapCC = null;
380         // REMIND: do we need to get them to stop input as well?
381

382         if (!isSingleExecution())
383             clearWarnings();
384     }
385
386     /**
387         Closing an activation marks it as unusable. Any other
388         requests made on it will fail. An activation should be
389         marked closed when it is expected to not be used any longer,
390         i.e. when the connection for it is closed, or it has suffered some
391         sort of severe error.
392
393         This should also remove it from the language connection context.
394
395         @exception StandardException on error
396      */

397     public final void close() throws StandardException
398     {
399         if (! closed) {
400             
401             // markUnused();
402

403             // we finish the result set before we call reset
404
// because reset will set it to null.
405
if (resultSet != null)
406             {
407                 resultSet.finish();
408                 resultSet = null;
409             }
410
411             // we call reset so that if the actual type of "this"
412
// is a subclass of BaseActivation, its cleanup will
413
// also happen -- reset in the actual type is called,
414
// not reset in BaseActivation. Subclass reset's
415
// are supposed to call super.reset() as well.
416
reset(); // get everything related to executing released
417

418             closed = true;
419
420             LanguageConnectionContext lcc = getLanguageConnectionContext();
421
422             lcc.removeActivation(this);
423             if (preStmt != null) {
424                 preStmt.finish(lcc);
425                 preStmt = null;
426             }
427
428             try {
429                 closeActivationAction();
430             } catch (Throwable JavaDoc e) {
431                 throw StandardException.plainWrapException(e);
432             }
433
434         }
435         
436     }
437
438     /**
439         A generated class can create its own closeActivationAction
440         method to invoke special logic when the activation is closed.
441     */

442     protected void closeActivationAction() throws Exception JavaDoc {
443         // no code to be added here as generated code
444
// will not call super.closeActivationAction()
445
}
446
447     /**
448         Find out if the activation closed or not.
449         @return true if the prepared statement has been closed.
450      */

451     public boolean isClosed() {
452         return closed;
453     }
454
455     /**
456         Set this Activation for a single execution.
457
458         @see Activation#setSingleExecution
459     */

460     public void setSingleExecution() {
461         singleExecution = true;
462     }
463
464     /**
465         Returns true if this Activation is only going to be used for
466         one execution.
467
468         @see Activation#isSingleExecution
469     */

470     public boolean isSingleExecution() {
471         return singleExecution;
472     }
473
474     /**
475         Get the number of subqueries in the entire query.
476         @return int The number of subqueries in the entire query.
477      */

478     public int getNumSubqueries() {
479         return numSubqueries;
480     }
481
482     /**
483      * @see Activation#isCursorActivation
484      */

485     public boolean isCursorActivation()
486     {
487         return false;
488     }
489
490     //
491
// GeneratedByteCode interface
492
//
493

494     public final void setGC(GeneratedClass gc) {
495         this.gc = gc;
496     }
497
498     public final GeneratedClass getGC() {
499
500         if (SanityManager.DEBUG) {
501             if (gc == null)
502                 SanityManager.THROWASSERT("move code requiring GC to postConstructor() method!!");
503         }
504         return gc;
505     }
506
507     public final GeneratedMethod getMethod(String JavaDoc methodName) throws StandardException {
508
509         return getGC().getMethod(methodName);
510     }
511     public Object JavaDoc e0() throws StandardException { return null; }
512     public Object JavaDoc e1() throws StandardException { return null; }
513     public Object JavaDoc e2() throws StandardException { return null; }
514     public Object JavaDoc e3() throws StandardException { return null; }
515     public Object JavaDoc e4() throws StandardException { return null; }
516     public Object JavaDoc e5() throws StandardException { return null; }
517     public Object JavaDoc e6() throws StandardException { return null; }
518     public Object JavaDoc e7() throws StandardException { return null; }
519     public Object JavaDoc e8() throws StandardException { return null; }
520     public Object JavaDoc e9() throws StandardException { return null; }
521
522     //
523
// class interface
524
//
525

526     /**
527      * Temporary tables can be declared with ON COMMIT DELETE ROWS. But if the table has a held curosr open at
528      * commit time, data should not be deleted from the table. This method, (gets called at commit time) checks if this
529      * activation held cursor and if so, does that cursor reference the passed temp table name.
530      *
531      * @return true if this activation has held cursor and if it references the passed temp table name
532      */

533     public boolean checkIfThisActivationHasHoldCursor(String JavaDoc tableName)
534     {
535         if (!inUse)
536             return false;
537
538         if (resultSetHoldability == false) //if this activation is not held over commit, do not need to worry about it
539
return false;
540
541         if (indexOfSessionTableNamesInSavedObjects == -1) //if this activation does not refer to session schema tables, do not need to worry about it
542
return false;
543
544         /* is there an open result set? */
545         if ((resultSet != null) && !resultSet.isClosed() && resultSet.returnsRows())
546         {
547             //If we came here, it means this activation is held over commit and it reference session table names
548
//Now let's check if it referneces the passed temporary table name which has ON COMMIT DELETE ROWS defined on it.
549
return ((ArrayList JavaDoc)getPreparedStatement().getSavedObject(indexOfSessionTableNamesInSavedObjects)).contains(tableName);
550         }
551
552         return false;
553     }
554
555     /**
556        remember the cursor name
557      */

558
559     public void setCursorName(String JavaDoc cursorName)
560     {
561         if (isCursorActivation())
562             this.cursorName = cursorName;
563     }
564
565
566     /**
567       get the cursor name. For something that isn't
568       a cursor, this is used as a string name of the
569       result set for messages from things like the
570       dependency manager.
571       <p>
572       Activations that do support cursors will override
573       this.
574     */

575     public String JavaDoc getCursorName() {
576
577         return isCursorActivation() ? cursorName : null;
578     }
579
580     public void setResultSetHoldability(boolean resultSetHoldability)
581     {
582         this.resultSetHoldability = resultSetHoldability;
583     }
584
585     public boolean getResultSetHoldability()
586     {
587         return resultSetHoldability;
588     }
589
590     /** @see Activation#setAutoGeneratedKeysResultsetInfo */
591     public void setAutoGeneratedKeysResultsetInfo(int[] columnIndexes, String JavaDoc[] columnNames)
592     {
593         autoGeneratedKeysResultSetMode = true;
594         autoGeneratedKeysColumnIndexes = columnIndexes;
595         autoGeneratedKeysColumnNames = columnNames;
596     }
597
598     /** @see Activation#getAutoGeneratedKeysResultsetMode */
599     public boolean getAutoGeneratedKeysResultsetMode()
600     {
601         return autoGeneratedKeysResultSetMode;
602     }
603
604     /** @see Activation#getAutoGeneratedKeysColumnIndexes */
605     public int[] getAutoGeneratedKeysColumnIndexes()
606     {
607         return autoGeneratedKeysColumnIndexes;
608     }
609
610     /** @see Activation#getAutoGeneratedKeysColumnNames */
611     public String JavaDoc[] getAutoGeneratedKeysColumnNames()
612     {
613         return autoGeneratedKeysColumnNames;
614     }
615
616     //
617
// class implementation
618
//
619

620
621     /**
622         Used in the execute method of activations for
623         generating the result sets that they concatenate together.
624      */

625     public ResultSetFactory getResultSetFactory() {
626         return rsFactory;
627     }
628
629     /**
630         Used in activations for generating rows.
631      */

632     public ExecutionFactory getExecutionFactory() {
633         return exFactory;
634     }
635
636
637     /**
638         Used in CurrentOfResultSet to get to the target result set
639         for a cursor. Overridden by activations generated for
640         updatable cursors. Those activations capture the target
641         result set in a field in their execute() method, and then
642         return the value of that field in their version of this method.
643
644         @return null.
645      */

646     public CursorResultSet getTargetResultSet() {
647         if (SanityManager.DEBUG)
648             SanityManager.THROWASSERT("Must be overridden to be used.");
649         return null;
650     }
651
652     /*
653      * Called by generated code to compute the next autoincrement value.
654      *
655      * @return The next autoincrement value which should be inserted.
656      * returns the correct number datatype.
657      */

658     protected DataValueDescriptor
659         getSetAutoincrementValue(int columnPosition, long increment)
660            throws StandardException
661     {
662         DataValueDescriptor l =
663             ((InsertResultSet)resultSet).getSetAutoincrementValue(columnPosition, increment);
664         return l;
665
666     }
667
668     /**
669         Used in CurrentOfResultSet to get to the cursor result set
670         for a cursor. Overridden by activations generated for
671         updatable cursors. Those activations capture the cursor
672         result set in a field in their execute() method, and then
673         return the value of that field in their version of this method.
674
675         @return null
676      */

677     public CursorResultSet getCursorResultSet() {
678         if (SanityManager.DEBUG)
679             SanityManager.THROWASSERT("Must be overridden to be used.");
680         return null;
681     }
682
683     /**
684         Various activation methods need to disallow their
685         invocation if the activation is closed. This lets them
686         check and throw without generating alot of code.
687         <p>
688         The code to write to generate the call to this is approximately:
689         <verbatim>
690             // jf is a JavaFactory
691             CallableExpression ce = jf.newMethodCall(
692                 jf.thisExpression(),
693                 BaseActivation.CLASS_NAME,
694                 "throwIfClosed",
695                 "void",
696                 acb.exprArray(jf.newStringLiteral(...some literal here...)));
697
698             //mb is a MethodBuilder
699             mb.addStatement(jf.newStatement(ce));
700         </verbatim>
701         The java code to write to call this is:
702         <verbatim>
703             this.throwIfClosed(...some literal here...);
704         </verbatim>
705         In both cases, "...some literal here..." gets replaced with
706         an expression of type String that evaluates to the name
707         of the operation that is being checked, like "execute" or
708         "reset".
709
710         @exception StandardException thrown if closed
711      */

712     public void throwIfClosed(String JavaDoc op) throws StandardException {
713         if (closed)
714             throw StandardException.newException(SQLState.LANG_ACTIVATION_CLOSED, op);
715     }
716
717     /**
718      * Set a column position in an array of column positions.
719      *
720      * @param columnPositions The array of column positions
721      * @param positionToSet The place to put the column position
722      * @param column The column position
723      */

724     public static void setColumnPosition(
725                             int[] columnPositions,
726                             int positionToSet,
727                             int column)
728     {
729         columnPositions[positionToSet] = column;
730     }
731
732     /**
733      * Allocate an array of qualifiers and initialize in Qualifier[][]
734      *
735      * @param qualifiers The array of Qualifier arrays.
736      * @param position The position in the array to set
737      * @param length The array length of the qualifier array to allocate.
738      */

739     public static void allocateQualArray(
740     Qualifier[][] qualifiers,
741     int position,
742     int length)
743     {
744         qualifiers[position] = new Qualifier[length];
745     }
746
747
748     /**
749      * Set a Qualifier in a 2 dimensional array of Qualifiers.
750      *
751      * Set a single Qualifier into one slot of a 2 dimensional array of
752      * Qualifiers. @see Qualifier for detailed description of layout of
753      * the 2-d array.
754      *
755      * @param qualifiers The array of Qualifiers
756      * @param qualifier The Qualifier
757      * @param position_1 The Nth array index into qualifiers[N][M]
758      * @param position_2 The Nth array index into qualifiers[N][M]
759      */

760     public static void setQualifier(
761     Qualifier[][] qualifiers,
762     Qualifier qualifier,
763     int position_1,
764     int position_2)
765     {
766         qualifiers[position_1][position_2] = qualifier;
767     }
768
769     /**
770      * Reinitialize all Qualifiers in an array of Qualifiers.
771      *
772      * @param qualifiers The array of Qualifiers
773      */

774     public static void reinitializeQualifiers(Qualifier[][] qualifiers)
775     {
776         if (qualifiers != null)
777         {
778             for (int term = 0; term < qualifiers.length; term++)
779             {
780                 for (int i = 0; i < qualifiers[term].length; i++)
781                 {
782                     qualifiers[term][i].reinitialize();
783                 }
784             }
785         }
786     }
787
788     /**
789      * Mark the activation as unused.
790      */

791     public final void markUnused()
792     {
793         if(isInUse()) {
794             inUse = false;
795             lcc.notifyUnusedActivation();
796         }
797     }
798
799     /**
800      * Is the activation in use?
801      *
802      * @return true/false
803      */

804     public final boolean isInUse()
805     {
806         return inUse;
807     }
808
809     /**
810       @see org.apache.derby.iapi.sql.Activation#addWarning
811       */

812     public void addWarning(SQLWarning JavaDoc w)
813     {
814         if (warnings == null)
815             warnings = w;
816         else
817             warnings.setNextWarning(w);
818     }
819
820     /**
821       @see org.apache.derby.iapi.sql.Activation#getWarnings
822       */

823     public SQLWarning JavaDoc getWarnings()
824     {
825         return warnings;
826     }
827
828     /**
829       @see org.apache.derby.iapi.sql.Activation#clearWarnings
830       */

831     public void clearWarnings()
832     {
833         warnings = null;
834     }
835
836     /**
837      * @exception StandardException on error
838      */

839     protected static void nullToPrimitiveTest(DataValueDescriptor dvd, String JavaDoc primitiveType)
840         throws StandardException
841     {
842         if (dvd.isNull())
843         {
844             throw StandardException.newException(SQLState.LANG_NULL_TO_PRIMITIVE_PARAMETER, primitiveType);
845         }
846     }
847
848     /**
849         @see Activation#informOfRowCount
850         @exception StandardException Thrown on error
851      */

852     public void informOfRowCount(NoPutResultSet resultSet, long currentRowCount)
853                     throws StandardException
854     {
855
856         /* Do we want to check the row counts during this execution? */
857         if (checkRowCounts)
858         {
859             boolean significantChange = false;
860
861             int resultSetNumber = resultSet.resultSetNumber();
862             Integer JavaDoc rsn = ReuseFactory.getInteger(resultSetNumber);
863
864             /* Check each result set only once per execution */
865             if (rowCountsCheckedThisExecution.add(rsn))
866             {
867                 synchronized (getPreparedStatement())
868                 {
869                     Vector JavaDoc rowCountCheckVector = getRowCountCheckVector();
870
871                     if (rowCountCheckVector == null) {
872                         rowCountCheckVector = new Vector JavaDoc();
873                         setRowCountCheckVector(rowCountCheckVector);
874                     }
875
876                     Long JavaDoc firstRowCount = null;
877
878                     /*
879                     ** Check whether this resultSet has been seen yet.
880                     */

881                     if (resultSetNumber < rowCountCheckVector.size())
882                     {
883                         firstRowCount =
884                             (Long JavaDoc) rowCountCheckVector.elementAt(resultSetNumber);
885                     }
886                     else
887                     {
888                         rowCountCheckVector.setSize(resultSetNumber + 1);
889                     }
890
891                     if (firstRowCount != null)
892                     {
893                         /*
894                         ** This ResultSet has been seen - has the row count
895                         ** changed significantly?
896                         */

897                         long n1 = firstRowCount.longValue();
898
899                         if (currentRowCount != n1)
900                         {
901                             if (n1 >= TEN_PERCENT_THRESHOLD)
902                             {
903                                 /*
904                                 ** For tables with more than
905                                 ** TEN_PERCENT_THRESHOLD rows, the
906                                 ** threshold is 10% of the size of the table.
907                                 */

908                                 long changeFactor = n1 / (currentRowCount - n1);
909                                 if (Math.abs(changeFactor) <= 10)
910                                     significantChange = true;
911                             }
912                             else
913                             {
914                                 /*
915                                 ** For tables with less than
916                                 ** TEN_PERCENT_THRESHOLD rows, the threshold
917                                 ** is non-linear. This is because we want
918                                 ** recompilation to happen sooner for small
919                                 ** tables that change size. This formula
920                                 ** is for a second-order equation (a parabola).
921                                 ** The derivation is:
922                                 **
923                                 ** c * n1 = (difference in row counts) ** 2
924                                 ** - or -
925                                 ** c * n1 = (currentRowCount - n1) ** 2
926                                 **
927                                 ** Solving this for currentRowCount, we get:
928                                 **
929                                 ** currentRowCount = n1 + sqrt(c * n1)
930                                 **
931                                 ** - or -
932                                 **
933                                 ** difference in row counts = sqrt(c * n1)
934                                 **
935                                 ** - or -
936                                 **
937                                 ** (difference in row counts) ** 2 =
938                                 ** c * n1
939                                 **
940                                 ** Which means that we should recompile when
941                                 ** the current row count exceeds n1 (the first
942                                 ** row count) by sqrt(c * n1), or when the
943                                 ** square of the difference exceeds c * n1.
944                                 ** A good value for c seems to be 4.
945                                 **
946                                 ** We don't use this formula when c is greater
947                                 ** than TEN_PERCENT_THRESHOLD because we never
948                                 ** want to recompile unless the number of rows
949                                 ** changes by more than 10%, and this formula
950                                 ** is more sensitive than that for values of
951                                 ** n1 greater than TEN_PERCENT_THRESHOLD.
952                                 */

953                                 long changediff = currentRowCount - n1;
954
955                                 /*
956                                 ** Square changediff rather than take the square
957                                 ** root of (4 * n1), because multiplying is
958                                 ** faster than taking a square root. Also,
959                                 ** check to be sure that squaring changediff
960                                 ** will not cause an overflow by comparing it
961                                 ** with the square root of the maximum value
962                                 ** for a long (this square root is taken only
963                                 ** once, when the class is loaded, or during
964                                 ** compilation if the compiler is smart enough).
965                                 */

966                                 if (Math.abs(changediff) <= MAX_SQRT)
967                                 {
968                                     if ((changediff * changediff) >
969                                                             Math.abs(4 * n1))
970                                     {
971                                         significantChange = true;
972                                     }
973                                 }
974                             }
975                         }
976                     }
977                     else
978                     {
979                         firstRowCount = new Long JavaDoc(currentRowCount);
980                         rowCountCheckVector.setElementAt(
981                                                         firstRowCount,
982                                                         resultSetNumber
983                                                         );
984
985                     }
986                 }
987             }
988
989             /* Invalidate outside of the critical section */
990             if (significantChange)
991             {
992                 preStmt.makeInvalid(DependencyManager.INTERNAL_RECOMPILE_REQUEST, lcc);
993             }
994         }
995
996     }
997
998     /**
999      * The subclass calls this method when it begins an execution.
1000     *
1001     * @exception StandardException Thrown on error
1002     */

1003    public void startExecution() throws StandardException
1004    {
1005        // determine if we should check row counts during this execution
1006
shouldWeCheckRowCounts();
1007
1008        // If we are to check row counts, clear the hash table of row counts
1009
// we have checked.
1010
if (checkRowCounts)
1011            rowCountsCheckedThisExecution.clear();
1012    }
1013
1014    /**
1015     * @see Activation#getHeapConglomerateController
1016     */

1017    public ConglomerateController getHeapConglomerateController()
1018    {
1019        return updateHeapCC;
1020    }
1021
1022
1023    /**
1024     * @see Activation#setHeapConglomerateController
1025     */

1026    public void setHeapConglomerateController(ConglomerateController updateHeapCC)
1027    {
1028        this.updateHeapCC = updateHeapCC;
1029    }
1030
1031    /**
1032     * @see Activation#clearHeapConglomerateController
1033     */

1034    public void clearHeapConglomerateController()
1035    {
1036        updateHeapCC = null;
1037    }
1038
1039    /**
1040     * @see Activation#getIndexScanController
1041     */

1042    public ScanController getIndexScanController()
1043    {
1044        return indexSC;
1045    }
1046
1047    /**
1048     * @see Activation#setIndexScanController
1049     */

1050    public void setIndexScanController(ScanController indexSC)
1051    {
1052        this.indexSC = indexSC;
1053    }
1054
1055    /**
1056     * @see Activation#getIndexConglomerateNumber
1057     */

1058    public long getIndexConglomerateNumber()
1059    {
1060        return indexConglomerateNumber;
1061    }
1062
1063    /**
1064     * @see Activation#setIndexConglomerateNumber
1065     */

1066    public void setIndexConglomerateNumber(long indexConglomerateNumber)
1067    {
1068        this.indexConglomerateNumber = indexConglomerateNumber;
1069    }
1070
1071    /**
1072     * @see Activation#clearIndexScanInfo
1073     */

1074    public void clearIndexScanInfo()
1075    {
1076        indexSC = null;
1077        indexConglomerateNumber = -1;
1078    }
1079
1080    /**
1081     * @see Activation#setForCreateTable()
1082     */

1083    public void setForCreateTable()
1084    {
1085        forCreateTable = true;
1086    }
1087
1088    /**
1089     * @see Activation#getForCreateTable()
1090     */

1091    public boolean getForCreateTable()
1092    {
1093        return forCreateTable;
1094    }
1095
1096    /**
1097     * @see Activation#setDDLTableDescriptor
1098     */

1099    public void setDDLTableDescriptor(TableDescriptor td)
1100    {
1101        ddlTableDescriptor = td;
1102    }
1103
1104    /**
1105     * @see Activation#getDDLTableDescriptor
1106     */

1107    public TableDescriptor getDDLTableDescriptor()
1108    {
1109        return ddlTableDescriptor;
1110    }
1111
1112    /**
1113     * @see Activation#setMaxRows
1114     */

1115    public void setMaxRows(int maxRows)
1116    {
1117        this.maxRows = maxRows;
1118    }
1119
1120    /**
1121     * @see Activation#getMaxRows
1122     */

1123    public int getMaxRows()
1124    {
1125        return maxRows;
1126    }
1127
1128    public void setTargetVTI(java.sql.ResultSet JavaDoc targetVTI)
1129    {
1130        this.targetVTI = targetVTI;
1131    }
1132
1133    public java.sql.ResultSet JavaDoc getTargetVTI()
1134    {
1135        return targetVTI;
1136    }
1137
1138    private void shouldWeCheckRowCounts() throws StandardException
1139    {
1140        /*
1141        ** Check the row count only every N executions. OK to check this
1142        ** without synchronization, since the value of this number is not
1143        ** critical. The value of N is determined by the property
1144        ** derby.language.stalePlanCheckInterval.
1145        */

1146        int executionCount = getExecutionCount() + 1;
1147
1148        /*
1149        ** Always check row counts the first time, to establish the
1150        ** row counts for each result set. After that, don't check
1151        ** if the execution count is below the minimum row count check
1152        ** interval. This saves us from checking a database property
1153        ** when we don't have to (checking involves querying the store,
1154        ** which can be expensive).
1155        */

1156
1157        if (executionCount == 1)
1158        {
1159            checkRowCounts = true;
1160        }
1161        else if (executionCount <
1162                                Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL)
1163        {
1164            checkRowCounts = false;
1165        }
1166        else
1167        {
1168            int stalePlanCheckInterval = getStalePlanCheckInterval();
1169
1170            /*
1171            ** Only query the database property once. We can tell because
1172            ** the minimum value of the property is greater than zero.
1173            */

1174            if (stalePlanCheckInterval == 0)
1175            {
1176                TransactionController tc = getTransactionController();
1177
1178                stalePlanCheckInterval =
1179                        PropertyUtil.getServiceInt(
1180                            tc,
1181                            Property.LANGUAGE_STALE_PLAN_CHECK_INTERVAL,
1182                            Property.MIN_LANGUAGE_STALE_PLAN_CHECK_INTERVAL,
1183                            Integer.MAX_VALUE,
1184                            Property.DEFAULT_LANGUAGE_STALE_PLAN_CHECK_INTERVAL
1185                            );
1186                setStalePlanCheckInterval(stalePlanCheckInterval);
1187            }
1188
1189            checkRowCounts = (executionCount % stalePlanCheckInterval) == 1;
1190
1191
1192        }
1193
1194        setExecutionCount(executionCount);
1195    }
1196
1197    /*
1198    ** These accessor methods are provided by the sub-class to help figure
1199    ** out whether to check row counts during this execution.
1200    */

1201    abstract protected int getExecutionCount();
1202
1203    abstract protected void setExecutionCount(int newValue);
1204
1205    /*
1206    ** These accessor methods are provided by the sub-class to help figure
1207    ** out whether the row count for a particular result set has changed
1208    ** enough to force recompilation.
1209    */

1210    abstract protected Vector JavaDoc getRowCountCheckVector();
1211
1212    abstract protected void setRowCountCheckVector(Vector JavaDoc newValue);
1213
1214    /*
1215    ** These accessor methods are provided by the sub-class to remember the
1216    ** value of the stale plan check interval property, so that we only
1217    ** have to query the database properties once (there is heavyweight
1218    ** synchronization around the database properties).
1219    */

1220    abstract protected int getStalePlanCheckInterval();
1221
1222    abstract protected void setStalePlanCheckInterval(int newValue);
1223
1224    public final boolean getScrollable() {
1225        return scrollable;
1226    }
1227
1228    protected final void setParameterValueSet(int paramCount, boolean hasReturnParam) {
1229
1230        pvs = lcc.getLanguageFactory().newParameterValueSet(
1231            lcc.getLanguageConnectionFactory().getClassFactory().getClassInspector(),
1232            paramCount, hasReturnParam);
1233        }
1234    
1235    /**
1236     * This method can help reduce the amount of generated code by changing
1237     * instances of this.pvs.getParameter(position) to this.getParameter(position)
1238     * @param position
1239     * @throws StandardException
1240     */

1241    protected final DataValueDescriptor getParameter(int position) throws StandardException {
1242        return pvs.getParameter(position);
1243        }
1244    
1245    /**
1246     return the parameters.
1247     */

1248    public ParameterValueSet getParameterValueSet()
1249    {
1250        if (pvs == null)
1251            setParameterValueSet(0, false);
1252        return pvs;
1253    }
1254
1255    // how do we do/do we want any sanity checking for
1256
// the number of parameters expected?
1257
public void setParameters(ParameterValueSet parameterValues, DataTypeDescriptor[] parameterTypes) throws StandardException
1258    {
1259        if (!isClosed())
1260        {
1261
1262            if (this.pvs == null || parameterTypes == null) {
1263                pvs = parameterValues;
1264                return;
1265
1266            }
1267
1268            DataTypeDescriptor[] newParamTypes = preStmt.getParameterTypes();
1269
1270            /*
1271            ** If there are old parameters but not new ones,
1272            ** they aren't compatible.
1273            */

1274            boolean match = false;
1275            if (newParamTypes != null) {
1276
1277                if (newParamTypes.length == parameterTypes.length) {
1278
1279                    /* Check each parameter */
1280                    match = true;
1281                    for (int i = 0; i < parameterTypes.length; i++)
1282                    {
1283                        DataTypeDescriptor oldType = parameterTypes[i];
1284                        DataTypeDescriptor newType = newParamTypes[i];
1285
1286                        if (!oldType.isExactTypeAndLengthMatch(newType)) {
1287                            match = false;
1288                            break;
1289                        }
1290                        /*
1291                        ** We could probably get away without checking nullability,
1292                        ** since parameters are always nullable.
1293                        */

1294                        if (oldType.isNullable() != newType.isNullable()) {
1295                            match = false;
1296                            break;
1297                        }
1298                    }
1299                }
1300
1301            }
1302
1303            if (!match)
1304                throw StandardException.newException(SQLState.LANG_OBSOLETE_PARAMETERS);
1305
1306
1307            parameterValues.transferDataValues(pvs);
1308
1309        }
1310        else if (SanityManager.DEBUG)
1311        {
1312            SanityManager.THROWASSERT("isClosed() is expected to return false");
1313        }
1314    }
1315
1316    /**
1317        Throw an exception if any parameters are uninitialized.
1318
1319        @exception StandardException Thrown if any parameters
1320                                                are unitialized
1321     */

1322
1323    public void throwIfMissingParms() throws StandardException
1324    {
1325        if (pvs != null && !pvs.allAreSet())
1326        {
1327            throw StandardException.newException(SQLState.LANG_MISSING_PARMS);
1328        }
1329    }
1330
1331    /**
1332     * Remember the row for the specified ResultSet.
1333     */

1334    public void setCurrentRow(ExecRow currentRow, int resultSetNumber)
1335    {
1336        if (SanityManager.DEBUG)
1337        {
1338            SanityManager.ASSERT(!isClosed(), "closed");
1339            if (row != null)
1340            {
1341                if (!(resultSetNumber >=0 && resultSetNumber < row.length))
1342                {
1343                    SanityManager.THROWASSERT("resultSetNumber = " + resultSetNumber +
1344                                 ", expected to be between 0 and " + row.length);
1345                }
1346            }
1347        }
1348        if (row != null)
1349        {
1350            row[resultSetNumber] = currentRow;
1351        }
1352    }
1353
1354    /**
1355     * Clear the current row for the specified ResultSet.
1356     */

1357    public void clearCurrentRow(int resultSetNumber)
1358    {
1359        if (SanityManager.DEBUG)
1360        {
1361            if (row != null)
1362            {
1363                if (!(resultSetNumber >=0 && resultSetNumber < row.length))
1364                {
1365                    SanityManager.THROWASSERT("resultSetNumber = " + resultSetNumber +
1366                                 ", expected to be between 0 and " + row.length);
1367                }
1368            }
1369        }
1370        if (row != null)
1371        {
1372            row[resultSetNumber] = null;
1373        }
1374    }
1375
1376    protected final DataValueDescriptor getColumnFromRow(int rsNumber, int colId)
1377        throws StandardException {
1378
1379        if( row[rsNumber] == null)
1380        {
1381            /* This actually happens. NoPutResultSetImpl.clearOrderableCache attempts to prefetch invariant values
1382             * into a cache. This fails in some deeply nested joins. See Beetle 4736 and 4880.
1383             */

1384            return null;
1385        }
1386        return row[rsNumber].getColumn(colId);
1387    }
1388
1389    protected void checkPositionedStatement(String JavaDoc cursorName, String JavaDoc psName)
1390        throws StandardException {
1391
1392        ExecPreparedStatement ps = getPreparedStatement();
1393        if (ps == null)
1394            return;
1395            
1396        LanguageConnectionContext lcc = getLanguageConnectionContext();
1397
1398        CursorActivation cursorActivation = lcc.lookupCursorActivation(cursorName);
1399
1400        if (cursorActivation != null)
1401        {
1402            // check we are compiled against the correct cursor
1403
if (!psName.equals(cursorActivation.getPreparedStatement().getObjectName())) {
1404
1405                // our prepared statement is now invalid since there
1406
// exists another cursor with the same name but a different
1407
// statement.
1408
ps.makeInvalid(DependencyManager.CHANGED_CURSOR, lcc);
1409            }
1410        }
1411    }
1412
1413    /* This method is used to materialize a resultset if can actually fit in the memory
1414     * specified by "maxMemoryPerTable" system property. It converts the result set into
1415     * union(union(union...(union(row, row), row), ...row), row). It returns this
1416     * in-memory converted resultset, or the original result set if not converted.
1417     * See beetle 4373 for details.
1418     *
1419     * Optimization implemented as part of Beetle: 4373 can cause severe stack overflow
1420     * problems. See JIRA entry DERBY-634. With default MAX_MEMORY_PER_TABLE of 1MG, it is
1421     * possible that this optimization could attempt to cache upto 250K rows as nested
1422     * union results. At runtime, this would cause stack overflow.
1423     *
1424     * As Jeff mentioned in DERBY-634, right way to optimize original problem would have been
1425     * to address subquery materialization during optimization phase, through hash joins.
1426     * Recent Army's optimizer work through DEBRY-781 and related work introduced a way to
1427     * materialize subquery results correctly and needs to be extended to cover this case.
1428     * While his optimization needs to be made more generic and stable, I propose to avoid
1429     * this regression by limiting size of the materialized resultset created here to be
1430     * less than MAX_MEMORY_PER_TABLE and MAX_DYNAMIC_MATERIALIZED_ROWS.
1431     *
1432     * @param rs input result set
1433     * @return materialized resultset, or original rs if it can't be materialized
1434     */

1435    public NoPutResultSet materializeResultSetIfPossible(NoPutResultSet rs)
1436        throws StandardException
1437    {
1438        rs.openCore();
1439        Vector JavaDoc rowCache = new Vector JavaDoc();
1440        ExecRow aRow;
1441        int cacheSize = 0;
1442        FormatableBitSet toClone = null;
1443
1444        int maxMemoryPerTable = getLanguageConnectionContext().getOptimizerFactory().getMaxMemoryPerTable();
1445
1446        aRow = rs.getNextRowCore();
1447        if (aRow != null)
1448        {
1449            toClone = new FormatableBitSet(aRow.nColumns() + 1);
1450            toClone.set(1);
1451        }
1452        while (aRow != null)
1453        {
1454            cacheSize += aRow.getColumn(1).getLength();
1455            if (cacheSize > maxMemoryPerTable ||
1456                    rowCache.size() > Optimizer.MAX_DYNAMIC_MATERIALIZED_ROWS)
1457                break;
1458            rowCache.addElement(aRow.getClone(toClone));
1459            aRow = rs.getNextRowCore();
1460        }
1461        rs.close();
1462
1463        if (aRow == null)
1464        {
1465            int rsNum = rs.resultSetNumber();
1466
1467            int numRows = rowCache.size();
1468            if (numRows == 0)
1469            {
1470                return new RowResultSet(
1471                                        this,
1472                                        (ExecRow) null,
1473                                        true,
1474                                        rsNum,
1475                                        0,
1476                                        0);
1477            }
1478            RowResultSet[] rrs = new RowResultSet[numRows];
1479            UnionResultSet[] urs = new UnionResultSet[numRows - 1];
1480
1481            for (int i = 0; i < numRows; i++)
1482            {
1483                rrs[i] = new RowResultSet(
1484                                        this,
1485                                        (ExecRow) rowCache.elementAt(i),
1486                                        true,
1487                                        rsNum,
1488                                        1,
1489                                        0);
1490                if (i > 0)
1491                {
1492                    urs[i - 1] = new UnionResultSet (
1493                                        (i > 1) ? (NoPutResultSet)urs[i - 2] : (NoPutResultSet)rrs[0],
1494                                        rrs[i],
1495                                        this,
1496                                        rsNum,
1497                                        i + 1,
1498                                        0);
1499                }
1500            }
1501
1502            rs.finish();
1503
1504            if (numRows == 1)
1505                return rrs[0];
1506            else
1507                return urs[urs.length - 1];
1508        }
1509        return rs;
1510    }
1511
1512
1513
1514    //WARNING : this field name is referred in the DeleteNode generate routines.
1515
protected CursorResultSet[] raParentResultSets;
1516
1517
1518    // maintain hash table of parent result set vector
1519
// a table can have more than one parent source.
1520
protected Hashtable JavaDoc parentResultSets;
1521    public void setParentResultSet(TemporaryRowHolder rs, String JavaDoc resultSetId)
1522    {
1523        Vector JavaDoc rsVector;
1524        if(parentResultSets == null)
1525            parentResultSets = new Hashtable JavaDoc();
1526        rsVector = (Vector JavaDoc) parentResultSets.get(resultSetId);
1527        if(rsVector == null)
1528        {
1529            rsVector = new Vector JavaDoc();
1530            rsVector.addElement(rs);
1531        }else
1532        {
1533            rsVector.addElement(rs);
1534        }
1535        parentResultSets.put(resultSetId , rsVector);
1536    }
1537
1538    /**
1539     * get the reference to parent table ResultSets, that will be needed by the
1540     * referential action dependent table scans.
1541     */

1542    public Vector JavaDoc getParentResultSet(String JavaDoc resultSetId)
1543    {
1544        return (Vector JavaDoc) parentResultSets.get(resultSetId);
1545    }
1546
1547    public Hashtable JavaDoc getParentResultSets()
1548    {
1549        return parentResultSets;
1550    }
1551
1552    /**
1553     ** prepared statement use the same activation for
1554     ** multiple execution. For each excution we create new
1555     ** set of temporary resultsets, we should clear this hash table.
1556     ** otherwise we will refer to the released resources.
1557     */

1558    public void clearParentResultSets()
1559    {
1560        if(parentResultSets != null)
1561            parentResultSets.clear();
1562    }
1563
1564    /**
1565     * beetle 3865: updateable cursor using index. A way of communication
1566     * between cursor activation and update activation.
1567     */

1568    public void setForUpdateIndexScan(CursorResultSet forUpdateIndexScan)
1569    {
1570        this.forUpdateIndexScan = forUpdateIndexScan;
1571    }
1572
1573    public CursorResultSet getForUpdateIndexScan()
1574    {
1575        return forUpdateIndexScan;
1576    }
1577
1578    private java.util.Calendar JavaDoc cal;
1579    /**
1580        Return a calendar for use by this activation.
1581        Calendar objects are not thread safe, the one returned
1582        is purely for use by this activation and it is assumed
1583        that is it single threded through the single active
1584        thread in a connection model.
1585    */

1586    protected java.util.Calendar JavaDoc getCalendar() {
1587        if (cal == null)
1588            cal = new java.util.GregorianCalendar JavaDoc();
1589        return cal;
1590
1591    }
1592
1593
1594    /*
1595    ** Code originally in the parent class BaseExpressionActivation
1596    */

1597    /**
1598        Get the language connection factory associated with this connection
1599      */

1600    public final LanguageConnectionContext getLanguageConnectionContext()
1601    {
1602        return lcc;
1603    }
1604
1605    public final TransactionController getTransactionController()
1606    {
1607        return lcc.getTransactionExecute();
1608    }
1609            
1610    /**
1611     * Get the ExecutionContext.
1612     */

1613    ExecutionContext getExecutionContext()
1614    {
1615        return ec;
1616    }
1617
1618    /**
1619     * Get the Current ContextManager.
1620     *
1621     * @return Current ContextManager
1622     */

1623    public ContextManager getContextManager()
1624    {
1625        return cm;
1626    }
1627
1628    /**
1629        Used by activations to generate data values. Most DML statements
1630        will use this method. Possibly some DDL statements will, as well.
1631     */

1632    public DataValueFactory getDataValueFactory()
1633    {
1634        return dvFactory;
1635    }
1636
1637    /**
1638     * Used to get a proxy for the current connection.
1639     *
1640     * @exception SQLException Thrown on failure to get connection
1641     */

1642    public Connection JavaDoc getCurrentConnection() throws SQLException JavaDoc {
1643
1644        ConnectionContext cc =
1645            (ConnectionContext) cm.getContext(ConnectionContext.CONTEXT_ID);
1646
1647        return cc.getNestedConnection(true);
1648    }
1649
1650    /**
1651        Real implementations of this method are provided by a generated class.
1652    */

1653    public java.sql.ResultSet JavaDoc[][] getDynamicResults() {
1654        return null;
1655    }
1656    /**
1657        Real implementations of this method are provided by a generated class.
1658    */

1659    public int getMaxDynamicResults() {
1660        return 0;
1661    }
1662
1663    /**
1664     * Compute the DB2 compatible length of a value.
1665     *
1666     * @param value
1667     * @param constantLength The length, if it is a constant modulo null/not null. -1 if the length is not constant
1668     * @param reUse If non-null then re-use this as a container for the length
1669     *
1670     * @return the DB2 compatible length, set to null if value is null.
1671     */

1672    public NumberDataValue getDB2Length( DataValueDescriptor value,
1673                                         int constantLength,
1674                                         NumberDataValue reUse)
1675        throws StandardException
1676    {
1677        if( reUse == null)
1678            reUse = getDataValueFactory().getNullInteger( null);
1679        if( value.isNull())
1680            reUse.setToNull();
1681        else
1682        {
1683            if( constantLength >= 0)
1684                reUse.setValue( constantLength);
1685            else
1686            {
1687                reUse.setValue(value.getLength());
1688            }
1689        }
1690        return reUse;
1691    } // end of getDB2Length
1692
}
1693
Popular Tags