Adding JMCR-Stable version
[Benchmarks_CSolver.git] / JMCR-Stable / real-world application / MyDerby-10.3 / java / engine / org / apache / derby / impl / sql / compile / VTIDeferModPolicy.java
diff --git a/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/VTIDeferModPolicy.java b/JMCR-Stable/real-world application/MyDerby-10.3/java/engine/org/apache/derby/impl/sql/compile/VTIDeferModPolicy.java
new file mode 100644 (file)
index 0000000..4bd9749
--- /dev/null
@@ -0,0 +1,207 @@
+/*\r
+\r
+   Derby - Class org.apache.derby.impl.sql.compile.VTIDeferModPolicy\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.error.StandardException;\r
+import org.apache.derby.iapi.sql.dictionary.TableDescriptor;\r
+import org.apache.derby.iapi.sql.compile.Visitor;\r
+import org.apache.derby.iapi.sql.compile.Visitable;\r
+\r
+import org.apache.derby.vti.DeferModification;\r
+\r
+import java.util.Enumeration;\r
+import java.util.Hashtable;\r
+\r
+import java.sql.ResultSet;\r
+import java.sql.SQLException;\r
+\r
+/**\r
+ * This class applies a VTI modification deferral policy to a statement to\r
+ * see whether it should be deferred.\r
+ */\r
+class VTIDeferModPolicy implements Visitor\r
+{\r
+    /**\r
+     * See if a VTI modification statement should be deferred.\r
+     *\r
+     * @param statementType DeferModification.INSERT_STATEMENT, UPDATE_STATEMENT, or DELETE_STATEMENT\r
+     * @param targetVTI The target VTI\r
+     * @param updateColumnNames The list of columns being updated, null if this is not an update statement\r
+     * @param source\r
+     */\r
+    public static boolean deferIt( int statementType,\r
+                                   FromVTI targetVTI,\r
+                                   String[] updateColumnNames,\r
+                                   QueryTreeNode source)\r
+        throws StandardException\r
+    {\r
+        try\r
+        {\r
+            DeferModification deferralControl;\r
+            int resultSetType = targetVTI.getResultSetType( );\r
+\r
+            /* Deferred updates and deletes are implemented by scrolling the result set. So, if\r
+             * the statement is an update or delete but the result set is not scrollable then do\r
+             * not attempt to defer the statement.\r
+             */\r
+            if( (statementType == DeferModification.UPDATE_STATEMENT ||statementType == DeferModification.DELETE_STATEMENT)\r
+                && resultSetType == ResultSet.TYPE_FORWARD_ONLY)\r
+                return false;\r
+\r
+            deferralControl = targetVTI.getDeferralControl();\r
+            if( deferralControl == null)\r
+            {\r
+                String VTIClassName = targetVTI.getNewInvocation().getJavaClassName();\r
+                deferralControl = new DefaultVTIModDeferPolicy( VTIClassName,\r
+                                                                ResultSet.TYPE_SCROLL_SENSITIVE == resultSetType);\r
+            }\r
+            if( deferralControl.alwaysDefer( statementType))\r
+                return true;\r
+\r
+            if( source == null && statementType != DeferModification.UPDATE_STATEMENT)\r
+                return false;\r
+\r
+            VTIDeferModPolicy deferralSearch = new VTIDeferModPolicy( targetVTI,\r
+                                                                      updateColumnNames,\r
+                                                                      deferralControl,\r
+                                                                      statementType);\r
+\r
+            if( source != null)\r
+                source.accept( deferralSearch);\r
+\r
+            if( statementType == DeferModification.UPDATE_STATEMENT)\r
+            {\r
+                // Apply the columnRequiresDefer method to updated columns not in the where clause.\r
+                Enumeration columns = deferralSearch.columns.keys();\r
+                while( columns.hasMoreElements())\r
+                {\r
+                    if( deferralControl.columnRequiresDefer( statementType,\r
+                                                             (String) columns.nextElement(),\r
+                                                             false))\r
+                        return true;\r
+                }\r
+            }\r
+            return deferralSearch.deferred;\r
+        }\r
+        catch( SQLException sqle)\r
+        {\r
+            throw StandardException.unexpectedUserException(sqle);\r
+        }\r
+    } // end of deferIt\r
+\r
+    // state needed to search the statement parse tree for nodes that require deferred modification\r
+    private boolean deferred = false;\r
+    private DeferModification deferralControl;\r
+    private int statementType;\r
+    private int tableNumber;\r
+    private Hashtable columns = new Hashtable();\r
+\r
+    private VTIDeferModPolicy( FromVTI targetVTI,\r
+                               String[] columnNames,\r
+                               DeferModification deferralControl,\r
+                               int statementType)\r
+    {\r
+        this.deferralControl = deferralControl;\r
+        this.statementType = statementType;\r
+        tableNumber = targetVTI.getTableNumber();\r
+        if( statementType == DeferModification.UPDATE_STATEMENT && columnNames != null)\r
+        {\r
+            for( int i = 0; i < columnNames.length; i++)\r
+                columns.put( columnNames[i], columnNames[i]);\r
+        }\r
+    }\r
+\r
+    public Visitable visit(Visitable node)\r
+        throws StandardException\r
+    {\r
+        try\r
+        {\r
+            if( node instanceof ColumnReference && statementType != DeferModification.INSERT_STATEMENT)\r
+            {\r
+                ColumnReference cr = (ColumnReference) node;\r
+                if( cr.getTableNumber() == tableNumber)\r
+                {\r
+                    String columnName = cr.getColumnName();\r
+                    if( statementType == DeferModification.DELETE_STATEMENT)\r
+                    {\r
+                        if( columns.get( columnName) == null)\r
+                        {\r
+                            columns.put( columnName, columnName);\r
+                            if( deferralControl.columnRequiresDefer( statementType, columnName, true))\r
+                                deferred = true;\r
+                        }\r
+                    }\r
+                    else if( statementType == DeferModification.UPDATE_STATEMENT)\r
+                    {\r
+                        if( columns.get( columnName) != null)\r
+                        {\r
+                            // This column is referenced in the where clause and is being updated\r
+                            if( deferralControl.columnRequiresDefer( statementType, columnName, true))\r
+                                deferred = true;\r
+                            columns.remove( columnName); // Only test it once.\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+            else if( node instanceof SelectNode)\r
+            {\r
+                SelectNode subSelect = (SelectNode) node;\r
+                FromList fromList = subSelect.getFromList();\r
+\r
+                for( int i = 0; i < fromList.size(); i++)\r
+                {\r
+                    FromTable fromTable = (FromTable) fromList.elementAt(i);\r
+                    if( fromTable instanceof FromBaseTable)\r
+                    {\r
+                        TableDescriptor td = fromTable.getTableDescriptor();\r
+                        if( deferralControl.subselectRequiresDefer( statementType,\r
+                                                                    td.getSchemaName(),\r
+                                                                    td.getName()))\r
+                            deferred = true;\r
+                    }\r
+                    else if( fromTable instanceof FromVTI)\r
+                    {\r
+                        FromVTI fromVTI = (FromVTI) fromTable;\r
+                        if( deferralControl.subselectRequiresDefer( statementType,\r
+                                                                    fromVTI.getNewInvocation().getJavaClassName()))\r
+                            deferred = true;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        catch( SQLException sqle)\r
+        {\r
+            throw StandardException.unexpectedUserException(sqle);\r
+        }\r
+        return node;\r
+    } // end of visit\r
+    \r
+    public boolean stopTraversal()\r
+    {\r
+        return deferred;\r
+    } // end of stopTraversal\r
+    \r
+    public boolean skipChildren(Visitable node)\r
+    {\r
+        return false;\r
+    } // end of skipChildren\r
+} // end of class VTIDeferModPolicy\r