KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.DDLConstantAction
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 java.util.Iterator JavaDoc;
25 import java.util.List JavaDoc;
26
27 import org.apache.derby.iapi.services.monitor.Monitor;
28
29 import org.apache.derby.iapi.services.sanity.SanityManager;
30
31 import org.apache.derby.iapi.services.io.FormatIdUtil;
32 import org.apache.derby.iapi.services.io.Formatable;
33 import org.apache.derby.iapi.services.io.StoredFormatIds;
34
35 import org.apache.derby.iapi.error.StandardException;
36
37 import org.apache.derby.iapi.sql.conn.Authorizer;
38 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
39
40 import org.apache.derby.iapi.sql.dictionary.ColPermsDescriptor;
41 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
42 import org.apache.derby.iapi.sql.dictionary.DataDictionaryContext;
43 import org.apache.derby.iapi.sql.dictionary.PermissionsDescriptor;
44 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
45 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
46 import org.apache.derby.iapi.sql.dictionary.StatementColumnPermission;
47 import org.apache.derby.iapi.sql.dictionary.StatementPermission;
48 import org.apache.derby.iapi.sql.dictionary.StatementRoutinePermission;
49 import org.apache.derby.iapi.sql.dictionary.StatementSchemaPermission;
50 import org.apache.derby.iapi.sql.dictionary.StatementTablePermission;
51
52 import org.apache.derby.iapi.sql.depend.Dependency;
53 import org.apache.derby.iapi.sql.depend.Dependent;
54 import org.apache.derby.iapi.sql.depend.DependencyManager;
55
56 import org.apache.derby.iapi.sql.Activation;
57
58 import org.apache.derby.iapi.reference.SQLState;
59
60 import org.apache.derby.iapi.sql.execute.ConstantAction;
61
62 import org.apache.derby.iapi.store.access.ConglomerateController;
63 import org.apache.derby.iapi.store.access.TransactionController;
64
65 import org.apache.derby.catalog.UUID;
66
67 /**
68  * Abstract class that has actions that are across
69  * all DDL actions.
70  *
71  * @author jamie
72  */

