KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > sql > execute > BulkTableScanResultSet


1 /*
2
3    Derby - Class org.apache.derby.impl.sql.execute.BulkTableScanResultSet
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.execute;
23
24 import org.apache.derby.iapi.sql.execute.CursorResultSet;
25 import org.apache.derby.iapi.error.StandardException;
26
27 import org.apache.derby.iapi.types.RowLocation;
28 import org.apache.derby.iapi.types.DataValueDescriptor;
29
30 import org.apache.derby.iapi.sql.ResultSet;
31 import org.apache.derby.iapi.sql.execute.ExecRow;
32 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
33 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
34
35 import org.apache.derby.iapi.sql.Activation;
36
37 import org.apache.derby.iapi.store.access.GroupFetchScanController;
38 import org.apache.derby.iapi.store.access.Qualifier;
39 import org.apache.derby.iapi.store.access.ScanController;
40 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
41 import org.apache.derby.iapi.store.access.TransactionController;
42
43 import org.apache.derby.iapi.types.RowLocation;
44
45 import org.apache.derby.iapi.services.sanity.SanityManager;
46 import org.apache.derby.iapi.services.loader.GeneratedMethod;
47
48 import org.apache.derby.iapi.services.io.FormatableBitSet;
49
50 /**
51  * Read a base table or index in bulk. Most of the
52  * work for this method is inherited from TableScanResultSet.
53  * This class overrides getNextRowCore (and extends
54  * re/openCore) to use a row array and fetch rows
55  * from the Store in bulk (using fetchNextGroup).
56  * <p>
57  * Since it retrieves rows in bulk, locking is not
58  * as is usual -- locks may have already been released
59  * on rows as they are returned to the user. Hence,
60  * this ResultSet is not suitable for a query running
61  * Isolation Level 1, cursor stability.
62  * <p>
63  * Note that this code is only accessable from an
64  * optimizer override. If it makes sense to have the
65  * optimizer select bulk reads, then this should
66  * probably be rolled into TableScanResultSet.
67  *
68  * @author jamie
69  */

