KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.RenameConstantAction
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.sql.dictionary.SchemaDescriptor;
25 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
26 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
27 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
28 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
29 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptor;
30 import org.apache.derby.iapi.sql.dictionary.ConstraintDescriptorList;
31 import org.apache.derby.iapi.sql.dictionary.ReferencedKeyConstraintDescriptor;
32 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
33 import org.apache.derby.iapi.store.access.TransactionController;
34
35 import org.apache.derby.iapi.sql.depend.DependencyManager;
36 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
37
38 import org.apache.derby.iapi.reference.SQLState;
39
40 import org.apache.derby.iapi.sql.Activation;
41 import org.apache.derby.iapi.sql.StatementType;
42
43 import org.apache.derby.iapi.sql.execute.ConstantAction;
44
45 import org.apache.derby.iapi.error.StandardException;
46
47 import org.apache.derby.iapi.services.sanity.SanityManager;
48
49 import org.apache.derby.catalog.UUID;
50
51 import org.apache.derby.iapi.services.io.FormatableBitSet;
52
53
54 /**
55  * This class describes actions that are ALWAYS performed for a
56  * RENAME TABLE/COLUMN/INDEX Statement at Execution time.
57  *
58  * @author Mamta Satoor.
59  */

60
61 class RenameConstantAction extends DDLSingleTableConstantAction
62 {
63
64
65     private String JavaDoc fullTableName;
66     private String JavaDoc tableName;
67     private String JavaDoc newTableName;
68     private String JavaDoc oldObjectName;
69     private String JavaDoc newObjectName;
70     private UUID schemaId;
71     private SchemaDescriptor sd;
72     /* You can rename using either alter table or rename command to
73      * rename a table/column. An index can only be renamed with rename
74      * command. usedAlterTable flag is used to keep that information.
75      */

76     private boolean usedAlterTable;
77     /* renamingWhat will be set to 1 if user is renaming a table.
78      * Will be set to 2 if user is renaming a column and will be
79      * set to 3 if user is renaming an index
80      */

81     private int renamingWhat;
82
83     // CONSTRUCTORS
84

85     /**
86      * Make the ConstantAction for a RENAME TABLE/COLUMN/INDEX statement.
87      *
88      * @param fullTableName Fully qualified table name
89      * @param tableName Table name.
90      * @param oldObjectName This is either the name of column/index in case
91      * of rename column/index. For rename table, this is null.
92      * @param newObjectName This is new name for table/column/index
93      * @param sd Schema that table lives in.
94      * @param tableId UUID for table
95      * @param usedAlterTable True-Used Alter Table, False-Used Rename.
96      * For rename index, this will always be false because
97      * there is no alter table command to rename index
98      * @param renamingWhat Rename a 1 - table, 2 - column, 3 - index
99      *
100      */

101     public RenameConstantAction
102     (
103                    String JavaDoc fullTableName,
104                    String JavaDoc tableName,
105                    String JavaDoc oldObjectName,
106                    String JavaDoc newObjectName,
107                    SchemaDescriptor sd,
108                    UUID tableId,
109                    boolean usedAlterTable,
110                    int renamingWhat)
111     {
112         super(tableId);
113         this.fullTableName = fullTableName;
114         this.tableName = tableName;
115         this.sd = sd;
116         this.usedAlterTable = usedAlterTable;
117         this.renamingWhat = renamingWhat;
118
119         switch (this.renamingWhat)
120         {
121             case StatementType.RENAME_TABLE:
122                 this.newTableName = newObjectName;
123                 this.oldObjectName = null;
124                 this.newObjectName=newObjectName;
125                 break;
126
127             case StatementType.RENAME_COLUMN:
128             case StatementType.RENAME_INDEX:
129                 this.oldObjectName = oldObjectName;
130                 this.newObjectName = newObjectName;
131                 break;
132
133             default:
134                 if (SanityManager.DEBUG) {
135                     SanityManager.THROWASSERT(
136                     "Unexpected rename action in RenameConstantAction");
137                 }
138         }
139         if (SanityManager.DEBUG)
140         {
141             SanityManager.ASSERT(sd != null, "SchemaDescriptor is null");
142         }
143     }
144
145     // OBJECT METHODS
146

147     public String JavaDoc toString()
148     {
149         String JavaDoc renameString;
150         if (usedAlterTable)
151             renameString = "ALTER TABLE ";
152         else
153             renameString = "RENAME ";
154
155         switch (this.renamingWhat)
156         {
157             case StatementType.RENAME_TABLE:
158                 if(usedAlterTable)
159                     renameString = renameString + fullTableName + " RENAME TO " + newTableName;
160                 else
161                     renameString = renameString + " TABLE " + fullTableName + " TO " + newTableName;
162                 break;
163
164             case StatementType.RENAME_COLUMN:
165                 if(usedAlterTable)
166                     renameString = renameString + fullTableName + " RENAME " + oldObjectName + " TO " + newObjectName;
167                 else
168                     renameString = renameString + " COLUMN " + fullTableName + "." + oldObjectName + " TO " + newObjectName;
169                 break;
170
171             case StatementType.RENAME_INDEX:
172                 renameString = renameString + " INDEX " + oldObjectName + " TO " + newObjectName;
173                 break;
174
175             default:
176                 if (SanityManager.DEBUG) {
177                         SanityManager.THROWASSERT(
178                     "Unexpected rename action in RenameConstantAction");
179                 }
180                 break;
181         }
182
183         return renameString;
184     }
185
186     // INTERFACE METHODS
187

188
189     /**
190      * The guts of the Execution-time logic for RENAME TABLE/COLUMN/INDEX.
191      *
192      * @see ConstantAction#executeConstantAction
193      *
194      * @exception StandardException Thrown on failure
195      */

196     public void executeConstantAction
197     (
198                    Activation activation)
199         throws StandardException
200     {
201         TableDescriptor td;
202         UUID tableID;
203
204         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
205         DataDictionary dd = lcc.getDataDictionary();
206         DependencyManager dm = dd.getDependencyManager();
207         TransactionController tc = lcc.getTransactionExecute();
208
209
210         /*
211         ** Inform the data dictionary that we are about to write to it.
212         ** There are several calls to data dictionary "get" methods here
213         ** that might be done in "read" mode in the data dictionary, but
214         ** it seemed safer to do this whole operation in "write" mode.
215         **
216         ** We tell the data dictionary we're done writing at the end of
217         ** the transaction.
218         */

219         dd.startWriting(lcc);
220
221         td = dd.getTableDescriptor(tableId);
222
223         if (td == null)
224         {
225             throw StandardException.newException(
226                 SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
227         }
228
229         /*
230         ** If the schema descriptor is null, then
231         ** we must have just read ourselves in.
232         ** So we will get the corresponding schema
233         ** descriptor from the data dictionary.
234         */

235         if (sd == null)
236         {
237             sd = getAndCheckSchemaDescriptor(dd, schemaId, "RENAME TABLE");
238         }
239
240         long heapId = td.getHeapConglomerateId();
241
242         /* need to lock table, beetle 4271
243          */

244         lockTableForDDL(tc, heapId, true);
245
246         /* need to get td again, in case it's changed before lock acquired
247          */

248         td = dd.getTableDescriptor(tableId);
249         if (td == null)
250         {
251             throw StandardException.newException(
252                 SQLState.LANG_TABLE_NOT_FOUND_DURING_EXECUTION, fullTableName);
253         }
254
255         switch (renamingWhat)
256         {
257             case StatementType.RENAME_TABLE:
258                 execGutsRenameTable(td, activation);
259                 break;
260
261             case StatementType.RENAME_COLUMN:
262                 execGutsRenameColumn(td, activation);
263                 break;
264
265             case StatementType.RENAME_INDEX:
266                 execGutsRenameIndex(td, activation);
267                 break;
268
269             default:
270                 if (SanityManager.DEBUG) {
271                     SanityManager.THROWASSERT(
272                             "Unexpected rename action in RenameConstantAction");
273                 }
274                 break;
275         }
276     }
277
278     //do necessary work for rename table at execute time.
279
private void execGutsRenameTable
280     (
281                    TableDescriptor td, Activation activation)
282         throws StandardException
283     {
284         ConstraintDescriptorList constraintDescriptorList;
285         ConstraintDescriptor constraintDescriptor;
286
287         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
288         DataDictionary dd = lcc.getDataDictionary();
289         DependencyManager dm = dd.getDependencyManager();
290         TransactionController tc = lcc.getTransactionExecute();
291         dm.invalidateFor(td, DependencyManager.RENAME, lcc);
292
293         /* look for foreign key dependency on the table. If found any,
294         use dependency manager to pass the rename action to the
295         dependents. */

296         constraintDescriptorList = dd.getConstraintDescriptors(td);
297         for(int index=0; index<constraintDescriptorList.size(); index++)
298         {
299             constraintDescriptor = constraintDescriptorList.elementAt(index);
300             if (constraintDescriptor instanceof ReferencedKeyConstraintDescriptor)
301                 dm.invalidateFor(constraintDescriptor, DependencyManager.RENAME, lcc);
302         }
303
304         // Drop the table
305
dd.dropTableDescriptor(td, sd, tc);
306         // Change the table name of the table descriptor
307
td.setTableName(newTableName);
308         // add the table descriptor with new name
309
dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM,
310                          false, tc);
311     }
312
313     //do necessary work for rename column at execute time.
314
private void execGutsRenameColumn
315     (
316                    TableDescriptor td, Activation activation)
317         throws StandardException
318     {
319         ColumnDescriptor columnDescriptor = null;
320         int columnPosition = 0;
321         ConstraintDescriptorList constraintDescriptorList;
322         ConstraintDescriptor constraintDescriptor;
323         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
324         DataDictionary dd = lcc.getDataDictionary();
325         DependencyManager dm = dd.getDependencyManager();
326         TransactionController tc = lcc.getTransactionExecute();
327
328         /* get the column descriptor for column to be renamed and
329          * using it's position in the table, set the referenced
330          * column map of the table indicating which column is being
331          * renamed. Dependency Manager uses this to find out the
332          * dependents on the column.
333          */

334         columnDescriptor = td.getColumnDescriptor(oldObjectName);
335         columnPosition = columnDescriptor.getPosition();
336         FormatableBitSet toRename = new FormatableBitSet(td.getColumnDescriptorList().size() + 1);
337         toRename.set(columnPosition);
338         td.setReferencedColumnMap(toRename);
339     
340         dm.invalidateFor(td, DependencyManager.RENAME, lcc);
341
342         //look for foreign key dependency on the column.
343
constraintDescriptorList = dd.getConstraintDescriptors(td);
344         for(int index=0; index<constraintDescriptorList.size(); index++)
345         {
346             constraintDescriptor = constraintDescriptorList.elementAt(index);
347             int[] referencedColumns = constraintDescriptor.getReferencedColumns();
348             int numRefCols = referencedColumns.length;
349             for (int j = 0; j < numRefCols; j++)
350             {
351                 if ((referencedColumns[j] == columnPosition) &&
352                     (constraintDescriptor instanceof ReferencedKeyConstraintDescriptor))
353                     dm.invalidateFor(constraintDescriptor, DependencyManager.RENAME, lcc);
354             }
355         }
356
357         // Drop the column
358
dd.dropColumnDescriptor(td.getUUID(), oldObjectName, tc);
359         columnDescriptor.setColumnName(newObjectName);
360         dd.addDescriptor(columnDescriptor, td,
361                          DataDictionary.SYSCOLUMNS_CATALOG_NUM, false, tc);
362
363         //Need to do following to reload the cache so that table
364
//descriptor now has new column name
365
td = dd.getTableDescriptor(td.getObjectID());
366     }
367
368     //do necessary work for rename index at execute time.
369
private void execGutsRenameIndex
370     (
371                    TableDescriptor td, Activation activation)
372         throws StandardException
373     {
374         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
375         DataDictionary dd = lcc.getDataDictionary();
376         DependencyManager dm = dd.getDependencyManager();
377         TransactionController tc = lcc.getTransactionExecute();
378         //for indexes, we only invalidate sps, rest we ignore(ie views)
379
dm.invalidateFor(td, DependencyManager.RENAME_INDEX, lcc);
380
381         ConglomerateDescriptor conglomerateDescriptor =
382             dd.getConglomerateDescriptor(oldObjectName, sd, true);
383
384         if (conglomerateDescriptor == null)
385             throw StandardException.newException(SQLState.LANG_INDEX_NOT_FOUND_DURING_EXECUTION,
386             oldObjectName);
387
388         /* Drop the index descriptor */
389         dd.dropConglomerateDescriptor(conglomerateDescriptor, tc);
390         // Change the index name of the index descriptor
391
conglomerateDescriptor.setConglomerateName(newObjectName);
392         // add the index descriptor with new name
393
dd.addDescriptor(conglomerateDescriptor, sd,
394                          DataDictionary.SYSCONGLOMERATES_CATALOG_NUM, false, tc);
395     }
396
397     /* Following is used for error handling by repSourceCompilerUtilities
398    * in it's method checkIfRenameDependency */

399     public String JavaDoc getTableName() { return tableName; }
400
401 }
402
Popular Tags