Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / compile / CreateViewNode.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/CreateViewNode.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/CreateViewNode.java
new file mode 100644 (file)
index 0000000..52c8e2e
--- /dev/null
@@ -0,0 +1,415 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.CreateViewNode\r
+\r
+   Licensed to the Apache Software Foundation (ASF) under one or more\r
+   contributor license agreements.  See the NOTICE file distributed with\r
+   this work for additional information regarding copyright ownership.\r
+   The ASF licenses this file to you under the Apache License, Version 2.0\r
+   (the "License"); you may not use this file except in compliance with\r
+   the License.  You may obtain a copy of the License at\r
+\r
+      http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+ */\r
+\r
+package        org.apache.derby.impl.sql.compile;\r
+\r
+import org.apache.derby.iapi.sql.compile.Visitable;\r
+import org.apache.derby.iapi.sql.compile.Visitor;\r
+\r
+import org.apache.derby.iapi.services.context.ContextManager;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import org.apache.derby.iapi.error.StandardException;\r
+\r
+import org.apache.derby.iapi.sql.compile.CompilerContext;\r
+import org.apache.derby.iapi.sql.compile.C_NodeTypes;\r
+import org.apache.derby.iapi.sql.compile.NodeFactory;\r
+\r
+import org.apache.derby.iapi.sql.conn.Authorizer;\r
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;\r
+\r
+import org.apache.derby.iapi.sql.dictionary.DataDictionary;\r
+import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+\r
+import org.apache.derby.iapi.sql.depend.DependencyManager;\r
+import org.apache.derby.iapi.sql.depend.Dependent;\r
+import org.apache.derby.iapi.sql.depend.ProviderInfo;\r
+import org.apache.derby.iapi.sql.depend.ProviderList;\r
+\r
+import org.apache.derby.iapi.reference.SQLState;\r
+import org.apache.derby.iapi.reference.Limits;\r
+\r
+import org.apache.derby.iapi.sql.execute.ConstantAction;\r
+\r
+import org.apache.derby.impl.sql.execute.ColumnInfo;\r
+import org.apache.derby.catalog.UUID;\r
+\r
+/**\r
+ * A CreateViewNode is the root of a QueryTree that represents a CREATE VIEW\r
+ * statement.\r
+ *\r
+ */\r
+\r
+public class CreateViewNode extends DDLStatementNode\r
+{\r
+       ResultColumnList        resultColumns;\r
+       ResultSetNode           queryExpression;\r
+       String                          qeText;\r
+       int                                     checkOption;\r
+       ProviderInfo[]          providerInfos;\r
+       ColumnInfo[]            colInfos;\r
+\r
+\r
+       /**\r
+        * Initializer for a CreateViewNode\r
+        *\r
+        * @param newObjectName         The name of the table to be created\r
+        * @param resultColumns         The column list from the view definition, \r
+        *                                                      if specified\r
+        * @param queryExpression       The query expression for the view\r
+        * @param checkOption           The type of WITH CHECK OPTION that was specified\r
+        *                                                      (NONE for now)\r
+        * @param qeText                        The text for the queryExpression\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       public void init(Object newObjectName,\r
+                                  Object resultColumns,\r
+                                  Object        queryExpression,\r
+                                  Object checkOption,\r
+                                  Object qeText)\r
+               throws StandardException\r
+       {\r
+               initAndCheck(newObjectName);\r
+               this.resultColumns = (ResultColumnList) resultColumns;\r
+               this.queryExpression = (ResultSetNode) queryExpression;\r
+               this.checkOption = ((Integer) checkOption).intValue();\r
+               this.qeText = ((String) qeText).trim();\r
+\r
+               implicitCreateSchema = true;\r
+       }\r
+\r
+       /**\r
+        * Convert this object to a String.  See comments in QueryTreeNode.java\r
+        * for how this should be done for tree printing.\r
+        *\r
+        * @return      This object as a String\r
+        */\r
+\r
+       public String toString()\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       return super.toString() +\r
+                               "checkOption: " + checkOption + "\n" +\r
+                               "qeText: " + qeText + "\n";\r
+               }\r
+               else\r
+               {\r
+                       return "";\r
+               }\r
+       }\r
+\r
+       public String statementToString()\r
+       {\r
+               return "CREATE VIEW";\r
+       }\r
+\r
+       /**\r
+        * Prints the sub-nodes of this object.  See QueryTreeNode.java for\r
+        * how tree printing is supposed to work.\r
+        *\r
+        * @param depth         The depth of this node in the tree\r
+        */\r
+\r
+       public void printSubNodes(int depth)\r
+       {\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       super.printSubNodes(depth);\r
+\r
+                       if (resultColumns != null)\r
+                       {\r
+                               printLabel(depth, "resultColumns: ");\r
+                               resultColumns.treePrint(depth + 1);\r
+                       }\r
+\r
+                       printLabel(depth, "queryExpression: ");\r
+                       queryExpression.treePrint(depth + 1);\r
+               }\r
+       }\r
+\r
+       // accessors\r
+\r
+       public  int                             getCheckOption() { return checkOption; }\r
+\r
+       public  ProviderInfo[]  getProviderInfo() { return providerInfos; }\r
+\r
+       public  ColumnInfo[]    getColumnInfo() { return colInfos; }\r
+\r
+       // We inherit the generate() method from DDLStatementNode.\r
+\r
+       /**\r
+        * Bind this CreateViewNode.  This means doing any static error\r
+        * checking that can be done before actually creating the table.\r
+        * For example, verifying that the ResultColumnList does not\r
+        * contain any duplicate column names.\r
+        *\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public void bindStatement() throws StandardException\r
+       {\r
+               CompilerContext                         cc = getCompilerContext();\r
+               DataDictionary                          dataDictionary = getDataDictionary();\r
+               ResultColumnList                        qeRCL;\r
+               String                                          duplicateColName;\r
+\r
+               // bind the query expression\r
+\r
+               providerInfos = bindViewDefinition\r
+                       ( dataDictionary, cc, getLanguageConnectionContext(),\r
+                         getNodeFactory(), \r
+                         queryExpression,\r
+                         getContextManager()\r
+                       );\r
+\r
+               qeRCL = queryExpression.getResultColumns();\r
+\r
+               /* If there is an RCL for the view definition then\r
+                * copy the names to the queryExpression's RCL after verifying\r
+                * that they both have the same size.\r
+                */\r
+               if (resultColumns != null)\r
+               {\r
+                       if (resultColumns.size() != qeRCL.visibleSize())\r
+                       {\r
+                               throw StandardException.newException(SQLState.LANG_VIEW_DEFINITION_R_C_L_MISMATCH,\r
+                                                               getFullName());\r
+                       }\r
+                       qeRCL.copyResultColumnNames(resultColumns);\r
+               }\r
+\r
+               /* Check to make sure the queryExpression's RCL has unique names. If target column\r
+                * names not specified, raise error if there are any un-named columns to match DB2\r
+                */\r
+               duplicateColName = qeRCL.verifyUniqueNames((resultColumns == null) ? true : false);\r
+               if (duplicateColName != null)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_DUPLICATE_COLUMN_NAME_CREATE_VIEW, duplicateColName);\r
+               }\r
+\r
+               /* Only 5000 columns allowed per view */\r
+               if (queryExpression.getResultColumns().size() > Limits.DB2_MAX_COLUMNS_IN_VIEW)\r
+               {\r
+                       throw StandardException.newException(SQLState.LANG_TOO_MANY_COLUMNS_IN_TABLE_OR_VIEW,\r
+                               String.valueOf(queryExpression.getResultColumns().size()),\r
+                               getRelativeName(),\r
+                               String.valueOf(Limits.DB2_MAX_COLUMNS_IN_VIEW));\r
+               }\r
+\r
+               // for each column, stuff system.column\r
+               colInfos = new ColumnInfo[queryExpression.getResultColumns().size()];\r
+               genColumnInfos(colInfos);\r
+       }\r
+\r
+       /**\r
+        * Bind the query expression for a view definition. \r
+        *\r
+        * @param dataDictionary        The DataDictionary to use to look up\r
+        *                              columns, tables, etc.\r
+        *\r
+        * @return      Array of providers that this view depends on.\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+\r
+       private ProviderInfo[] bindViewDefinition( DataDictionary       dataDictionary,\r
+                                                                                        CompilerContext        compilerContext,\r
+                                                                                        LanguageConnectionContext lcc,\r
+                                                                                        NodeFactory            nodeFactory,\r
+                                                                                        ResultSetNode          queryExpr,\r
+                                                                                        ContextManager         cm)\r
+               throws StandardException\r
+       {\r
+               FromList        fromList = (FromList) nodeFactory.getNode(\r
+                                                                               C_NodeTypes.FROM_LIST,\r
+                                                                               nodeFactory.doJoinOrderOptimization(),\r
+                                                                               cm);\r
+\r
+               ProviderList    prevAPL = compilerContext.getCurrentAuxiliaryProviderList();\r
+               ProviderList    apl = new ProviderList();\r
+\r
+               try {\r
+                       compilerContext.setCurrentAuxiliaryProviderList(apl);\r
+                       compilerContext.pushCurrentPrivType(Authorizer.SELECT_PRIV);\r
+\r
+                       /* Bind the tables in the queryExpression */\r
+                       queryExpr = queryExpr.bindNonVTITables(dataDictionary, fromList);\r
+                       queryExpr = queryExpr.bindVTITables(fromList);\r
+\r
+                       /* Bind the expressions under the resultSet */\r
+                       queryExpr.bindExpressions(fromList);\r
+\r
+                       //cannot define views on temporary tables\r
+                       if (queryExpr instanceof SelectNode)\r
+                       {\r
+                               //If attempting to reference a SESSION schema table (temporary or permanent) in the view, throw an exception\r
+                               if (queryExpr.referencesSessionSchema())\r
+                                       throw StandardException.newException(SQLState.LANG_OPERATION_NOT_ALLOWED_ON_SESSION_SCHEMA_TABLES);\r
+                       }\r
+\r
+                       // bind the query expression\r
+                       queryExpr.bindResultColumns(fromList);\r
+                       \r
+                       // rejects any untyped nulls in the RCL\r
+                       // e.g.:  CREATE VIEW v1 AS VALUES NULL\r
+                       queryExpr.bindUntypedNullsToResultColumns(null);\r
+               }\r
+               finally\r
+               {\r
+                       compilerContext.popCurrentPrivType();\r
+                       compilerContext.setCurrentAuxiliaryProviderList(prevAPL);\r
+               }\r
+\r
+               DependencyManager               dm = dataDictionary.getDependencyManager();\r
+               ProviderInfo[]                  providerInfos = dm.getPersistentProviderInfos(apl);\r
+               // need to clear the column info in case the same table descriptor\r
+               // is reused, eg., in multiple target only view definition\r
+               dm.clearColumnInfoInProviders(apl);\r
+\r
+               /* Verify that all underlying ResultSets reclaimed their FromList */\r
+               if (SanityManager.DEBUG)\r
+               {\r
+                       SanityManager.ASSERT(fromList.size() == 0,\r
+                               "fromList.size() is expected to be 0, not " + fromList.size() +\r
+                               " on return from RS.bindExpressions()");\r
+               }\r
+\r
+               return providerInfos;\r
+       }\r
+\r
+       /**\r
+        * Return true if the node references SESSION schema tables (temporary or permanent)\r
+        *\r
+        * @return      true if references SESSION schema tables, else false\r
+        *\r
+        * @exception StandardException         Thrown on error\r
+        */\r
+       public boolean referencesSessionSchema()\r
+               throws StandardException\r
+       {\r
+               //If create view is part of create statement and the view references SESSION schema tables, then it will\r
+               //get caught in the bind phase of the view and exception will be thrown by the view bind. \r
+               return (queryExpression.referencesSessionSchema());\r
+       }\r
+\r
+       /**\r
+        * Create the Constant information that will drive the guts of Execution.\r
+        *\r
+        * @exception StandardException         Thrown on failure\r
+        */\r
+       public ConstantAction   makeConstantAction() throws StandardException\r
+       {\r
+               /* RESOLVE - need to build up dependendencies and store them away through\r
+                * the constant action.\r
+                */\r
+               return  getGenericConstantActionFactory().getCreateViewConstantAction(getSchemaDescriptor().getSchemaName(),\r
+                                                                                         getRelativeName(),\r
+                                                                                         TableDescriptor.VIEW_TYPE,\r
+                                                                                         qeText,\r
+                                                                                         checkOption,\r
+                                                                                         colInfos,\r
+                                                                                         providerInfos,\r
+                                                                                         (UUID)null);  // compilation schema, filled\r
+                                                                                                                       // in when we create the view\r
+       }\r
+\r
+       /**\r
+        * Fill in the ColumnInfo[] for this create view.\r
+        * \r
+        * @param colInfos      The ColumnInfo[] to be filled in.\r
+        */\r
+       private void genColumnInfos(ColumnInfo[] colInfos)\r
+       {\r
+               ResultColumnList rcl =  queryExpression.getResultColumns();\r
+               int                              rclSize = rcl.size();\r
+\r
+               for (int index = 0; index < rclSize; index++)\r
+               {\r
+                       ResultColumn rc = (ResultColumn) rcl.elementAt(index);\r
+\r
+                       //RESOLVEAUTOINCREMENT\r
+                       colInfos[index] = new ColumnInfo(rc.getName(),\r
+                                                                                        rc.getType(),\r
+                                                                                        null,\r
+                                                                                        null,\r
+                                                                                        null,\r
+                                                                                        null,\r
+                                                                                        ColumnInfo.CREATE,\r
+                                                                                        0, 0, 0);\r
+               }\r
+       }\r
+\r
+       /*\r
+        * class interface\r
+        */\r
+\r
+       /**\r
+         *     Get the parsed query expression (the SELECT statement).\r
+         *\r
+         *     @return the parsed query expression.\r
+         */\r
+       ResultSetNode   getParsedQueryExpression() { return queryExpression; }\r
+\r
+\r
+       /*\r
+        * These methods are used by execution\r
+        * to get information for storing into\r
+        * the system catalogs.\r
+        */\r
+\r
+\r
+       /**\r
+        * Accept a visitor, and call v.visit()\r
+        * on child nodes as necessary.  \r
+        * \r
+        * @param v the visitor\r
+        *\r
+        * @exception StandardException on error\r
+        */\r
+       public Visitable accept(Visitor v) \r
+               throws StandardException\r
+       {\r
+               Visitable returnNode = v.visit(this);\r
+\r
+               if (v.skipChildren(this))\r
+               {\r
+                       return returnNode;\r
+               }\r
+\r
+               if (!v.stopTraversal())\r
+               {\r
+                       super.accept(v);\r
+               }\r
+\r
+               if (queryExpression != null && !v.stopTraversal())\r
+               {\r
+                       queryExpression = (ResultSetNode)queryExpression.accept(v);\r
+               }\r
+\r
+               return returnNode;\r
+       }\r
+\r
+}\r