KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.CreateTableConstantAction
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.execute.ConstantAction;
25
26 import org.apache.derby.iapi.store.access.TransactionController;
27
28 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
29
30 import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
31 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
32 import org.apache.derby.iapi.sql.dictionary.DefaultDescriptor;
33 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
34 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptorList;
35 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptor;
36 import org.apache.derby.iapi.sql.dictionary.ColumnDescriptorList;
37 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
38 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
39
40 import org.apache.derby.iapi.sql.depend.Provider;
41 import org.apache.derby.iapi.sql.depend.ProviderInfo;
42
43 import org.apache.derby.iapi.sql.execute.ExecRow;
44
45 import org.apache.derby.iapi.sql.Activation;
46 import org.apache.derby.iapi.sql.depend.DependencyManager;
47
48 import org.apache.derby.iapi.error.StandardException;
49
50 import org.apache.derby.iapi.services.sanity.SanityManager;
51
52 import org.apache.derby.catalog.UUID;
53
54 import org.apache.derby.catalog.types.DefaultInfoImpl;
55
56 import java.util.Properties JavaDoc;
57
58 /**
59  * This class describes actions that are ALWAYS performed for a
60  * CREATE TABLE Statement at Execution time.
61  *
62  * @author Rick Hillegas Extracted code from CreateTableResultSet.
63  */

64
65 class CreateTableConstantAction extends DDLConstantAction
66 {
67
68     private char lockGranularity;
69     private boolean onCommitDeleteRows; //If true, on commit delete rows else on commit preserve rows of temporary table.
70
private boolean onRollbackDeleteRows; //If true, on rollback delete rows from temp table if it was logically modified in that UOW. true is the only supported value
71
private String JavaDoc tableName;
72     private String JavaDoc schemaName;
73     private int tableType;
74     private ColumnInfo[] columnInfo;
75     private CreateConstraintConstantAction[] constraintActions;
76     private Properties JavaDoc properties;
77     
78     /**
79      * Make the ConstantAction for a CREATE TABLE statement.
80      *
81      * @param schemaName name for the schema that table lives in.
82      * @param tableName Name of table.
83      * @param tableType Type of table (e.g., BASE, global temporary table).
84      * @param columnInfo Information on all the columns in the table.
85      * (REMIND tableDescriptor ignored)
86      * @param constraintActions CreateConstraintConstantAction[] for constraints
87      * @param properties Optional table properties
88      * @param lockGranularity The lock granularity.
89      * @param onCommitDeleteRows If true, on commit delete rows else on commit preserve rows of temporary table.
90      * @param onRollbackDeleteRows If true, on rollback, delete rows from temp tables which were logically modified. true is the only supported value
91      */

92     CreateTableConstantAction(
93                                 String JavaDoc schemaName,
94                                 String JavaDoc tableName,
95                                 int tableType,
96                                 ColumnInfo[] columnInfo,
97                                 CreateConstraintConstantAction[] constraintActions,
98                                 Properties JavaDoc properties,
99                                 char lockGranularity,
100                                 boolean onCommitDeleteRows,
101                                 boolean onRollbackDeleteRows)
102     {
103         this.schemaName = schemaName;
104         this.tableName = tableName;
105         this.tableType = tableType;
106         this.columnInfo = columnInfo;
107         this.constraintActions = constraintActions;
108         this.properties = properties;
109         this.lockGranularity = lockGranularity;
110         this.onCommitDeleteRows = onCommitDeleteRows;
111         this.onRollbackDeleteRows = onRollbackDeleteRows;
112
113         if (SanityManager.DEBUG)
114         {
115             if (tableType == TableDescriptor.BASE_TABLE_TYPE && lockGranularity != TableDescriptor.TABLE_LOCK_GRANULARITY &&
116                 lockGranularity != TableDescriptor.ROW_LOCK_GRANULARITY)
117             {
118                 SanityManager.THROWASSERT(
119                     "Unexpected value for lockGranularity = " + lockGranularity);
120             }
121             if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE && onRollbackDeleteRows == false)
122             {
123                 SanityManager.THROWASSERT(
124                     "Unexpected value for onRollbackDeleteRows = " + onRollbackDeleteRows);
125             }
126             SanityManager.ASSERT(schemaName != null, "SchemaName is null");
127         }
128     }
129
130     // OBJECT METHODS
131

