KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > compile > ExecSPSNode


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.ExecSPSNode
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.compile;
23
24 import org.apache.derby.iapi.services.sanity.SanityManager;
25
26 import org.apache.derby.iapi.services.loader.GeneratedClass;
27
28 import org.apache.derby.iapi.error.StandardException;
29
30 import org.apache.derby.iapi.sql.compile.CompilerContext;
31
32 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
33 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
34 import org.apache.derby.iapi.sql.dictionary.SPSDescriptor;
35
36 import org.apache.derby.iapi.sql.depend.DependencyManager;
37
38 import org.apache.derby.iapi.reference.SQLState;
39
40 import org.apache.derby.iapi.sql.execute.ConstantAction;
41 import org.apache.derby.iapi.sql.execute.ExecPreparedStatement;
42
43 import org.apache.derby.iapi.types.DataTypeDescriptor;
44 import org.apache.derby.iapi.sql.PreparedStatement;
45 import org.apache.derby.iapi.sql.ResultDescription;
46
47 import org.apache.derby.impl.sql.CursorInfo;
48
49 import org.apache.derby.iapi.util.ByteArray;
50
51 import java.util.Enumeration JavaDoc;
52
53 /**
54  * A ExecSPSNode is the root of a QueryTree
55  * that represents an EXECUTE STATEMENT
56  * statement. It is a tad abnormal. Duringa
57  * bind, it locates and retrieves the SPSDescriptor
58  * for the particular statement. At generate time,
59  * it generates the prepared statement for the
60  * stored prepared statement and returns it (i.e.
61  * it effectively replaces itself with the appropriate
62  * prepared statement).
63  *
64  * @author jamie
65  */

