KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.DropConstraintConstantAction
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.sanity.SanityManager;
25
26 import org.apache.derby.iapi.services.io.FormatableHashtable;
27
28 import org.apache.derby.catalog.UUID;
29 import org.apache.derby.iapi.services.uuid.UUIDFactory;
30
31 import org.apache.derby.iapi.error.StandardException;
32
33 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
34
35 import org.apache.derby.iapi.sql.StatementType;
36
37 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
38 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
39 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
40 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
41 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
42 import org.apache.derby.iapi.sql.dictionary.ForeignKeyConstraintDescriptor;
43 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
44 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
45 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
46
47 import org.apache.derby.iapi.types.DataValueFactory;
48
49 import org.apache.derby.iapi.sql.depend.DependencyManager;
50
51 import org.apache.derby.iapi.reference.SQLState;
52
53 import org.apache.derby.iapi.sql.execute.ConstantAction;
54
55 import org.apache.derby.iapi.sql.Activation;
56
57 import org.apache.derby.iapi.store.access.TransactionController;
58
59 import org.apache.derby.catalog.UUID;
60
61 /**
62  * This class describes actions that are ALWAYS performed for a
63  * drop constraint at Execution time.
64  *
65  * @version 0.1
66  * @author Jerry Brenner
67  */

68
69 public class DropConstraintConstantAction extends ConstraintConstantAction
70 {
71
72     private boolean cascade; // default false
73
private String JavaDoc constraintSchemaName;
74     private int verifyType;
75
76     // CONSTRUCTORS
77

78     /**
79      * Make one of these puppies.
80      *
81      * @param constraintName Constraint name.
82      * @param constraintSchemaName the schema that constraint lives in.
83      * @param tableName Table name.
84      * @param tableId UUID of table.
85      * @param tableSchemaName the schema that table lives in.
86      * @param indexAction IndexConstantAction for constraint (if necessary)
87      * @param behavior the drop behavior (e.g. StatementType.DROP_CASCADE)
88      */

89     DropConstraintConstantAction(
90                        String JavaDoc constraintName,
91                        String JavaDoc constraintSchemaName,
92                        String JavaDoc tableName,
93                        UUID tableId,
94                        String JavaDoc tableSchemaName,
95                        IndexConstantAction indexAction,
96                        int behavior,
97                        int verifyType)
98     {
99         super(constraintName, DataDictionary.DROP_CONSTRAINT, tableName,
100               tableId, tableSchemaName, indexAction);
101
102         cascade = (behavior == StatementType.DROP_CASCADE);
103         this.constraintSchemaName = constraintSchemaName;
104         this.verifyType = verifyType;
105     }
106
107     // OBJECT METHODS
108

109     public String JavaDoc toString()
110     {
111         // Do not put this under SanityManager.DEBUG - it is needed for
112
// error reporting.
113
if (constraintName == null)
114             return "DROP PRIMARY KEY";
115
116         String JavaDoc ss = constraintSchemaName == null ? schemaName : constraintSchemaName;
117         return "DROP CONSTRAINT " + ss + "." + constraintName;
118     }
119
120     // INTERFACE METHODS
121

122
123     /**
124      * This is the guts of the Execution-time logic for DROP CONSTRAINT.
125      *
126      * @see ConstantAction#executeConstantAction
127      *
128      * @exception StandardException Thrown on failure
129      */

130     public void executeConstantAction( Activation activation )
131                         throws StandardException
132     {
133         ConstraintDescriptor conDesc = null;
134         TableDescriptor td;
135         UUID indexId = null;
136         String JavaDoc indexUUIDString;
137
138         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
139         DataDictionary dd = lcc.getDataDictionary();
140         DependencyManager dm = dd.getDependencyManager();
141         TransactionController tc = lcc.getTransactionExecute();
142
143
144         /*
145         ** Inform the data dictionary that we are about to write to it.
146         ** There are several calls to data dictionary "get" methods here
147         ** that might be done in "read" mode in the data dictionary, but
148         ** it seemed safer to do this whole operation in "write" mode.
149         **
150         ** We tell the data dictionary we're done writing at the end of
151         ** the transaction.
152         */

153         dd.startWriting(lcc);
154
155         td = dd.getTableDescriptor(tableId);
156
157         if (td == null)
158         {
159             throw StandardException.newException(SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, tableName);
160         }
161
162         /* Table gets locked in AlterTableConstantAction */
163
164         /*
165         ** If the schema descriptor is null, then
166         ** we must have just read ourselves in.
167         ** So we will get the corresponding schema
168         ** descriptor from the data dictionary.
169         */

170
171         SchemaDescriptor tdSd = td.getSchemaDescriptor();
172         SchemaDescriptor constraintSd =
173             constraintSchemaName == null ? tdSd : dd.getSchemaDescriptor(constraintSchemaName, tc, true);
174
175
176         /* Get the constraint descriptor for the index, along
177          * with an exclusive row lock on the row in sys.sysconstraints
178          * in order to ensure that no one else compiles against the
179          * index.
180          */

181         if (constraintName == null) // this means "alter table drop primary key"
182
conDesc = dd.getConstraintDescriptors(td).getPrimaryKey();
183         else
184             conDesc = dd.getConstraintDescriptorByName(td, constraintSd, constraintName, true);
185
186         // Error if constraint doesn't exist
187
if (conDesc == null)
188         {
189             String JavaDoc errorName = constraintName == null ? "PRIMARY KEY" :
190                                 (constraintSd.getSchemaName() + "."+ constraintName);
191
192             throw StandardException.newException(SQLState.LANG_DROP_NON_EXISTENT_CONSTRAINT,
193                         errorName,
194                         td.getQualifiedName());
195         }
196         switch( verifyType)
197         {
198         case DataDictionary.UNIQUE_CONSTRAINT:
199             if( conDesc.getConstraintType() != verifyType)
200                 throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE,
201                                                      constraintName, "UNIQUE");
202             break;
203
204         case DataDictionary.CHECK_CONSTRAINT:
205             if( conDesc.getConstraintType() != verifyType)
206                 throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE,
207                                                      constraintName, "CHECK");
208             break;
209
210         case DataDictionary.FOREIGNKEY_CONSTRAINT:
211             if( conDesc.getConstraintType() != verifyType)
212                 throw StandardException.newException(SQLState.LANG_DROP_CONSTRAINT_TYPE,
213                                                      constraintName, "FOREIGN KEY");
214             break;
215         }
216
217         boolean cascadeOnRefKey = (cascade &&
218                         conDesc instanceof ReferencedKeyConstraintDescriptor);
219         if (!cascadeOnRefKey)
220         {
221             dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
222         }
223
224         /*
225         ** If we had a primary/unique key and it is drop cascade,
226         ** drop all the referencing keys now. We MUST do this AFTER
227         ** dropping the referenced key because otherwise we would
228         ** be repeatedly changing the reference count of the referenced
229         ** key and generating unnecessary I/O.
230         */