132     public String JavaDoc toString()
133     {
134         if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
135             return constructToString("DECLARE GLOBAL TEMPORARY TABLE ", tableName);
136         else
137             return constructToString("CREATE TABLE ", tableName);
138     }
139
140     // INTERFACE METHODS
141

142
143     /**
144      * This is the guts of the Execution-time logic for CREATE TABLE.
145      *
146      * @see ConstantAction#executeConstantAction
147      *
148      * @exception StandardException Thrown on failure
149      */

150     public void executeConstantAction( Activation activation )
151         throws StandardException
152     {
153         TableDescriptor td;
154         UUID toid;
155         SchemaDescriptor schemaDescriptor;
156         ColumnDescriptor columnDescriptor;
157         ExecRow template;
158
159         LanguageConnectionContext lcc = activation.getLanguageConnectionContext();
160         DataDictionary dd = lcc.getDataDictionary();
161         DependencyManager dm = dd.getDependencyManager();
162         TransactionController tc = lcc.getTransactionExecute();
163
164         /* Mark the activation as being for create table */
165         activation.setForCreateTable();
166
167         /*
168         ** Create a row template to tell the store what type of rows this table
169         ** holds.
170         */

171         template = RowUtil.getEmptyValueRow(columnInfo.length, lcc);
172
173         /* Get a template value for each column */
174         for (int ix = 0; ix < columnInfo.length; ix++)
175         {
176             /* If there is a default value, use it, otherwise use null */
177             if (columnInfo[ix].defaultValue != null)
178                 template.setColumn(ix + 1, columnInfo[ix].defaultValue);
179             else
180                 template.setColumn(ix + 1,
181                                     columnInfo[ix].dataType.getNull()
182                                 );
183         }
184
185         /* create the conglomerate to hold the table's rows
186          * RESOLVE - If we ever have a conglomerate creator
187          * that lets us specify the conglomerate number then
188          * we will need to handle it here.
189          */

190         long conglomId = tc.createConglomerate(
191                 "heap", // we're requesting a heap conglomerate
192
template.getRowArray(), // row template
193
null, //column sort order - not required for heap
194
properties, // properties
195
tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE ?
196                 (TransactionController.IS_TEMPORARY | TransactionController.IS_KEPT) : TransactionController.IS_DEFAULT);
197
198         /*
199         ** Inform the data dictionary that we are about to write to it.
200         ** There are several calls to data dictionary "get" methods here
201         ** that might be done in "read" mode in the data dictionary, but
202         ** it seemed safer to do this whole operation in "write" mode.
203         **
204         ** We tell the data dictionary we're done writing at the end of
205         ** the transaction.
206         */

207         if ( tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE )
208             dd.startWriting(lcc);
209
210         SchemaDescriptor sd;
211         if (tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
212             sd = dd.getSchemaDescriptor(schemaName, tc, true);
213         else
214             sd = DDLConstantAction.getSchemaDescriptorForCreate(dd, activation, schemaName);
215
216         //
217
// Create a new table descriptor.
218
//
219
DataDescriptorGenerator ddg = dd.getDataDescriptorGenerator();
220
221         if ( tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE )
222         {
223             td = ddg.newTableDescriptor(tableName, sd, tableType, lockGranularity);
224             dd.addDescriptor(td, sd, DataDictionary.SYSTABLES_CATALOG_NUM, false, tc);
225         } else
226         {
227             td = ddg.newTableDescriptor(tableName, sd, tableType, onCommitDeleteRows, onRollbackDeleteRows);
228             td.setUUID(dd.getUUIDFactory().createUUID());
229         }
230         toid = td.getUUID();
231
232         // Save the TableDescriptor off in the Activation
233
activation.setDDLTableDescriptor(td);
234
235         /* NOTE: We must write the columns out to the system
236          * tables before any of the conglomerates, including
237          * the heap, since we read the columns before the
238          * conglomerates when building a TableDescriptor.
239          * This will hopefully reduce the probability of
240          * a deadlock involving those system tables.
241          */

242         
243         // for each column, stuff system.column
244
int index = 1;
245
246         ColumnDescriptor[] cdlArray = new ColumnDescriptor[columnInfo.length];
247         for (int ix = 0; ix < columnInfo.length; ix++)
248         {
249             UUID defaultUUID = columnInfo[ix].newDefaultUUID;
250
251             /* Generate a UUID for the default, if one exists
252              * and there is no default id yet.
253              */

254             if (columnInfo[ix].defaultInfo != null &&
255                 defaultUUID == null)
256             {
257                 defaultUUID = dd.getUUIDFactory().createUUID();
258             }
259
260             if (columnInfo[ix].autoincInc != 0)//dealing with autoinc column
261
columnDescriptor = new ColumnDescriptor(
262                                    columnInfo[ix].name,
263                                    index++,
264                                    columnInfo[ix].dataType,
265                                    columnInfo[ix].defaultValue,
266                                    columnInfo[ix].defaultInfo,
267                                    td,
268                                    defaultUUID,
269                                    columnInfo[ix].autoincStart,
270                                    columnInfo[ix].autoincInc,
271                                    columnInfo[ix].autoinc_create_or_modify_Start_Increment
272                                );
273             else
274                 columnDescriptor = new ColumnDescriptor(
275                            columnInfo[ix].name,
276                            index++,
277                            columnInfo[ix].dataType,
278                            columnInfo[ix].defaultValue,
279                            columnInfo[ix].defaultInfo,
280                            td,
281                            defaultUUID,
282                            columnInfo[ix].autoincStart,
283                            columnInfo[ix].autoincInc
284                        );
285
286             cdlArray[ix] = columnDescriptor;
287         }
288
289         if ( tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE )
290         {
291             dd.addDescriptorArray(cdlArray, td,
292                               DataDictionary.SYSCOLUMNS_CATALOG_NUM,
293                               false, tc);
294         }
295
296         // now add the column descriptors to the table.
297
ColumnDescriptorList cdl = td.getColumnDescriptorList();
298         for (int i = 0; i < cdlArray.length; i++)
299             cdl.add(cdlArray[i]);
300                  
301         //
302
// Create a conglomerate desciptor with the conglomId filled in and
303
// add it.
304
//
305
// RESOLVE: Get information from the conglomerate descriptor which
306
// was provided.
307
//
308
ConglomerateDescriptor cgd =
309             ddg.newConglomerateDescriptor(conglomId, null, false, null, false, null, toid,
310                                           sd.getUUID());
311         if ( tableType != TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE )
312         {
313             dd.addDescriptor(cgd, sd, DataDictionary.SYSCONGLOMERATES_CATALOG_NUM,
314                          false, tc);
315         }
316
317         // add the newly added conglomerate to the table descriptor
318
ConglomerateDescriptorList conglomList = td.getConglomerateDescriptorList();
319         conglomList.add(cgd);
320
321         /* Create any constraints */
322         if (constraintActions != null)
323         {
324             /*
325             ** Do everything but FK constraints first,
326             ** then FK constraints on 2nd pass.
327             */

328             for (int conIndex = 0; conIndex < constraintActions.length; conIndex++)
329             {
330                 // skip fks
331
if (!constraintActions[conIndex].isForeignKeyConstraint())
332                 {
333                     constraintActions[conIndex].executeConstantAction(activation);
334                 }
335             }
336
337             for (int conIndex = 0; conIndex < constraintActions.length; conIndex++)
338             {
339                 // only foreign keys
340
if (constraintActions[conIndex].isForeignKeyConstraint())
341                 {
342                     constraintActions[conIndex].executeConstantAction(activation);
343                 }
344             }
345         }
346         if ( tableType == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE )
347         {
348             lcc.addDeclaredGlobalTempTable(td);
349         }
350     }
351
352
353 }
354
Popular Tags