KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.CreateViewNode
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.sql.compile.Visitable;
25 import org.apache.derby.iapi.sql.compile.Visitor;
26
27 import org.apache.derby.iapi.services.context.ContextManager;
28
29 import org.apache.derby.iapi.services.sanity.SanityManager;
30
31 import org.apache.derby.iapi.error.StandardException;
32
33 import org.apache.derby.iapi.sql.compile.CompilerContext;
34 import org.apache.derby.iapi.sql.compile.C_NodeTypes;
35 import org.apache.derby.iapi.sql.compile.NodeFactory;
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.DataDictionary;
41 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
42 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
43
44 import org.apache.derby.iapi.sql.depend.DependencyManager;
45 import org.apache.derby.iapi.sql.depend.Dependent;
46 import org.apache.derby.iapi.sql.depend.ProviderInfo;
47 import org.apache.derby.iapi.sql.depend.ProviderList;
48
49 import org.apache.derby.iapi.reference.SQLState;
50 import org.apache.derby.iapi.reference.Limits;
51
52 import org.apache.derby.iapi.sql.execute.ConstantAction;
53
54 import org.apache.derby.impl.sql.execute.ColumnInfo;
55 import org.apache.derby.catalog.UUID;
56
57 /**
58  * A CreateViewNode is the root of a QueryTree that represents a CREATE VIEW
59  * statement.
60  *
61  * @author Jerry Brenner
62  */

