KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.DDLStatementNode
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.compiler.MethodBuilder;
25
26 import org.apache.derby.iapi.sql.ResultSet;
27
28 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
29 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
30 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
31 import org.apache.derby.iapi.sql.compile.CompilerContext;
32 import org.apache.derby.iapi.sql.conn.Authorizer;
33 import org.apache.derby.iapi.reference.SQLState;
34 import org.apache.derby.iapi.error.StandardException;
35
36 import org.apache.derby.impl.sql.compile.ActivationClassBuilder;
37
38 import org.apache.derby.iapi.services.sanity.SanityManager;
39 import org.apache.derby.iapi.reference.ClassName;
40
41 import org.apache.derby.iapi.services.classfile.VMOpcode;
42 import org.apache.derby.catalog.UUID;
43
44 /**
45  * A DDLStatementNode represents any type of DDL statement: CREATE TABLE,
46  * CREATE INDEX, ALTER TABLE, etc.
47  *
48  * @author Jeff Lichtman
49  */

50
51 abstract class DDLStatementNode extends StatementNode
52 {
53     /////////////////////////////////////////////////////////////////////////
54
//
55
// CONSTANTS
56
//
57
/////////////////////////////////////////////////////////////////////////
58

59     public static final int UNKNOWN_TYPE = 0;
60     public static final int ADD_TYPE = 1;
61     public static final int DROP_TYPE = 2;
62     public static final int MODIFY_TYPE = 3;
63     public static final int LOCKING_TYPE = 4;
64
65
66     /////////////////////////////////////////////////////////////////////////
67
//
68
// STATE
69
//
70
/////////////////////////////////////////////////////////////////////////
71

72     private TableName objectName;
73     private boolean initOk;
74
75     /**
76         sub-classes can set this to be true to allow implicit
77         creation of the main object's schema at execution time.
78     */

79     boolean implicitCreateSchema;
80
81
82     /////////////////////////////////////////////////////////////////////////
83
//
84
// BEHAVIOR
85
//
86
/////////////////////////////////////////////////////////////////////////
87

88     public void init(Object JavaDoc objectName)
89         throws StandardException {
90         initAndCheck(objectName);
91     }
92
93     /**
94         Initialize the object name we will be performing the DDL
95         on and check that we are not in the system schema
96         and that DDL is allowed.
97     */

98     protected void initAndCheck(Object JavaDoc objectName)
99         throws StandardException {
100
101         this.objectName = (TableName) objectName;
102
103         initOk = true;
104     }
105
106     /**
107      * A DDL statement is always atomic
108      *
109      * @return true
110      */

111     public boolean isAtomic()
112     {
113         return true;
114     }
115
116     /**
117      * Return the name of the table being dropped.
118      * This is the unqualified table name.
119      *
120      * @return the relative name
121      */

122     public String JavaDoc getRelativeName()
123     {
124         return objectName.getTableName() ;
125     }
126
127     /**
128      * Return the full dot expression name of the
129      * object being dropped.
130      *
131      * @return the full name
132      */

133     public String JavaDoc getFullName()
134     {
135         return objectName.getFullTableName() ;
136     }
137
138     public final TableName getObjectName() { return objectName; }
139
140     /**
141      * Convert this object to a String. See comments in QueryTreeNode.java
142      * for how this should be done for tree printing.
143      *
144      * @return This object as a String
145      */

146
147     public String JavaDoc toString()
148     {
149         if (SanityManager.DEBUG)
150         {
151             return ((objectName==null)?"":objectName.toString()) + super.toString();
152         }
153         else
154         {
155             return "";
156         }
157     }
158
159     int activationKind()
160     {
161            return StatementNode.NEED_DDL_ACTIVATION;
162     }
163
164     /**
165      * Generic generate code for all DDL statements.
166      *
167      * @param acb The ActivationClassBuilder for the class being built
168      * @param mb The execute() method to be built
169      *
170      * @exception StandardException Thrown on error
171      */

172
173     public final void generate(ActivationClassBuilder acb,
174                                 MethodBuilder mb)
175                             throws StandardException
176     {
177         if (SanityManager.DEBUG) {
178             if (!initOk)
179                 SanityManager.THROWASSERT(getClass() + " never called initAndCheck()");
180         }
181
182         // The generated java is the expression:
183
// return ResultSetFactory.getDDLResultSet(this)
184
//
185

186         acb.pushGetResultSetFactoryExpression(mb); // instance for getDDLResultSet
187
acb.pushThisAsActivation(mb); // first arg
188

189         mb.callMethod(VMOpcode.INVOKEINTERFACE, (String JavaDoc) null, "getDDLResultSet", ClassName.ResultSet, 1);
190     }
191
192      
193
194     /**
195     * Get a schema descriptor for this DDL object.
196     * Uses this.objectName. Always returns a schema,
197     * we lock in the schema name prior to execution.
198     * Checks if current authorizationID is owner of the schema.
199     *
200     * @return Schema Descriptor
201     *
202     * @exception StandardException throws on schema name
203     * that doesn't exist
204     */

205     protected final SchemaDescriptor getSchemaDescriptor() throws StandardException
206     {
207         return getSchemaDescriptor(true);
208     }
209
210     /**
211     * Get a schema descriptor for this DDL object.
212     * Uses this.objectName. Always returns a schema,
213     * we lock in the schema name prior to execution.
214     *
215     * @param ownerCheck If check for schema owner is needed
216     *
217     * @return Schema Descriptor
218     *
219     * @exception StandardException throws on schema name
220     * that doesn't exist
221     */

222     protected final SchemaDescriptor getSchemaDescriptor(boolean ownerCheck)
223          throws StandardException
224     {
225         String JavaDoc schemaName = objectName.getSchemaName();
226         //boolean needError = !(implicitCreateSchema || (schemaName == null));
227
boolean needError = !implicitCreateSchema;
228         SchemaDescriptor sd = getSchemaDescriptor(schemaName, needError);
229         CompilerContext cc = getCompilerContext();
230
231         if (sd == null) {
232             /* Disable creating schemas starting with SYS */
233             if (schemaName.startsWith("SYS"))
234                 throw StandardException.newException(
235                     SQLState.LANG_NO_USER_DDL_IN_SYSTEM_SCHEMA,
236                     statementToString(),
237                     schemaName);
238
239             sd = new SchemaDescriptor(getDataDictionary(), schemaName,
240                 (String JavaDoc) null, (UUID)null, false);
241
242             if (isPrivilegeCollectionRequired())
243                 cc.addRequiredSchemaPriv(schemaName, null, Authorizer.CREATE_SCHEMA_PRIV);
244         }
245
246         if (ownerCheck && isPrivilegeCollectionRequired())
247             cc.addRequiredSchemaPriv(sd.getSchemaName(), null,
248                         Authorizer.MODIFY_SCHEMA_PRIV);
249
250         /*
251         ** Catch the system schema here.
252         */

253         if (sd.isSystemSchema())
254         {
255             throw StandardException.newException(SQLState.LANG_NO_USER_DDL_IN_SYSTEM_SCHEMA,
256                             statementToString(), sd);
257         }
258         return sd;
259     }
260
261     protected final TableDescriptor getTableDescriptor()
262         throws StandardException
263     {
264         return getTableDescriptor(objectName);
265     }
266
267     protected final TableDescriptor getTableDescriptor(UUID tableId)
268         throws StandardException {
269
270         TableDescriptor td = getDataDictionary().getTableDescriptor(tableId);
271
272         td = checkTableDescriptor(td);
273         return td;
274
275     }
276
277
278     /**
279      * Validate that the table is ok for DDL -- e.g.
280      * that it exists, it is not a view, and is not
281      * a system table, and that its schema is ok.
282      *
283      * @return the validated table descriptor, never null
284      *
285      * @exception StandardException on error
286      */

287     protected final TableDescriptor getTableDescriptor(TableName tableName)
288         throws StandardException
289     {
290         String JavaDoc schemaName = tableName.getSchemaName();
291         SchemaDescriptor sd = getSchemaDescriptor(schemaName);
292         
293         TableDescriptor td = getTableDescriptor(tableName.getTableName(), sd);
294
295         if (td == null)
296         {
297             throw StandardException.newException(SQLState.LANG_OBJECT_DOES_NOT_EXIST,
298                         statementToString(), tableName);
299         }
300
301         /* beetle 4444, td may have changed when we obtain shared lock */
302         td = checkTableDescriptor(td);
303         return td;
304
305     }
306
307     private TableDescriptor checkTableDescriptor(TableDescriptor td)
308         throws StandardException
309     {
310         String JavaDoc sqlState = null;
311
312         switch (td.getTableType()) {
313         case TableDescriptor.VTI_TYPE:
314         case TableDescriptor.SYSTEM_TABLE_TYPE:
315
316             /*
317             ** Not on system tables (though there are no constraints on
318             ** system tables as of the time this is writen
319             */

320             sqlState = SQLState.LANG_INVALID_OPERATION_ON_SYSTEM_TABLE;
321             break;
322
323         case TableDescriptor.BASE_TABLE_TYPE:
324             /* need to IX lock table if we are a reader in DDL datadictionary
325              * cache mode, otherwise we may interfere with another DDL thread
326              * that is in execution phase; beetle 4343, also see $WS/docs/
327              * language/SolutionsToConcurrencyIssues.txt (point f)
328              */

329             return lockTableForCompilation(td);
330
331         case TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE:
332             return td;
333
334         /*
335         ** Make sure it is not a view
336         */

337         case TableDescriptor.VIEW_TYPE:
338             sqlState = SQLState.LANG_INVALID_OPERATION_ON_VIEW;
339             break;
340         }
341
342         
343         throw StandardException.newException(sqlState,
344                 statementToString(), td.getQualifiedName());
345
346     }
347
348     /**
349       * Bind the object Name. This means filling in the schema name if it
350       * wasn't specified.
351       *
352       * @param dataDictionary Data dictionary to bind against.
353       *
354       * @exception StandardException Thrown on error
355       */

356     public void bindName( DataDictionary dataDictionary )
357                                throws StandardException
358     {
359         if (objectName != null)
360             objectName.bind( dataDictionary );
361     }
362 }
363
Popular Tags