KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.compile.VTIDeferModPolicy
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.error.StandardException;
25 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
26 import org.apache.derby.iapi.sql.compile.Visitor;
27 import org.apache.derby.iapi.sql.compile.Visitable;
28
29 import org.apache.derby.vti.DeferModification;
30
31 import java.util.Enumeration JavaDoc;
32 import java.util.Hashtable JavaDoc;
33
34 import java.sql.ResultSet JavaDoc;
35 import java.sql.SQLException JavaDoc;
36
37 /**
38  * This class applies a VTI modification deferral policy to a statement to
39  * see whether it should be deferred.
40  */

41 class VTIDeferModPolicy implements Visitor
42 {
43     /**
44      * See if a VTI modification statement should be deferred.
45      *
46      * @param statementType DeferModification.INSERT_STATEMENT, UPDATE_STATEMENT, or DELETE_STATEMENT
47      * @param targetVTI The target VTI
48      * @param updateColumnNames The list of columns being updated, null if this is not an update statement
49      * @param source
50      */

51     public static boolean deferIt( int statementType,
52                                    FromVTI targetVTI,
53                                    String JavaDoc[] updateColumnNames,
54                                    QueryTreeNode source)
55         throws StandardException
56     {
57         try
58         {
59             DeferModification deferralControl;
60             int resultSetType = targetVTI.getResultSetType( );
61
62             /* Deferred updates and deletes are implemented by scrolling the result set. So, if
63              * the statement is an update or delete but the result set is not scrollable then do
64              * not attempt to defer the statement.
65              */

66             if( (statementType == DeferModification.UPDATE_STATEMENT ||statementType == DeferModification.DELETE_STATEMENT)
67                 && resultSetType == ResultSet.TYPE_FORWARD_ONLY)
68                 return false;
69
70             deferralControl = targetVTI.getDeferralControl();
71             if( deferralControl == null)
72             {
73                 String JavaDoc VTIClassName = targetVTI.getNewInvocation().getJavaClassName();
74                 deferralControl = new DefaultVTIModDeferPolicy( VTIClassName,
75                                                                 ResultSet.TYPE_SCROLL_SENSITIVE == resultSetType);
76             }
77             if( deferralControl.alwaysDefer( statementType))
78                 return true;
79
80             if( source == null && statementType != DeferModification.UPDATE_STATEMENT)
81                 return false;
82
83             VTIDeferModPolicy deferralSearch = new VTIDeferModPolicy( targetVTI,
84                                                                       updateColumnNames,
85                                                                       deferralControl,
86                                                                       statementType);
87
88             if( source != null)
89                 source.accept( deferralSearch);
90
91             if( statementType == DeferModification.UPDATE_STATEMENT)
92             {
93                 // Apply the columnRequiresDefer method to updated columns not in the where clause.
94
Enumeration JavaDoc columns = deferralSearch.columns.keys();
95                 while( columns.hasMoreElements())
96                 {
97                     if( deferralControl.columnRequiresDefer( statementType,
98                                                              (String JavaDoc) columns.nextElement(),
99                                                              false))
100                         return true;
101                 }
102             }
103             return deferralSearch.deferred;
104         }
105         catch( SQLException JavaDoc sqle)
106         {
107             throw StandardException.unexpectedUserException(sqle);
108         }
109     } // end of deferIt
110

111     // state needed to search the statement parse tree for nodes that require deferred modification
112
private boolean deferred = false;
113     private DeferModification deferralControl;
114     private int statementType;
115     private int tableNumber;
116     private Hashtable JavaDoc columns = new Hashtable JavaDoc();
117
118     private VTIDeferModPolicy( FromVTI targetVTI,
119                                String JavaDoc[] columnNames,
120                                DeferModification deferralControl,
121                                int statementType)
122     {
123         this.deferralControl = deferralControl;
124         this.statementType = statementType;
125         tableNumber = targetVTI.getTableNumber();
126         if( statementType == DeferModification.UPDATE_STATEMENT && columnNames != null)
127         {
128             for( int i = 0; i < columnNames.length; i++)
129                 columns.put( columnNames[i], columnNames[i]);
130         }
131     }
132
133     public Visitable visit(Visitable node)
134         throws StandardException
135     {
136         try
137         {
138             if( node instanceof ColumnReference && statementType != DeferModification.INSERT_STATEMENT)
139             {
140                 ColumnReference cr = (ColumnReference) node;
141                 if( cr.getTableNumber() == tableNumber)
142                 {
143                     String JavaDoc columnName = cr.getColumnName();
144                     if( statementType == DeferModification.DELETE_STATEMENT)
145                     {
146                         if( columns.get( columnName) == null)
147                         {
148                             columns.put( columnName, columnName);
149                             if( deferralControl.columnRequiresDefer( statementType, columnName, true))
150                                 deferred = true;
151                         }
152                     }
153                     else if( statementType == DeferModification.UPDATE_STATEMENT)
154                     {
155                         if( columns.get( columnName) != null)
156                         {
157                             // This column is referenced in the where clause and is being updated
158
if( deferralControl.columnRequiresDefer( statementType, columnName, true))
159                                 deferred = true;
160                             columns.remove( columnName); // Only test it once.
161
}
162                     }
163                 }
164             }
165             else if( node instanceof SelectNode)
166             {
167                 SelectNode subSelect = (SelectNode) node;
168                 FromList fromList = subSelect.getFromList();
169
170                 for( int i = 0; i < fromList.size(); i++)
171                 {
172                     FromTable fromTable = (FromTable) fromList.elementAt(i);
173                     if( fromTable instanceof FromBaseTable)
174                     {
175                         TableDescriptor td = fromTable.getTableDescriptor();
176                         if( deferralControl.subselectRequiresDefer( statementType,
177                                                                     td.getSchemaName(),
178                                                                     td.getName()))
179                             deferred = true;
180                     }
181                     else if( fromTable instanceof FromVTI)
182                     {
183                         FromVTI fromVTI = (FromVTI) fromTable;
184                         if( deferralControl.subselectRequiresDefer( statementType,
185                                                                     fromVTI.getNewInvocation().getJavaClassName()))
186                             deferred = true;
187                     }
188                 }
189             }
190         }
191         catch( SQLException JavaDoc sqle)
192         {
193             throw StandardException.unexpectedUserException(sqle);
194         }
195         return node;
196     } // end of visit
197

198     public boolean stopTraversal()
199     {
200         return deferred;
201     } // end of stopTraversal
202

203     public boolean skipChildren(Visitable node)
204     {
205         return false;
206     } // end of skipChildren
207
} // end of class VTIDeferModPolicy
208
Popular Tags