63
64 public class CreateViewNode extends DDLStatementNode
65 {
66     ResultColumnList resultColumns;
67     ResultSetNode queryExpression;
68     String JavaDoc qeText;
69     int checkOption;
70     ProviderInfo[] providerInfos;
71     ColumnInfo[] colInfos;
72
73
74     /**
75      * Initializer for a CreateViewNode
76      *
77      * @param newObjectName The name of the table to be created
78      * @param resultColumns The column list from the view definition,
79      * if specified
80      * @param queryExpression The query expression for the view
81      * @param checkOption The type of WITH CHECK OPTION that was specified
82      * (NONE for now)
83      * @param qeText The text for the queryExpression
84      *
85      * @exception StandardException Thrown on error
86      */

87
88     public void init(Object JavaDoc newObjectName,
89                    Object JavaDoc resultColumns,
90                    Object JavaDoc queryExpression,
91                    Object JavaDoc checkOption,
92                    Object JavaDoc qeText)
93         throws StandardException
94     {
95         initAndCheck(newObjectName);
96         this.resultColumns = (ResultColumnList) resultColumns;
97         this.queryExpression = (ResultSetNode) queryExpression;
98         this.checkOption = ((Integer JavaDoc) checkOption).intValue();
99         this.qeText = ((String JavaDoc) qeText).trim();
100
101         implicitCreateSchema = true;
102     }
103
104     /**
105      * Convert this object to a String. See comments in QueryTreeNode.java
106      * for how this should be done for tree printing.
107      *
108      * @return This object as a String
109      */

110
111     public String JavaDoc toString()
112     {
113         if (SanityManager.DEBUG)
114         {
115             return super.toString() +
116                 "checkOption: " + checkOption + "\n" +
117                 "qeText: " + qeText + "\n";
118         }
119         else
120         {
121             return "";
122         }
123     }
124
125     public String JavaDoc statementToString()
126     {
127         return "CREATE VIEW";
128     }
129
130     /**
131      * Prints the sub-nodes of this object. See QueryTreeNode.java for
132      * how tree printing is supposed to work.
133      *
134      * @param depth The depth of this node in the tree
135      */

136
137     public void printSubNodes(int depth)
138     {
139         if (SanityManager.DEBUG)
140         {
141             super.printSubNodes(depth);
142
143             if (resultColumns != null)
144             {
145                 printLabel(depth, "resultColumns: ");
146                 resultColumns.treePrint(depth + 1);
147             }
148
149             printLabel(depth, "queryExpression: ");
150             queryExpression.treePrint(depth + 1);
151         }
152     }
153
154     // accessors
155

156     public int getCheckOption() { return checkOption; }
157
158     public ProviderInfo[] getProviderInfo() { return providerInfos; }
159
160     public ColumnInfo[] getColumnInfo() { return colInfos; }
161
162     // We inherit the generate() method from DDLStatementNode.
163

164     /**
165      * Bind this CreateViewNode. This means doing any static error
166      * checking that can be done before actually creating the table.
167      * For example, verifying that the ResultColumnList does not
168      * contain any duplicate column names.
169      *
170      * @return The bound query tree
171      *
172      * @exception StandardException Thrown on error
173      */

174     public QueryTreeNode bind() throws StandardException
175     {
176         CompilerContext cc = getCompilerContext();
177         DataDictionary dataDictionary = getDataDictionary();
178         ResultColumnList qeRCL;
179         String JavaDoc duplicateColName;
180
181         // bind the query expression
182

183         providerInfos = bindViewDefinition
184             ( dataDictionary, cc, getLanguageConnectionContext(),
185               getNodeFactory(),
186               queryExpression,
187               getContextManager()
188             );
189
190         qeRCL = queryExpression.getResultColumns();
191
192         /* If there is an RCL for the view definition then
193          * copy the names to the queryExpression's RCL after verifying
194          * that they both have the same size.
195          */

196         if (resultColumns != null)
197         {
198             if (resultColumns.size() != qeRCL.size())
199             {
200                 throw StandardException.newException(SQLState.LANG_VIEW_DEFINITION_R_C_L_MISMATCH,
201                                 getFullName());
202             }
203             qeRCL.copyResultColumnNames(resultColumns);
204         }
205
206         /* Check to make sure the queryExpression's RCL has unique names. If target column
207          * names not specified, raise error if there are any un-named columns to match DB2
208          */

209         duplicateColName = qeRCL.verifyUniqueNames((resultColumns == null) ? true : false);
210         if (duplicateColName != null)
211         {
212             throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE_VIEW, duplicateColName);
213         }
214
215         /* Only 5000 columns allowed per view */
216         if (queryExpression.getResultColumns().size() > Limits.DB2_MAX_COLUMNS_IN_VIEW)
217         {
218             throw StandardException.newException(SQLState.LANG_TOO_MANY_COLUMNS_IN_TABLE_OR_VIEW,
219                 String.valueOf(queryExpression.getResultColumns().size()),
220                 getRelativeName(),
221                 String.valueOf(Limits.DB2_MAX_COLUMNS_IN_VIEW));
222         }
223
224         // for each column, stuff system.column
225
colInfos = new ColumnInfo[queryExpression.getResultColumns().size()];
226         genColumnInfos(colInfos);
227
228         return this;
229     }
230
231     /**
232      * Bind the query expression for a view definition.
233      *
234      * @param dataDictionary The DataDictionary to use to look up
235      * columns, tables, etc.
236      *
237      * @return Array of providers that this view depends on.
238      *
239      * @exception StandardException Thrown on error
240      */

241
242     private ProviderInfo[] bindViewDefinition( DataDictionary dataDictionary,
243                                              CompilerContext compilerContext,
244                                              LanguageConnectionContext lcc,
245                                              NodeFactory nodeFactory,
246                                              ResultSetNode queryExpr,
247                                              ContextManager cm)
248         throws StandardException
249     {
250         FromList fromList = (FromList) nodeFactory.getNode(
251                                         C_NodeTypes.FROM_LIST,
252                                         nodeFactory.doJoinOrderOptimization(),
253                                         cm);
254
255         ProviderList prevAPL = compilerContext.getCurrentAuxiliaryProviderList();
256         ProviderList apl = new ProviderList();
257
258         try {
259             compilerContext.setCurrentAuxiliaryProviderList(apl);
260             compilerContext.pushCurrentPrivType(Authorizer.SELECT_PRIV);
261
262             /* Bind the tables in the queryExpression */
263             queryExpr = queryExpr.bindNonVTITables(dataDictionary, fromList);
264             queryExpr = queryExpr.bindVTITables(fromList);
265
266             /* Bind the expressions under the resultSet */
267             queryExpr.bindExpressions(fromList);
268
269             //cannot define views on temporary tables
270
if (queryExpr instanceof SelectNode)
271             {
272                 //If attempting to reference a SESSION schema table (temporary or permanent) in the view, throw an exception
273
if (queryExpr.referencesSessionSchema())
274                     throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);
275             }
276
277             // bind the query expression
278
queryExpr.bindResultColumns(fromList);
279         }
280         finally
281         {
282             compilerContext.popCurrentPrivType();
283             compilerContext.setCurrentAuxiliaryProviderList(prevAPL);
284         }
285
286         DependencyManager dm = dataDictionary.getDependencyManager();
287         ProviderInfo[] providerInfos = dm.getPersistentProviderInfos(apl);
288         // need to clear the column info in case the same table descriptor
289
// is reused, eg., in multiple target only view definition
290
dm.clearColumnInfoInProviders(apl);
291
292         /* Verify that all underlying ResultSets reclaimed their FromList */
293         if (SanityManager.DEBUG)
294         {
295             SanityManager.ASSERT(fromList.size() == 0,
296                 "fromList.size() is expected to be 0, not " + fromList.size() +
297                 " on return from RS.bindExpressions()");
298         }
299
300         return providerInfos;
301     }
302
303     /**
304      * Return true if the node references SESSION schema tables (temporary or permanent)
305      *
306      * @return true if references SESSION schema tables, else false
307      *
308      * @exception StandardException Thrown on error
309      */