73 public abstract class DDLConstantAction extends GenericConstantAction
74 {
75     //TransactionController tc;
76
//protected LanguageConnectionContext lcc;
77
//DataDescriptorGenerator ddg;
78
//DataDictionary dd;
79
//DependencyManager dm;
80

81     /**
82      * Set up the "environment variables" for this
83      * constant action.
84      */

85     //protected void setEnvironmentVariables(Activation activation)
86
//{
87
/* find the language context.
88          * NOTE: The activation could be null if
89          * we are creating the SPSs for the metadata
90          * queries in the background, so we get
91          * the lcc from the ContextService.
92          */

93         //lcc = (activation == null) ?
94
// (LanguageConnectionContext)
95
// ContextService.getContext(LanguageConnectionContext.CONTEXT_ID):
96
// activation.getLanguageConnectionContext();
97

98
99         // Get the current transaction controller
100
//tc = lcc.getTransactionExecute();
101

102         //dd = lcc.getDataDictionary();
103
//dm = dd.getDependencyManager();
104
//ddg = dd.getDataDescriptorGenerator();
105
// }
106

107     /**
108      * Get the schema descriptor for the schemaid.
109      *
110      * @param dd the data dictionary
111      * @param schemaId the schema id
112      * @param statementType string describing type of statement for error
113      * reporting. e.g. "ALTER STATEMENT"
114      *
115      * @return the schema descriptor
116      *
117      * @exception StandardException if schema is system schema
118      */

119     static SchemaDescriptor getAndCheckSchemaDescriptor(
120                         DataDictionary dd,
121                         UUID schemaId,
122                         String JavaDoc statementType)
123         throws StandardException
124     {
125         SchemaDescriptor sd = dd.getSchemaDescriptor(schemaId, null);
126         return sd;
127     }
128
129     /**
130      * Get the schema descriptor in the creation of an object in
131        the passed in schema.
132      *
133      * @param dd the data dictionary
134        @param activation activation
135        @param schemaName name of the schema
136      *
137      * @return the schema descriptor
138      *
139      * @exception StandardException if the schema does not exist
140      */

141     static SchemaDescriptor getSchemaDescriptorForCreate(
142                         DataDictionary dd,
143                         Activation activation,
144                         String JavaDoc schemaName)
145         throws StandardException
146     {
147         TransactionController tc = activation.getLanguageConnectionContext().getTransactionExecute();
148         SchemaDescriptor sd = dd.getSchemaDescriptor(schemaName, tc, false);
149
150         if (sd == null || sd.getUUID() == null) {
151             ConstantAction csca
152                 = new CreateSchemaConstantAction(schemaName, (String JavaDoc) null);
153
154             try {
155                 csca.executeConstantAction(activation);
156             } catch (StandardException se) {
157                 if (se.getMessageId()
158                     .equals(SQLState.LANG_OBJECT_ALREADY_EXISTS)) {
159                     // Ignore "Schema already exists". Another thread has
160
// probably created it after we checked for it
161
} else {
162                     throw se;
163                 }
164             }
165             
166             sd = dd.getSchemaDescriptor(schemaName, tc, true);
167         }
168
169         return sd;
170     }
171
172     /**
173      * Lock the table in exclusive or share mode to prevent deadlocks.
174      *
175      * @param tc The TransactionController
176      * @param heapConglomerateNumber The conglomerate number for the heap.
177      * @param exclusiveMode Whether or not to lock the table in exclusive mode.
178      *
179      * @exception StandardException if schema is system schema
180      */

181     final void lockTableForDDL(TransactionController tc,
182                          long heapConglomerateNumber, boolean exclusiveMode)
183         throws StandardException
184     {
185         ConglomerateController cc;
186
187         cc = tc.openConglomerate(
188                     heapConglomerateNumber,
189                     false,
190                     (exclusiveMode) ?
191                         (TransactionController.OPENMODE_FORUPDATE |
192                             TransactionController.OPENMODE_FOR_LOCK_ONLY) :
193                         TransactionController.OPENMODE_FOR_LOCK_ONLY,
194                     TransactionController.MODE_TABLE,
195                     TransactionController.ISOLATION_SERIALIZABLE);
196         cc.close();
197     }
198
199     protected String JavaDoc constructToString(
200                         String JavaDoc statementType,
201                         String JavaDoc objectName)
202     {
203         // Do not put this under SanityManager.DEBUG - it is needed for
204
// error reporting.
205

206         return statementType + objectName;
207     }
208     
209     
210     /**
211      * This method saves dependencies of constraints on privileges in the
212      * dependency system. It gets called by CreateConstraintConstantAction.
213      * Views and triggers and constraints run with definer's privileges. If
214      * one of the required privileges is revoked from the definer, the
215      * dependent view/trigger/constraint on that privilege will be dropped
216      * automatically. In order to implement this behavior, we need to save
217      * view/trigger/constraint dependencies on required privileges in the
218      * dependency system. Following method accomplishes that part of the
219      * equation for constraints only. The dependency collection for
220      * constraints is not same as for views and triggers and hence
221      * constraints are handled by this special method.
222      * Views and triggers can depend on many different kind of privileges
223      * where as constraints only depend on REFERENCES privilege on a table.
224      * Another difference is only one view or trigger can be defined by a
225      * sql statement and hence all the dependencies collected for the sql
226      * statement apply to the view or trigger in question. As for constraints,
227      * one sql statement can defined multiple constraints and hence the
228      * all the privileges required by the statement are not necessarily
229      * required by all the constraints defined by that sql statement. We need
230      * to identify right privileges for right constraints for a given sql
231      * statement. Because of these differences between constraints and views
232      * (and triggers), there are 2 different methods in this class to save
233      * their privileges in the dependency system.
234      *
235      * @param activation The execution environment for this constant action.
236      * @param dependent Make this object depend on required privileges
237      * @param refTableUUID Make sure we are looking for REFERENCES privilege
238      * for right table
239      *
240      * @exception StandardException Thrown on failure
241      */

242     protected void storeConstraintDependenciesOnPrivileges(
243             Activation activation, Dependent dependent, UUID refTableUUID)
244     throws StandardException
245     {
246         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
247         DataDictionary dd = lcc.getDataDictionary();
248         DependencyManager dm = dd.getDependencyManager();
249         
250         //If the Database Owner is creating this constraint, then no need to
251
//collect any privilege dependencies because the Database Owner can
252
//access any objects without any restrictions
253
if (!(lcc.getAuthorizationId().equals(dd.getAuthorizationDatabaseOwner())))
254         {
255             PermissionsDescriptor permDesc;
256             //Now, it is time to add into dependency system, constraint's
257
//dependency on REFERENCES privilege. If the REFERENCES privilege is
258
//revoked from the constraint owner, the constraint will get
259
//dropped automatically.
260
List JavaDoc requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList();
261             if (requiredPermissionsList != null && ! requiredPermissionsList.isEmpty())
262             {
263                 for(Iterator JavaDoc iter = requiredPermissionsList.iterator();iter.hasNext();)
264                 {
265                     StatementPermission statPerm = (StatementPermission) iter.next();
266                     //First check if we are dealing with a Table or
267
//Column level privilege. All the other privileges
268
//are not required for a foreign key constraint.
269
if (statPerm instanceof StatementTablePermission)
270                     {//It is a table/column level privilege
271
StatementTablePermission statementTablePermission =
272                             (StatementTablePermission) statPerm;
273                         //Check if we are dealing with REFERENCES privilege.
274
//If not, move on to the next privilege in the
275
//required privileges list
276
if (statementTablePermission.getPrivType() != Authorizer.REFERENCES_PRIV)
277                             continue;
278                         //Next check is this REFERENCES privilege is
279
//on the same table as referenced by the foreign
280
//key constraint? If not, move on to the next
281
//privilege in the required privileges list
282
if (!statementTablePermission.getTableUUID().equals(refTableUUID))
283                             continue;
284                     } else if (statPerm instanceof StatementSchemaPermission
285                             || statPerm instanceof StatementRoutinePermission)
286                         continue;
287
288                     //We know that we are working with a REFERENCES
289
//privilege. Find all the PermissionDescriptors for
290
//this privilege and make constraint depend on it
291
//through dependency manager.
292
//The REFERENCES privilege could be defined at the
293
//table level or it could be defined at individual
294
//column levels. In addition, individual column
295
//REFERENCES privilege could be available at the
296
//user level or PUBLIC level.
297
permDesc = statPerm.getPermissionDescriptor(lcc.getAuthorizationId(), dd);
298                     if (permDesc == null)
299                     {
300                         //No REFERENCES privilege exists for given
301
//authorizer at table or column level.
302
//REFERENCES privilege has to exist at at PUBLIC level
303
permDesc = statPerm.getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd);
304                         if (!(permDesc.checkOwner(lcc.getAuthorizationId())))
305                             dm.addDependency(dependent, permDesc, lcc.getContextManager());
306                     } else
307                         //if the object on which permission is required is owned by the
308
//same user as the current user, then no need to keep that
309
//object's privilege dependency in the dependency system
310
if (!(permDesc.checkOwner(lcc.getAuthorizationId())))
311                     {
312                         dm.addDependency(dependent, permDesc, lcc.getContextManager());
313                         if (permDesc instanceof ColPermsDescriptor)
314                         {
315                             //The if statement above means we found a
316
//REFERENCES privilege at column level for
317
//the given authorizer. If this privilege
318
//doesn't cover all the column , then there
319
//has to exisit REFERENCES for the remaining
320
//columns at PUBLIC level. Get that permission
321
//descriptor and save it in dependency system
322
StatementColumnPermission statementColumnPermission = (StatementColumnPermission) statPerm;
323                             permDesc = statementColumnPermission.getPUBLIClevelColPermsDescriptor(lcc.getAuthorizationId(), dd);
324                             //Following if checks if some column level privileges
325
//exist only at public level. If so, then the public
326
//level column privilege dependency is added
327
//into the dependency system
328
if (permDesc != null)
329                                 dm.addDependency(dependent, permDesc, lcc.getContextManager());
330                         }
331                     }
332                     //We have found the REFERENCES privilege for all the
333
//columns in foreign key constraint and we don't
334
//need to go through the rest of the privileges
335
//for this sql statement.
336
break;
337                 }
338             }
339         }
340         
341     }
342     
343     /**
344      * This method saves dependencies of views and triggers on privileges in
345      * the dependency system. It gets called by CreateViewConstantAction
346      * and CreateTriggerConstantAction. Views and triggers and constraints
347      * run with definer's privileges. If one of the required privileges is
348      * revoked from the definer, the dependent view/trigger/constraint on
349      * that privilege will be dropped automatically. In order to implement
350      * this behavior, we need to save view/trigger/constraint dependencies
351      * on required privileges in the dependency system. Following method
352      * accomplishes that part of the equation for views and triggers. The
353      * dependency collection for constraints is not same as for views and
354      * triggers and hence constraints are not covered by this method.
355      * Views and triggers can depend on many different kind of privileges
356      * where as constraints only depend on REFERENCES privilege on a table.
357      * Another difference is only one view or trigger can be defined by a
358      * sql statement and hence all the dependencies collected for the sql
359      * statement apply to the view or trigger in question. As for constraints,
360      * one sql statement can defined multiple constraints and hence the
361      * all the privileges required by the statement are not necessarily
362      * required by all the constraints defined by that sql statement. We need
363      * to identify right privileges for right constraints for a given sql
364      * statement. Because of these differences between constraints and views
365      * (and triggers), there are 2 different methods in this class to save
366      * their privileges in the dependency system.
367      *
368      * @param activation The execution environment for this constant action.
369      * @param dependent Make this object depend on required privileges
370      *
371      * @exception StandardException Thrown on failure
372      */