70 class BulkTableScanResultSet extends TableScanResultSet
71     implements CursorResultSet
72 {
73     private DataValueDescriptor[][] rowArray;
74     private int curRowPosition;
75     private int numRowsInArray;
76
77     private static int OUT_OF_ROWS = 0;
78
79     /**
80      * Constructor. Just save off the rowsPerRead argument
81      * and pass everything else down to TableScanResultSet
82      *
83      * @see org.apache.derby.iapi.sql.execute.ResultSetFactory#getBulkTableScanResultSet
84      *
85      * @exception StandardException thrown on failure to open
86      */

87     BulkTableScanResultSet(long conglomId,
88         StaticCompiledOpenConglomInfo scoci, Activation activation,
89         GeneratedMethod resultRowAllocator,
90         int resultSetNumber,
91         GeneratedMethod startKeyGetter, int startSearchOperator,
92         GeneratedMethod stopKeyGetter, int stopSearchOperator,
93         boolean sameStartStopPosition,
94         Qualifier[][] qualifiers,
95         String JavaDoc tableName,
96         String JavaDoc userSuppliedOptimizerOverrides,
97         String JavaDoc indexName,
98         boolean isConstraint,
99         boolean forUpdate,
100         int colRefItem,
101         int indexColItem,
102         int lockMode,
103         boolean tableLocked,
104         int isolationLevel,
105         int rowsPerRead,
106         boolean oneRowScan,
107         double optimizerEstimatedRowCount,
108         double optimizerEstimatedCost)
109             throws StandardException
110     {
111         super(conglomId,
112             scoci,
113             activation,
114             resultRowAllocator,
115             resultSetNumber,
116             startKeyGetter,
117             startSearchOperator,
118             stopKeyGetter,
119             stopSearchOperator,
120             sameStartStopPosition,
121             qualifiers,
122             tableName,
123             userSuppliedOptimizerOverrides,
124             indexName,
125             isConstraint,
126             forUpdate,
127             colRefItem,
128             indexColItem,
129             lockMode,
130             tableLocked,
131             isolationLevel,
132             rowsPerRead,
133             oneRowScan,
134             optimizerEstimatedRowCount,
135             optimizerEstimatedCost);
136
137         if (SanityManager.DEBUG)
138         {
139             /* Bulk fetch of size 1 is same as a regular table scan
140              * and is supposed to be detected at compile time.
141              */

142             if (rowsPerRead == 1)
143             {
144                 SanityManager.THROWASSERT(
145                     "rowsPerRead not expected to be 1");
146             }
147             /* Bulk table scan implies that scan is not
148              * a 1 row scan.
149              */

150             if (oneRowScan)
151             {
152                 SanityManager.THROWASSERT(
153                     "oneRowScan expected to be false - " +
154                     "rowsPerRead = " + rowsPerRead);
155             }
156         }
157     }
158
159     /**
160      * Open the scan controller
161      *
162      * @param tc transaction controller will open one if null
163      *
164      * @exception StandardException thrown on failure to open
165      */

166     protected void openScanController(TransactionController tc)
167         throws StandardException
168     {
169         DataValueDescriptor[] startPositionRow = startPosition == null ? null : startPosition.getRowArray();
170         DataValueDescriptor[] stopPositionRow = stopPosition == null ? null : stopPosition.getRowArray();
171
172         // Clear the Qualifiers's Orderable cache
173
if (qualifiers != null)
174         {
175             clearOrderableCache(qualifiers);
176         }
177
178         // Get the current transaction controller
179
if (tc == null)
180             tc = activation.getTransactionController();
181         scanController = tc.openCompiledScan(
182                 activation.getResultSetHoldability(),
183                 (forUpdate ? TransactionController.OPENMODE_FORUPDATE : 0),
184                 lockMode,
185                 isolationLevel,
186                 accessedCols,
187                 startPositionRow,
188                     // not used when giving null start position
189
startSearchOperator,
190                 qualifiers,
191                 stopPositionRow,
192                     // not used when giving null stop position
193
stopSearchOperator,
194                 scoci,
195                 dcoci);
196
197         /* Remember that we opened the scan */
198         scanControllerOpened = true;
199
200         rowsThisScan = 0;
201
202         /*
203         ** Inform the activation of the estimated number of rows. Only
204         ** do it here, not in reopen, so that we don't do this costly
205         ** check too often.
206         */

207         activation.informOfRowCount(
208                                     this,
209                                     scanController.getEstimatedRowCount()
210                                     );
211     }
212
213     /**
214      * Open up the result set. Delegate
215      * most work to TableScanResultSet.openCore().
216      * Create a new array with <rowsPerRead> rows
217      * for use in fetchNextGroup().
218      *
219      * @exception StandardException thrown on failure to open
220      */

221     public void openCore() throws StandardException
222     {
223         super.openCore();
224         /*
225         ** Add the extra time we spent after
226         ** the super class -- TableScanResultSet()
227         ** already added up its time in openCore().
228         */

229         beginTime = getCurrentTimeMillis();
230         rowArray = new DataValueDescriptor[rowsPerRead][];
231
232         // we only allocate the first row -- the
233
// store clones as needed for the rest
234
// of the rows
235
rowArray[0] = candidate.getRowArrayClone();
236         numRowsInArray = 0;
237         curRowPosition = -1;
238         
239         openTime += getElapsedMillis(beginTime);
240     }
241
242     /**
243      * Reopen the result set. Delegate
244      * most work to TableScanResultSet.reopenCore().
245      * Reuse the array of rows.
246      *
247      * @exception StandardException thrown on failure to open
248      */

249     public void reopenCore() throws StandardException
250     {
251         super.reopenCore();
252         numRowsInArray = 0;
253         curRowPosition = -1;
254     }
255         
256     /**
257      * Return the next row (if any) from the scan (if open).
258      * Reload the rowArray as necessary.
259      *
260      * @exception StandardException thrown on failure to get next row
261      */

262     public ExecRow getNextRowCore() throws StandardException
263     {
264         ExecRow result = null;
265             
266         checkCancellationFlag();
267
268         beginTime = getCurrentTimeMillis();
269         if (isOpen && scanControllerOpened)
270         {
271             if (currentRow == null)
272             {
273                 currentRow =
274                     getCompactRow(candidate,
275                                     accessedCols,
276                                     (FormatableBitSet) null,
277                                     isKeyed);
278             }
279
280 outer: for (;;)
281             {
282                 if (curRowPosition >= numRowsInArray - 1)
283                 {
284                     if (reloadArray() == OUT_OF_ROWS)
285                     {
286                         setCurrentRow(null);
287                         setRowCountIfPossible(rowsThisScan);
288                         return null;
289                     }
290                 }
291
292                 while (++curRowPosition < numRowsInArray)
293                 {
294                     candidate.setRowArray(rowArray[curRowPosition]);
295                     currentRow = setCompactRow(candidate, currentRow);
296                     rowsSeen++;
297                     rowsThisScan++;
298
299                     /*
300                     ** Skip rows where there are start or stop positioners
301                     ** that do not implement ordered null semantics and
302                     ** there are columns in those positions that contain
303                     ** null.
304                     */

305                     if (skipRow(candidate))
306                     {
307                         rowsFiltered++;
308                         continue;
309                     }
310
311                     result = currentRow;
312                     break outer;
313                 }
314             }
315         }
316
317         setCurrentRow(result);
318         nextTime += getElapsedMillis(beginTime);
319         return result;
320     }
321
322     /*
323     ** Load up rowArray with a batch of
324     ** rows.
325     */

326     private int reloadArray() throws StandardException
327     {
328         curRowPosition = -1;
329         numRowsInArray =
330                 ((GroupFetchScanController) scanController).fetchNextGroup(
331                                                rowArray, (RowLocation[]) null);
332
333         return numRowsInArray;
334
335     }
336     /**
337      * If the result set has been opened,
338      * close the open scan. Delegate most
339      * of the work to TableScanResultSet.
340      *
341      * @exception StandardException on error
342      */

343     public void close() throws StandardException
344     {
345         /*
346         ** We'll let TableScanResultSet track
347         ** the time it takes to close up, so
348         ** no timing here.
349         */

350         super.close();
351         numRowsInArray = -1;
352         curRowPosition = -1;
353         rowArray = null;
354     }
355
356     /**
357      * Can we get instantaneous locks when getting share row
358      * locks at READ COMMITTED.
359      */

360     protected boolean canGetInstantaneousLocks()
361     {
362         return true;
363     }
364
365     /**
366      * @see NoPutResultSet#requiresRelocking
367      */

368     public boolean requiresRelocking()
369     {
370         // IndexRowToBaseRow needs to relock if we didn't keep the lock
371
return(
372           isolationLevel == TransactionController.ISOLATION_READ_COMMITTED ||
373           isolationLevel == TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK ||
374           isolationLevel == TransactionController.ISOLATION_READ_UNCOMMITTED);
375     }
376 }
377
Popular Tags