310     public boolean referencesSessionSchema()
311         throws StandardException
312     {
313         //If create view is part of create statement and the view references SESSION schema tables, then it will
314
//get caught in the bind phase of the view and exception will be thrown by the view bind.
315
return (queryExpression.referencesSessionSchema());
316     }
317
318     /**
319      * Create the Constant information that will drive the guts of Execution.
320      *
321      * @exception StandardException Thrown on failure
322      */

323     public ConstantAction makeConstantAction() throws StandardException
324     {
325         /* RESOLVE - need to build up dependendencies and store them away through
326          * the constant action.
327          */

328         return getGenericConstantActionFactory().getCreateViewConstantAction(getSchemaDescriptor().getSchemaName(),
329                                               getRelativeName(),
330                                               TableDescriptor.VIEW_TYPE,
331                                               qeText,
332                                               checkOption,
333                                               colInfos,
334                                               providerInfos,
335                                               (UUID)null); // compilation schema, filled
336
// in when we create the view
337
}
338
339     /**
340      * Fill in the ColumnInfo[] for this create view.
341      *
342      * @param colInfos The ColumnInfo[] to be filled in.
343      */

344     private void genColumnInfos(ColumnInfo[] colInfos)
345     {
346         ResultColumnList rcl = queryExpression.getResultColumns();
347         int rclSize = rcl.size();
348
349         for (int index = 0; index < rclSize; index++)
350         {
351             ResultColumn rc = (ResultColumn) rcl.elementAt(index);
352
353             //RESOLVEAUTOINCREMENT
354
colInfos[index] = new ColumnInfo(rc.getName(),
355                                              rc.getType(),
356                                              null,
357                                              null,
358                                              null,
359                                              null,
360                                              ColumnInfo.CREATE,
361                                              0, 0, 0);
362         }
363     }
364
365     /*
366      * class interface
367      */

368
369     /**
370       * Get the parsed query expression (the SELECT statement).
371       *
372       * @return the parsed query expression.
373       */

374     ResultSetNode getParsedQueryExpression() { return queryExpression; }
375
376
377     /*
378      * These methods are used by execution
379      * to get information for storing into
380      * the system catalogs.
381      */

382
383
384     /**
385      * Accept a visitor, and call v.visit()
386      * on child nodes as necessary.
387      *
388      * @param v the visitor
389      *
390      * @exception StandardException on error
391      */

392     public Visitable accept(Visitor v)
393         throws StandardException
394     {
395         Visitable returnNode = v.visit(this);
396
397         if (v.skipChildren(this))
398         {
399             return returnNode;
400         }
401
402         if (!v.stopTraversal())
403         {
404             super.accept(v);
405         }
406
407         if (queryExpression != null && !v.stopTraversal())
408         {
409             queryExpression = (ResultSetNode)queryExpression.accept(v);
410         }
411
412         return returnNode;
413     }
414
415 }
416
Popular Tags