373     protected void storeViewTriggerDependenciesOnPrivileges(
374             Activation activation, Dependent dependent)
375     throws StandardException
376     {
377         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
378         DataDictionary dd = lcc.getDataDictionary();
379         DependencyManager dm = dd.getDependencyManager();
380         
381         //If the Database Owner is creating this view/triiger, then no need to
382
//collect any privilege dependencies because the Database Owner can
383
//access any objects without any restrictions
384
if (!(lcc.getAuthorizationId().equals(dd.getAuthorizationDatabaseOwner())))
385         {
386             PermissionsDescriptor permDesc;
387             List JavaDoc requiredPermissionsList = activation.getPreparedStatement().getRequiredPermissionsList();
388             if (requiredPermissionsList != null && ! requiredPermissionsList.isEmpty())
389             {
390                 for(Iterator JavaDoc iter = requiredPermissionsList.iterator();iter.hasNext();)
391                 {
392                     StatementPermission statPerm = (StatementPermission) iter.next();
393                     //The schema ownership permission just needs to be checked
394
//at object creation time, to see if the object creator has
395
//permissions to create the object in the specified schema.
396
//But we don't need to add schema permission to list of
397
//permissions that the object is dependent on once it is
398
//created.
399
if (statPerm instanceof StatementSchemaPermission)
400                         continue;
401                     //See if we can find the required privilege for given authorizer?
402
permDesc = statPerm.getPermissionDescriptor(lcc.getAuthorizationId(), dd);
403                     if (permDesc == null)//privilege not found for given authorizer
404
{
405                         //The if condition above means that required privilege does
406
//not exist at the user level. The privilege has to exist at
407
//PUBLIC level.
408
permDesc = statPerm.getPermissionDescriptor(Authorizer.PUBLIC_AUTHORIZATION_ID, dd);
409                         //If the user accessing the object is the owner of that
410
//object, then no privilege tracking is needed for the
411
//owner.
412
if (!(permDesc.checkOwner(lcc.getAuthorizationId())))
413                             dm.addDependency(dependent, permDesc, lcc.getContextManager());
414                         continue;
415                     }
416                     //if the object on which permission is required is owned by the
417
//same user as the current user, then no need to keep that
418
//object's privilege dependency in the dependency system
419
if (!(permDesc.checkOwner(lcc.getAuthorizationId())))
420                     {
421                         dm.addDependency(dependent, permDesc, lcc.getContextManager());
422                         if (permDesc instanceof ColPermsDescriptor)
423                         {
424                             //For a given table, the table owner can give privileges
425
//on some columns at individual user level and privileges
426
//on some columns at PUBLIC level. Hence, when looking for
427
//column level privileges, we need to look both at user
428
//level as well as PUBLIC level(only if user level column
429
//privileges do not cover all the columns accessed by this
430
//object). We have finished adding dependency for user level
431
//columns, now we are checking if some required column
432
//level privileges are at PUBLIC level.
433
//A specific eg of a view
434
//user1
435
//create table t11(c11 int, c12 int);
436
//grant select(c11) on t1 to user2;
437
//grant select(c12) on t1 to PUBLIC;
438
//user2
439
//create view v1 as select c11 from user1.t11 where c12=2;
440
//For the view above, there are 2 column level privilege
441
//depencies, one for column c11 which exists directly
442
//for user2 and one for column c12 which exists at PUBLIC level.
443
StatementColumnPermission statementColumnPermission = (StatementColumnPermission) statPerm;
444                             permDesc = statementColumnPermission.getPUBLIClevelColPermsDescriptor(lcc.getAuthorizationId(), dd);
445                             //Following if checks if some column level privileges
446
//exist only at public level. If so, then the public
447
//level column privilege dependency of view is added
448
//into dependency system.
449
if (permDesc != null)
450                                 dm.addDependency(dependent, permDesc, lcc.getContextManager());
451                         }
452                     }
453                 }
454             }
455             
456         }
457     }
458 }
459
460
Popular Tags