66
67 public class ExecSPSNode extends StatementNode
68 {
69     private TableName name;
70     private SPSDescriptor spsd;
71     private ExecPreparedStatement ps;
72
73     /**
74      * Initializer for a ExecSPSNode
75      *
76      * @param newObjectName The name of the table to be created
77      *
78      * @exception StandardException Thrown on error
79      */

80
81     public void init(
82                 Object JavaDoc newObjectName)
83     {
84         this.name = (TableName) newObjectName;
85     }
86
87     /**
88      * Bind this ExecSPSNode. This means doing any static error
89      * checking that can be done before actually creating the table.
90      * For example, verifying that the ResultColumnList does not
91      * contain any duplicate column names.
92      *
93      * @return The bound query tree
94      *
95      * @exception StandardException Thrown on error
96      */

97     public QueryTreeNode bind() throws StandardException
98     {
99         /*
100         ** Grab the compiler context each time we bind just
101         ** to make sure we have the write one (even though
102         ** we are caching it).
103         */

104         DataDictionary dd = getDataDictionary();
105
106         String JavaDoc schemaName = name.getSchemaName();
107         SchemaDescriptor sd = getSchemaDescriptor(name.getSchemaName());
108         if (schemaName == null)
109             name.setSchemaName(sd.getSchemaName());
110
111         if (sd.getUUID() != null)
112             spsd = dd.getSPSDescriptor(name.getTableName(), sd);
113
114         if (spsd == null)
115         {
116             throw StandardException.newException(SQLState.LANG_OBJECT_NOT_FOUND, "STATEMENT", name);
117         }
118
119         if (spsd.getType() == spsd.SPS_TYPE_TRIGGER)
120         {
121             throw StandardException.newException(SQLState.LANG_TRIGGER_SPS_CANNOT_BE_EXECED, name);
122         }
123         
124
125         /*
126         ** This execute statement is dependent on the
127         ** stored prepared statement. If for any reason
128         ** the underlying statement is invalidated by
129         ** the time we get to execution, the 'execute statement'
130         ** will get invalidated when the underlying statement
131         ** is invalidated.
132         */

133         getCompilerContext().createDependency(spsd);
134
135         return this;
136     }
137
138     /**
139      * SPSes are atomic if its underlying statement is
140      * atomic.
141      *
142      * @return true if the statement is atomic
143      */

144     public boolean isAtomic()
145     {
146
147         if (SanityManager.DEBUG)
148         {
149             SanityManager.ASSERT(ps != null,
150                 "statement expected to be bound before calling isAtomic()");
151         }
152
153         return ps.isAtomic();
154     }
155
156     /**
157      * Do code generation for this statement. Overrides
158      * the normal generation path in StatementNode.
159      *
160      * @param ignored - ignored (he he)
161      *
162      * @return A GeneratedClass for this statement
163      *
164      * @exception StandardException Thrown on error
165      */

166     public GeneratedClass generate(ByteArray ignored) throws StandardException
167     {
168         //Bug 4821 - commiting the nested transaction will release any bind time locks
169
//This way we won't get lock time out errors while trying to update sysstatement
170
//table during stale sps recompilation later in the getPreparedstatement() call.
171
if (spsd.isValid() == false) {
172             getLanguageConnectionContext().commitNestedTransaction();
173             getLanguageConnectionContext().beginNestedTransaction(true);
174         }
175
176         /*
177         ** The following does a prepare on the underlying
178         ** statement if necessary. The returned statement
179         ** is valid and its class is loaded up.
180         */

181         ps = spsd.getPreparedStatement();
182
183
184         /*
185         ** Set the saved constants from the prepared statement.
186         ** Put them in the compilation context -- this is where
187         ** they are expected.
188         */

189         getCompilerContext().setSavedObjects(ps.getSavedObjects());
190         getCompilerContext().setCursorInfo(ps.getCursorInfo());
191         GeneratedClass gc = ps.getActivationClass();
192         
193         return gc;
194     }
195         
196     /**
197      * Make the result description. Really, we are just
198      * copying it from the stored prepared statement.
199      *
200      * @return the description
201      */

202     public ResultDescription makeResultDescription()
203     {
204         return ps.getResultDescription();
205     }
206
207     /**
208      * Get information about this cursor. For sps,
209      * this is info saved off of the original query
210      * tree (the one for the underlying query).
211      *
212      * @return the cursor info
213      */

214     public Object JavaDoc getCursorInfo()
215     {
216         return ps.getCursorInfo();
217     }
218
219     /**
220      * Return a description of the ? parameters for the statement
221      * represented by this query tree. Just return the params
222      * stored with the prepared statement.
223      *
224      * @return An array of DataTypeDescriptors describing the
225      * ? parameters for this statement. It returns null
226      * if there are no parameters.
227      *
228      * @exception StandardException on error
229      */

230     public DataTypeDescriptor[] getParameterTypes() throws StandardException
231     {
232         return spsd.getParams();
233     }
234
235
236     /**
237      * Create the Constant information that will drive the guts of Execution.
238      * This is assumed to be the first action on this node.
239      *
240      */

241     public ConstantAction makeConstantAction()
242     {
243         return ps.getConstantAction();
244     }
245
246     /**
247      * We need a savepoint if we will do transactional work.
248      * We'll ask the underlying statement if it needs
249      * a savepoint and pass that back. We have to do this
250      * after generation because getting the PS now might
251      * cause us to basically do DDL (for a stmt recompilation)
252      * which is explicitly banned during binding. So the
253      * caller can only call this after generate() has retrieved
254      * the target PS.
255      *
256      * @return boolean always true.
257      */

258     public boolean needsSavepoint()
259     {
260         if (SanityManager.DEBUG)
261         {
262             SanityManager.ASSERT(ps != null,
263                 "statement expected to be bound before calling needsSavepoint()");
264         }
265
266         return ps.needsSavepoint();
267     }
268
269     /** @see QueryTreeNode#executeStatementName */
270     public String JavaDoc executeStatementName()
271     {
272         return name.getTableName();
273     }
274
275     /** @see QueryTreeNode#executeSchemaName */
276     public String JavaDoc executeSchemaName()
277     {
278         return name.getSchemaName();
279     }
280
281     /**
282      * Get the name of the SPS that is used
283      * to execute this statement. Only relevant
284      * for an ExecSPSNode -- otherwise, returns null.
285      *
286      * @return the name of the underlying sps
287      */

288     public String JavaDoc getSPSName()
289     {
290         return spsd.getQualifiedName();
291     }
292         
293     /*
294      * Shouldn't be called
295      */

296     int activationKind()
297     {
298         if (SanityManager.DEBUG)
299         {
300             SanityManager.THROWASSERT("activationKind not expected "+
301                 "to be called for a stored prepared statement");
302         }
303        return StatementNode.NEED_PARAM_ACTIVATION;
304     }
305     /////////////////////////////////////////////////////////////////////
306
//
307
// PRIVATE
308
//
309
/////////////////////////////////////////////////////////////////////
310

311         
312     /////////////////////////////////////////////////////////////////////
313
//
314
// MISC
315
//
316
/////////////////////////////////////////////////////////////////////
317
public String JavaDoc statementToString()
318     {
319         return "EXECUTE STATEMENT";
320     }
321
322     // called after bind only
323
private final SPSDescriptor getSPSDescriptor()
324     {
325         return spsd;
326     }
327 }
328
Popular Tags