231         dropConstraintAndIndex(dm, td, dd, conDesc, tc, lcc, !cascadeOnRefKey);
232
233         if (cascadeOnRefKey)
234         {
235             ForeignKeyConstraintDescriptor fkcd;
236             ReferencedKeyConstraintDescriptor cd;
237             ConstraintDescriptorList cdl;
238
239             cd = (ReferencedKeyConstraintDescriptor)conDesc;
240             cdl = cd.getForeignKeyConstraints(ReferencedKeyConstraintDescriptor.ALL);
241             int cdlSize = cdl.size();
242
243             for(int index = 0; index < cdlSize; index++)
244             {
245                 fkcd = (ForeignKeyConstraintDescriptor) cdl.elementAt(index);
246                 dm.invalidateFor(fkcd, DependencyManager.DROP_CONSTRAINT, lcc);
247                 dropConstraintAndIndex(dm, fkcd.getTableDescriptor(), dd, fkcd,
248                                 tc, lcc, true);
249             }
250     
251             /*
252             ** We told dropConstraintAndIndex not to
253             ** remove our dependencies, so send an invalidate,
254             ** and drop the dependencies.
255             */

256             dm.invalidateFor(conDesc, DependencyManager.DROP_CONSTRAINT, lcc);
257             dm.clearDependencies(lcc, conDesc);
258         }
259     }
260
261     /*
262      * Drop the constraint. Clears dependencies, drops
263      * the backing index and removes the constraint
264      * from the list on the table descriptor. Does NOT
265      * do an dm.invalidateFor()
266      */

267     public static void dropConstraintAndIndex(DependencyManager dm,
268                                 TableDescriptor td,
269                                 DataDictionary dd,
270                                 ConstraintDescriptor conDesc,
271                                 TransactionController tc,
272                                 LanguageConnectionContext lcc,
273                                 boolean clearDependencies)
274         throws StandardException
275     {
276         if (SanityManager.DEBUG)
277         {
278             SanityManager.ASSERT(tc != null, "tc is null");
279             SanityManager.ASSERT(td != null, "td is null");
280         }
281
282         if (clearDependencies)
283         {
284             dm.clearDependencies(lcc, conDesc);
285         }
286
287         /* Drop the constraint.
288          * NOTE: This must occur before dropping any backing index, since
289          * a user is not allowed to drop a backing index without dropping
290          * the constraint.
291          */

292         dd.dropConstraintDescriptor(td, conDesc, tc);
293
294         /* Drop the index, if there's one for this constraint.
295          * NOTE: There will always be an indexAction. We don't
296          * force the constraint to exist at bind time, so we always
297          * generate one.
298          */

299         if (conDesc.hasBackingIndex())
300         {
301             ConglomerateDescriptor[] conglomDescs;
302
303             // it may have duplicates, and we drop a backing index
304
// Bug 4307
305
// We need to get the conglomerate descriptors from the
306
// dd in case we dropped other constraints in a cascade operation.
307
conglomDescs = dd.getConglomerateDescriptors(
308                             conDesc.getConglomerateId());
309
310             if (conglomDescs.length != 0)
311             {
312                 for (int i = 0; i < conglomDescs.length; i++)
313                 {
314                     if (conglomDescs[i].isConstraint())
315                     {
316                         DropIndexConstantAction.dropIndex(dm, dd, tc,
317                                                     conglomDescs[i], td,
318                                                     lcc);
319                         break;
320                     }
321                 }
322             }
323         }
324
325         td.removeConstraintDescriptor(conDesc);
326     }
327 }
328
Popular Tags