KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.AlterTableNode
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.reference.SQLState;
25 import org.apache.derby.iapi.reference.Limits;
26
27 import org.apache.derby.iapi.services.sanity.SanityManager;
28
29 import org.apache.derby.iapi.error.StandardException;
30
31 import org.apache.derby.iapi.sql.compile.C_NodeTypes;
32
33 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
34 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
35 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
36
37 import org.apache.derby.iapi.sql.execute.ConstantAction;
38
39 import org.apache.derby.impl.sql.execute.ColumnInfo;
40 import org.apache.derby.impl.sql.execute.ConstraintConstantAction;
41
42 /**
43  * A AlterTableNode represents a DDL statement that alters a table.
44  * It contains the name of the object to be created.
45  *
46  * @author Jerry Brenner
47  */

48
49 public class AlterTableNode extends DDLStatementNode
50 {
51     // The alter table action
52
public TableElementList tableElementList = null;
53     public char lockGranularity;
54     public boolean compressTable = false;
55     public boolean sequential = false;
56     public int behavior; // currently for drop column
57

58     public TableDescriptor baseTable;
59
60     protected int numConstraints;
61
62     private int changeType = UNKNOWN_TYPE;
63
64     private boolean truncateTable = false;
65
66     // constant action arguments
67

68     protected SchemaDescriptor schemaDescriptor = null;
69     protected ColumnInfo[] colInfos = null;
70     protected ConstraintConstantAction[] conActions = null;
71
72
73     /**
74      * Initializer for a TRUNCATE TABLE
75      *
76      * @param objectName The name of the table being truncated
77      * @exception StandardException Thrown on error
78      */

79
80     public void init(Object JavaDoc objectName)
81         throws StandardException
82     {
83
84         //truncate table is not suppotted in this release
85
//semantics are not yet clearly defined by SQL Council yet
86
//truncate will be allowed only in DEBUG builds for testing purposes.
87
if (SanityManager.DEBUG)
88         {
89             initAndCheck(objectName);
90             /* For now, this init() only called for truncate table */
91             truncateTable = true;
92             schemaDescriptor = getSchemaDescriptor();
93         }else
94         {
95             throw StandardException.newException(SQLState.NOT_IMPLEMENTED,
96                                                  "truncate table");
97         }
98     }
99
100     /**
101      * Initializer for a AlterTableNode for COMPRESS
102      *
103      * @param objectName The name of the table being altered
104      * @param sequential Whether or not the COMPRESS is SEQUENTIAL
105      *
106      * @exception StandardException Thrown on error
107      */

108
109     public void init(Object JavaDoc objectName,
110                      Object JavaDoc sequential)
111         throws StandardException
112     {
113         initAndCheck(objectName);
114
115         this.sequential = ((Boolean JavaDoc) sequential).booleanValue();
116         /* For now, this init() only called for compress table */
117         compressTable = true;
118
119         schemaDescriptor = getSchemaDescriptor();
120     }
121
122     /**
123      * Initializer for a AlterTableNode
124      *
125      * @param objectName The name of the table being altered
126      * @param tableElementList The alter table action
127      * @param lockGranularity The new lock granularity, if any
128      * @param changeType ADD_TYPE or DROP_TYPE
129      *
130      * @exception StandardException Thrown on error
131      */

132
133     public void init(
134                             Object JavaDoc objectName,
135                             Object JavaDoc tableElementList,
136                             Object JavaDoc lockGranularity,
137                             Object JavaDoc changeType,
138                             Object JavaDoc behavior,
139                             Object JavaDoc sequential )
140         throws StandardException
141     {
142         initAndCheck(objectName);
143         this.tableElementList = (TableElementList) tableElementList;
144         this.lockGranularity = ((Character JavaDoc) lockGranularity).charValue();
145
146         int[] ct = (int[]) changeType, bh = (int[]) behavior;
147         this.changeType = ct[0];
148         this.behavior = bh[0];
149         boolean[] seq = (boolean[]) sequential;
150         this.sequential = seq[0];
151         switch ( this.changeType )
152         {
153             case ADD_TYPE:
154             case DROP_TYPE:
155             case MODIFY_TYPE:
156             case LOCKING_TYPE:
157
158                 break;
159
160             default:
161
162                 throw StandardException.newException(SQLState.NOT_IMPLEMENTED);
163         }
164
165         schemaDescriptor = getSchemaDescriptor();
166     }
167
168     /**
169      * Convert this object to a String. See comments in QueryTreeNode.java
170      * for how this should be done for tree printing.
171      *
172      * @return This object as a String
173      */

174
175     public String JavaDoc toString()
176     {
177         if (SanityManager.DEBUG)
178         {
179             return super.toString() +
180                 "objectName: " + "\n" + getObjectName() + "\n" +
181                 "tableElementList: " + "\n" + tableElementList + "\n" +
182                 "lockGranularity: " + "\n" + lockGranularity + "\n" +
183                 "compressTable: " + "\n" + compressTable + "\n" +
184                 "sequential: " + "\n" + sequential + "\n" +
185                 "truncateTable: " + "\n" + truncateTable + "\n";
186         }
187         else
188         {
189             return "";
190         }
191     }
192
193     public String JavaDoc statementToString()
194     {
195         if(truncateTable)
196             return "TRUNCATE TABLE";
197         else
198             return "ALTER TABLE";
199     }
200
201     public int getChangeType() { return changeType; }
202
203     // We inherit the generate() method from DDLStatementNode.
204

205     /**
206      * Bind this AlterTableNode. This means doing any static error
207      * checking that can be done before actually creating the table.
208      * For example, verifying that the user is not trying to add a
209      * non-nullable column.
210      *
211      * @return The bound query tree
212      *
213      * @exception StandardException Thrown on error
214      */

215     public QueryTreeNode bind() throws StandardException
216     {
217         DataDictionary dd = getDataDictionary();
218         int numCheckConstraints = 0;
219         int numBackingIndexes = 0;
220
221         /*
222         ** Get the table descriptor. Checks the schema
223         ** and the table.
224         */

225         baseTable = getTableDescriptor();
226         //throw an exception if user is attempting to alter a temporary table
227
if (baseTable.getTableType() == TableDescriptor.GLOBAL_TEMPORARY_TABLE_TYPE)
228         {
229                 throw StandardException.newException(SQLState.LANG_NOT_ALLOWED_FOR_DECLARED_GLOBAL_TEMP_TABLE);
230         }
231
232         /* Statement is dependent on the TableDescriptor */
233         getCompilerContext().createDependency(baseTable);
234
235         if (tableElementList != null)
236         {
237             tableElementList.validate(this, dd, baseTable);
238
239             /* Only 1012 columns allowed per table */
240             if ((tableElementList.countNumberOfColumns() + baseTable.getNumberOfColumns()) > Limits.DB2_MAX_COLUMNS_IN_TABLE)
241             {
242                 throw StandardException.newException(SQLState.LANG_TOO_MANY_COLUMNS_IN_TABLE_OR_VIEW,
243                     String.valueOf(tableElementList.countNumberOfColumns() + baseTable.getNumberOfColumns()),
244                     getRelativeName(),
245                     String.valueOf(Limits.DB2_MAX_COLUMNS_IN_TABLE));
246             }
247             /* Number of backing indexes in the alter table statment */
248             numBackingIndexes = tableElementList.countConstraints(DataDictionary.PRIMARYKEY_CONSTRAINT) +
249                                     tableElementList.countConstraints(DataDictionary.FOREIGNKEY_CONSTRAINT) +
250                                     tableElementList.countConstraints(DataDictionary.UNIQUE_CONSTRAINT);
251             /* Check the validity of all check constraints */
252             numCheckConstraints = tableElementList.countConstraints(
253                                     DataDictionary.CHECK_CONSTRAINT);
254         }
255
256         //If the sum of backing indexes for constraints in alter table statement and total number of indexes on the table
257
//so far is more than 32767, then we need to throw an exception
258
if ((numBackingIndexes + baseTable.getTotalNumberOfIndexes()) > Limits.DB2_MAX_INDEXES_ON_TABLE)
259         {
260             throw StandardException.newException(SQLState.LANG_TOO_MANY_INDEXES_ON_TABLE,
261                 String.valueOf(numBackingIndexes + baseTable.getTotalNumberOfIndexes()),
262                 getRelativeName(),
263                 String.valueOf(Limits.DB2_MAX_INDEXES_ON_TABLE));
264         }
265
266         if (numCheckConstraints > 0)
267         {
268             /* In order to check the validity of the check constraints
269              * we must goober up a FromList containing a single table,
270              * the table being alter, with an RCL containing the existing and
271              * new columns and their types. This will allow us to
272              * bind the constraint definition trees against that
273              * FromList. When doing this, we verify that there are
274              * no nodes which can return non-deterministic results.
275              */

276             FromList fromList = (FromList) getNodeFactory().getNode(
277                                     C_NodeTypes.FROM_LIST,
278                                     getNodeFactory().doJoinOrderOptimization(),
279                                     getContextManager());
280             FromBaseTable table = (FromBaseTable)
281                                     getNodeFactory().getNode(
282                                         C_NodeTypes.FROM_BASE_TABLE,
283                                         getObjectName(),
284                                         null,
285                                         null,
286                                         null,
287                                         getContextManager());
288             fromList.addFromTable(table);
289             fromList.bindTables(dd,
290                             (FromList) getNodeFactory().getNode(
291                                 C_NodeTypes.FROM_LIST,
292                                 getNodeFactory().doJoinOrderOptimization(),
293                                 getContextManager()));
294             tableElementList.appendNewColumnsToRCL(table);
295
296             /* Now that we've finally goobered stuff up, bind and validate
297              * the check constraints.
298              */

299             tableElementList.bindAndValidateCheckConstraints(fromList);
300
301         }
302
303         /* Unlike most other DDL, we will make this ALTER TABLE statement
304          * dependent on the table being altered. In general, we try to
305          * avoid this for DDL, but we are already requiring the table to
306          * exist at bind time (not required for create index) and we don't
307          * want the column ids to change out from under us before
308          * execution.
309          */

310         getCompilerContext().createDependency(baseTable);
311
312         return this;
313     }
314
315     /**
316      * Return true if the node references SESSION schema tables (temporary or permanent)
317      *
318      * @return true if references SESSION schema tables, else false
319      *
320      * @exception StandardException Thrown on error
321      */

322     public boolean referencesSessionSchema()
323         throws StandardException
324     {
325         //If alter table is on a SESSION schema table, then return true.
326
return isSessionSchema(baseTable.getSchemaName());
327     }
328
329     /**
330      * Create the Constant information that will drive the guts of Execution.
331      *
332      * @exception StandardException Thrown on failure
333      */

334     public ConstantAction makeConstantAction() throws StandardException
335     {
336         prepConstantAction();
337
338         return getGenericConstantActionFactory().getAlterTableConstantAction(schemaDescriptor,
339                                              getRelativeName(),
340                                              baseTable.getUUID(),
341                                              baseTable.getHeapConglomerateId(),
342                                              TableDescriptor.BASE_TABLE_TYPE,
343                                              colInfos,
344                                              conActions,
345                                              lockGranularity,
346                                              compressTable,
347                                              behavior,
348                                              sequential,
349                                              truncateTable);
350     }
351
352     /**
353       * Generate arguments to constant action. Called by makeConstantAction() in this class and in
354       * our subclass RepAlterTableNode.
355       *
356       *
357       * @exception StandardException Thrown on failure
358       */

359     public void prepConstantAction() throws StandardException
360     {
361         if (tableElementList != null)
362         {
363             genColumnInfo();
364         }
365
366         /* If we've seen a constraint, then build a constraint list */
367
368         if (numConstraints > 0)
369         {
370             conActions = new ConstraintConstantAction[numConstraints];
371
372             tableElementList.genConstraintActions(conActions, getRelativeName(), schemaDescriptor,
373                                                   getDataDictionary());
374         }
375     }
376       
377     /**
378       * Generate the ColumnInfo argument for the constant action. Return the number of constraints.
379       */

380     public void genColumnInfo()
381     {
382         // for each column, stuff system.column
383
colInfos = new ColumnInfo[tableElementList.countNumberOfColumns()];
384
385         numConstraints = tableElementList.genColumnInfos(colInfos);
386     }
387
388
389     /*
390      * class interface
391      */

392 }
393
394
395
396
397
Popular Tags