Source Code Cross Referenced for HashScanResultSet.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » sql » execute » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.impl.sql.execute 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Derby - Class org.apache.derby.impl.sql.execute.HashScanResultSet
004:
005:           Licensed to the Apache Software Foundation (ASF) under one or more
006:           contributor license agreements.  See the NOTICE file distributed with
007:           this work for additional information regarding copyright ownership.
008:           The ASF licenses this file to you under the Apache License, Version 2.0
009:           (the "License"); you may not use this file except in compliance with
010:           the License.  You may obtain a copy of the License at
011:
012:              http://www.apache.org/licenses/LICENSE-2.0
013:
014:           Unless required by applicable law or agreed to in writing, software
015:           distributed under the License is distributed on an "AS IS" BASIS,
016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017:           See the License for the specific language governing permissions and
018:           limitations under the License.
019:
020:         */
021:
022:        package org.apache.derby.impl.sql.execute;
023:
024:        import org.apache.derby.iapi.services.loader.GeneratedMethod;
025:
026:        import org.apache.derby.iapi.services.monitor.Monitor;
027:
028:        import org.apache.derby.iapi.services.sanity.SanityManager;
029:
030:        import org.apache.derby.iapi.services.io.Storable;
031:
032:        import org.apache.derby.iapi.services.stream.HeaderPrintWriter;
033:        import org.apache.derby.iapi.services.stream.InfoStreams;
034:
035:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
036:
037:        import org.apache.derby.iapi.error.StandardException;
038:        import org.apache.derby.iapi.services.i18n.MessageService;
039:
040:        import org.apache.derby.iapi.reference.SQLState;
041:
042:        import org.apache.derby.iapi.sql.execute.CursorResultSet;
043:        import org.apache.derby.iapi.sql.execute.ExecIndexRow;
044:        import org.apache.derby.iapi.sql.execute.ExecRow;
045:        import org.apache.derby.iapi.sql.execute.ExecutionContext;
046:        import org.apache.derby.iapi.sql.execute.NoPutResultSet;
047:
048:        import org.apache.derby.iapi.sql.Activation;
049:        import org.apache.derby.iapi.sql.ResultSet;
050:
051:        import org.apache.derby.iapi.store.access.ConglomerateController;
052:        import org.apache.derby.iapi.store.access.Qualifier;
053:        import org.apache.derby.iapi.store.access.RowUtil;
054:        import org.apache.derby.iapi.store.access.ScanController;
055:        import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
056:        import org.apache.derby.iapi.store.access.TransactionController;
057:
058:        import org.apache.derby.iapi.types.DataValueDescriptor;
059:
060:        import org.apache.derby.iapi.types.Orderable;
061:        import org.apache.derby.iapi.types.RowLocation;
062:
063:        import org.apache.derby.iapi.store.access.BackingStoreHashtable;
064:        import org.apache.derby.iapi.services.io.FormatableBitSet;
065:        import org.apache.derby.iapi.services.io.FormatableArrayHolder;
066:        import org.apache.derby.iapi.services.io.FormatableIntHolder;
067:        import org.apache.derby.iapi.store.access.KeyHasher;
068:
069:        import java.util.Enumeration;
070:        import java.util.Properties;
071:        import java.util.Vector;
072:
073:        /**
074:         * Takes a conglomerate and a table filter builds a hash table on the 
075:         * specified column of the conglomerate on the 1st open.  Look up into the
076:         * hash table is done on the hash key column.  The hash table consists of
077:         * either DataValueDescriptor[]s or Vectors of DataValueDescriptor[].  The store builds 
078:         * the hash table.  When a collision occurs, the store builds a Vector with
079:         * the colliding DataValueDescriptor[]s.
080:         *
081:         * @author jerry
082:         */
083:        public class HashScanResultSet extends NoPutResultSetImpl implements 
084:                CursorResultSet {
085:            private boolean hashtableBuilt;
086:            private ExecIndexRow startPosition;
087:            private ExecIndexRow stopPosition;
088:            protected ExecRow candidate; // candidate row is sparse
089:            protected ExecRow compactRow;
090:
091:            // Variable for managing next() logic on hash entry
092:            protected boolean firstNext = true;
093:            private int numFetchedOnNext;
094:            private int entryVectorSize;
095:            private Vector entryVector;
096:
097:            // set in constructor and not altered during
098:            // life of object.
099:            private long conglomId;
100:            protected StaticCompiledOpenConglomInfo scoci;
101:            private GeneratedMethod resultRowAllocator;
102:            private GeneratedMethod startKeyGetter;
103:            private int startSearchOperator;
104:            private GeneratedMethod stopKeyGetter;
105:            private int stopSearchOperator;
106:            public Qualifier[][] scanQualifiers;
107:            public Qualifier[][] nextQualifiers;
108:            private int initialCapacity;
109:            private float loadFactor;
110:            private int maxCapacity;
111:            public String tableName;
112:            public String userSuppliedOptimizerOverrides;
113:            public String indexName;
114:            public boolean forUpdate;
115:            private boolean runTimeStatisticsOn;
116:            private FormatableBitSet accessedCols;
117:            public int isolationLevel;
118:            public int lockMode;
119:            public int[] keyColumns;
120:            private boolean sameStartStopPosition;
121:            private boolean skipNullKeyColumns;
122:
123:            protected BackingStoreHashtable hashtable;
124:            protected boolean eliminateDuplicates; // set to true in DistinctScanResultSet
125:
126:            // Run time statistics
127:            public Properties scanProperties;
128:            public String startPositionString;
129:            public String stopPositionString;
130:            public int hashtableSize;
131:            public boolean isConstraint;
132:
133:            public static final int DEFAULT_INITIAL_CAPACITY = -1;
134:            public static final float DEFAULT_LOADFACTOR = (float) -1.0;
135:            public static final int DEFAULT_MAX_CAPACITY = -1;
136:
137:            //
138:            // class interface
139:            //
140:            HashScanResultSet(long conglomId,
141:                    StaticCompiledOpenConglomInfo scoci, Activation activation,
142:                    GeneratedMethod resultRowAllocator, int resultSetNumber,
143:                    GeneratedMethod startKeyGetter, int startSearchOperator,
144:                    GeneratedMethod stopKeyGetter, int stopSearchOperator,
145:                    boolean sameStartStopPosition,
146:                    Qualifier[][] scanQualifiers, Qualifier[][] nextQualifiers,
147:                    int initialCapacity, float loadFactor, int maxCapacity,
148:                    int hashKeyItem, String tableName,
149:                    String userSuppliedOptimizerOverrides, String indexName,
150:                    boolean isConstraint, boolean forUpdate, int colRefItem,
151:                    int lockMode, boolean tableLocked, int isolationLevel,
152:                    boolean skipNullKeyColumns,
153:                    double optimizerEstimatedRowCount,
154:                    double optimizerEstimatedCost) throws StandardException {
155:                super (activation, resultSetNumber, optimizerEstimatedRowCount,
156:                        optimizerEstimatedCost);
157:                this .scoci = scoci;
158:                this .conglomId = conglomId;
159:
160:                if (SanityManager.DEBUG) {
161:                    SanityManager.ASSERT(activation != null,
162:                            "hash scan must get activation context");
163:                    SanityManager.ASSERT(resultRowAllocator != null,
164:                            "hash scan must get row allocator");
165:                    if (sameStartStopPosition) {
166:                        SanityManager
167:                                .ASSERT(stopKeyGetter == null,
168:                                        "stopKeyGetter expected to be null when sameStartStopPosition is true");
169:                    }
170:                }
171:
172:                this .resultRowAllocator = resultRowAllocator;
173:
174:                this .startKeyGetter = startKeyGetter;
175:                this .startSearchOperator = startSearchOperator;
176:                this .stopKeyGetter = stopKeyGetter;
177:                this .stopSearchOperator = stopSearchOperator;
178:                this .sameStartStopPosition = sameStartStopPosition;
179:                this .scanQualifiers = scanQualifiers;
180:                this .nextQualifiers = nextQualifiers;
181:                this .initialCapacity = initialCapacity;
182:                this .loadFactor = loadFactor;
183:                this .maxCapacity = maxCapacity;
184:                this .tableName = tableName;
185:                this .userSuppliedOptimizerOverrides = userSuppliedOptimizerOverrides;
186:                this .indexName = indexName;
187:                this .isConstraint = isConstraint;
188:                this .forUpdate = forUpdate;
189:                this .skipNullKeyColumns = skipNullKeyColumns;
190:
191:                /* Retrieve the hash key columns */
192:                FormatableArrayHolder fah = (FormatableArrayHolder) (activation
193:                        .getPreparedStatement().getSavedObject(hashKeyItem));
194:                FormatableIntHolder[] fihArray = (FormatableIntHolder[]) fah
195:                        .getArray(FormatableIntHolder.class);
196:                keyColumns = new int[fihArray.length];
197:                for (int index = 0; index < fihArray.length; index++) {
198:                    keyColumns[index] = fihArray[index].getInt();
199:                }
200:
201:                // retrieve the valid column list from
202:                // the saved objects, if it exists
203:                this .accessedCols = null;
204:                if (colRefItem != -1) {
205:                    this .accessedCols = (FormatableBitSet) (activation
206:                            .getPreparedStatement().getSavedObject(colRefItem));
207:                }
208:                this .lockMode = lockMode;
209:
210:                /* Isolation level - translate from language to store */
211:                // If not specified, get current isolation level
212:                if (isolationLevel == ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL) {
213:                    isolationLevel = lcc.getCurrentIsolationLevel();
214:                }
215:
216:                if (isolationLevel == ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL) {
217:                    this .isolationLevel = TransactionController.ISOLATION_SERIALIZABLE;
218:                } else {
219:                    /* NOTE: always do row locking on READ COMMITTED/UNCOMMITTED 
220:                     *       and repeatable read scans unless the table is marked as 
221:                     *       table locked (in sys.systables).
222:                     *
223:                     *		 We always get instantaneous locks as we will complete
224:                     *		 the scan before returning any rows and we will fully
225:                     *		 requalify the row if we need to go to the heap on a next().
226:                     */
227:
228:                    if (!tableLocked) {
229:                        this .lockMode = TransactionController.MODE_RECORD;
230:                    }
231:
232:                    if (isolationLevel == ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL) {
233:                        this .isolationLevel = TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK;
234:                    } else if (isolationLevel == ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL) {
235:                        this .isolationLevel = TransactionController.ISOLATION_READ_UNCOMMITTED;
236:                    } else if (isolationLevel == ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL) {
237:                        this .isolationLevel = TransactionController.ISOLATION_REPEATABLE_READ;
238:                    }
239:                }
240:
241:                if (SanityManager.DEBUG) {
242:                    SanityManager
243:                            .ASSERT(
244:                                    ((isolationLevel == ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL)
245:                                            || (isolationLevel == ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL)
246:                                            || (isolationLevel == ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL) || (isolationLevel == ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL)),
247:
248:                                    "Invalid isolation level - "
249:                                            + isolationLevel);
250:                }
251:
252:                runTimeStatisticsOn = getLanguageConnectionContext()
253:                        .getRunTimeStatisticsMode();
254:
255:                /* Only call row allocators once */
256:                candidate = (ExecRow) resultRowAllocator.invoke(activation);
257:                compactRow = getCompactRow(candidate, accessedCols,
258:                        (FormatableBitSet) null, false);
259:                constructorTime += getElapsedMillis(beginTime);
260:            }
261:
262:            //
263:            // ResultSet interface (leftover from NoPutResultSet)
264:            //
265:
266:            /**
267:             * open a scan on the table. scan parameters are evaluated
268:             * at each open, so there is probably some way of altering
269:             * their values...
270:             *
271:             * @exception StandardException thrown on failure to open
272:             */
273:            public void openCore() throws StandardException {
274:                TransactionController tc;
275:
276:                beginTime = getCurrentTimeMillis();
277:                if (SanityManager.DEBUG)
278:                    SanityManager.ASSERT(!isOpen,
279:                            "HashScanResultSet already open");
280:
281:                // Get the current transaction controller
282:                tc = activation.getTransactionController();
283:
284:                if (startKeyGetter != null) {
285:                    startPosition = (ExecIndexRow) startKeyGetter
286:                            .invoke(activation);
287:                    if (sameStartStopPosition) {
288:                        stopPosition = startPosition;
289:                    }
290:                }
291:                if (stopKeyGetter != null) {
292:                    stopPosition = (ExecIndexRow) stopKeyGetter
293:                            .invoke(activation);
294:                }
295:
296:                // Check whether there are any comparisons with unordered nulls
297:                // on either the start or stop position.  If there are, we can
298:                // (and must) skip the scan, because no rows can qualify
299:                if (skipScan(startPosition, stopPosition)) {
300:                    // Do nothing
301:                    ;
302:                } else if (!hashtableBuilt) {
303:                    DataValueDescriptor[] startPositionRow = startPosition == null ? null
304:                            : startPosition.getRowArray();
305:                    DataValueDescriptor[] stopPositionRow = stopPosition == null ? null
306:                            : stopPosition.getRowArray();
307:
308:                    hashtable = tc
309:                            .createBackingStoreHashtableFromScan(
310:                                    conglomId, // conglomerate to open
311:                                    (forUpdate ? TransactionController.OPENMODE_FORUPDATE
312:                                            : 0), lockMode, isolationLevel,
313:                                    accessedCols, startPositionRow,
314:                                    startSearchOperator, scanQualifiers,
315:                                    stopPositionRow, stopSearchOperator, -1, // no limit on total rows.
316:                                    keyColumns, eliminateDuplicates,// remove duplicates?
317:                                    -1, // RESOLVE - is there a row estimate?
318:                                    maxCapacity, initialCapacity, // in memory Hashtable initial capacity
319:                                    loadFactor, // in memory Hashtable load factor
320:                                    runTimeStatisticsOn, skipNullKeyColumns);
321:
322:                    if (runTimeStatisticsOn) {
323:                        hashtableSize = hashtable.size();
324:
325:                        if (scanProperties == null) {
326:                            scanProperties = new Properties();
327:                        }
328:
329:                        try {
330:                            if (hashtable != null) {
331:                                hashtable.getAllRuntimeStats(scanProperties);
332:                            }
333:                        } catch (StandardException se) {
334:                            // ignore
335:                        }
336:                    }
337:
338:                    /* Remember that we created the hash table */
339:                    hashtableBuilt = true;
340:
341:                    /*
342:                     ** Tell the activation about the number of qualifying rows.
343:                     ** Do this only here, not in reopen, because we don't want
344:                     ** to do this costly operation too often.
345:                     */
346:                    activation.informOfRowCount(this , (long) hashtableSize);
347:                }
348:
349:                isOpen = true;
350:
351:                resetProbeVariables();
352:
353:                numOpens++;
354:                openTime += getElapsedMillis(beginTime);
355:            }
356:
357:            /**
358:             * reopen this ResultSet.
359:             *
360:             * @exception StandardException thrown if cursor finished.
361:             */
362:            public void reopenCore() throws StandardException {
363:                TransactionController tc;
364:
365:                if (SanityManager.DEBUG) {
366:                    SanityManager.ASSERT(isOpen,
367:                            "HashScanResultSet already open");
368:                }
369:
370:                beginTime = getCurrentTimeMillis();
371:
372:                resetProbeVariables();
373:
374:                numOpens++;
375:                openTime += getElapsedMillis(beginTime);
376:            }
377:
378:            private void resetProbeVariables() throws StandardException {
379:                firstNext = true;
380:                numFetchedOnNext = 0;
381:                entryVector = null;
382:                entryVectorSize = 0;
383:
384:                if (nextQualifiers != null) {
385:                    clearOrderableCache(nextQualifiers);
386:                }
387:            }
388:
389:            /**
390:             * Return the next row (if any) from the scan (if open).
391:             *
392:             * @exception StandardException thrown on failure to get next row
393:             */
394:            public ExecRow getNextRowCore() throws StandardException {
395:                ExecRow result = null;
396:                DataValueDescriptor[] columns = null;
397:
398:                beginTime = getCurrentTimeMillis();
399:                if (isOpen && hashtableBuilt) {
400:                    /* We use a do/while loop to ensure that we continue down
401:                     * the duplicate chain, if one exists, until we find a
402:                     * row that matches on all probe predicates (or the
403:                     * duplicate chain is exhausted.)
404:                     */
405:                    do {
406:                        if (firstNext) {
407:                            firstNext = false;
408:
409:                            /* Hash key could be either a single column or multiple columns.
410:                             * If a single column, then it is the datavalue wrapper, otherwise
411:                             * it is a KeyHasher.
412:                             */
413:                            Object hashEntry;
414:                            if (keyColumns.length == 1) {
415:                                hashEntry = hashtable.get(nextQualifiers[0][0]
416:                                        .getOrderable());
417:                            } else {
418:                                KeyHasher mh = new KeyHasher(keyColumns.length);
419:
420:                                if (SanityManager.DEBUG) {
421:                                    SanityManager
422:                                            .ASSERT(nextQualifiers.length == 1);
423:                                }
424:
425:                                for (int index = 0; index < keyColumns.length; index++) {
426:                                    // For hashing only use the AND qualifiers 
427:                                    // located in nextQualifiers[0][0...N], OR 
428:                                    // qualifiers are checked down a bit by calling
429:                                    // qualifyRow on rows returned from hash.
430:
431:                                    DataValueDescriptor dvd = nextQualifiers[0][index]
432:                                            .getOrderable();
433:
434:                                    if (dvd == null) {
435:                                        mh = null;
436:                                        break;
437:                                    }
438:                                    mh.setObject(index,
439:                                            nextQualifiers[0][index]
440:                                                    .getOrderable());
441:                                }
442:                                hashEntry = (mh == null) ? null : hashtable
443:                                        .get(mh);
444:                            }
445:
446:                            if (hashEntry instanceof  Vector) {
447:                                entryVector = (Vector) hashEntry;
448:                                entryVectorSize = entryVector.size();
449:                                columns = (DataValueDescriptor[]) entryVector
450:                                        .firstElement();
451:                            } else {
452:                                entryVector = null;
453:                                entryVectorSize = 0;
454:                                columns = (DataValueDescriptor[]) hashEntry;
455:                            }
456:                        } else if (numFetchedOnNext < entryVectorSize) {
457:                            /* We walking a Vector and there's 
458:                             * more rows left in the vector.
459:                             */
460:                            columns = (DataValueDescriptor[]) entryVector
461:                                    .elementAt(numFetchedOnNext);
462:                        }
463:
464:                        if (columns != null) {
465:                            if (SanityManager.DEBUG) {
466:                                // There used to be an assertion here that the columns
467:                                // array was the same size as the number of columns
468:                                // in the compact row. This assertion no longer holds
469:                                // now that we're doing sparse rows, so I deleted it.
470:
471:                                // Columns is really a Storable[]
472:                                for (int i = 0; i < columns.length; i++) {
473:                                    if (columns[i] != null
474:                                            && !(columns[i] instanceof  Storable)) {
475:                                        SanityManager
476:                                                .THROWASSERT("columns["
477:                                                        + i
478:                                                        + "] expected to be Storable, not "
479:                                                        + columns[i].getClass()
480:                                                                .getName());
481:                                    }
482:                                }
483:                            }
484:
485:                            // See if the entry satisfies all of the other qualifiers
486:
487:                            /* We've already "evaluated" the 1st keyColumns qualifiers 
488:                             * when we probed into the hash table, but we need to 
489:                             * evaluate them again here because of the behavior of 
490:                             * NULLs.  NULLs are treated as equal when building and 
491:                             * probing the hash table so that we only get a single 
492:                             * entry.  However, NULL does not equal NULL, so the 
493:                             * compare() method below will eliminate any row that
494:                             * has a key column containing a NULL.
495:                             *
496:                             * The following code will also evaluate any OR clauses
497:                             * that may exist, while the above hashing does not 
498:                             * include them.
499:                             */
500:
501:                            if (RowUtil.qualifyRow(columns, nextQualifiers)) {
502:                                setCompatRow(compactRow, columns);
503:
504:                                rowsSeen++;
505:
506:                                result = compactRow;
507:                            } else {
508:                                result = null;
509:                            }
510:
511:                            numFetchedOnNext++;
512:                        } else {
513:                            result = null;
514:                        }
515:                    } while (result == null
516:                            && numFetchedOnNext < entryVectorSize);
517:
518:                }
519:
520:                currentRow = result;
521:                setCurrentRow(result);
522:
523:                nextTime += getElapsedMillis(beginTime);
524:                return result;
525:            }
526:
527:            /**
528:             * If the result set has been opened,
529:             * close the open scan.
530:             *
531:             * @exception StandardException thrown on error
532:             */
533:            public void close() throws StandardException {
534:                beginTime = getCurrentTimeMillis();
535:                if (isOpen) {
536:                    // we don't want to keep around a pointer to the
537:                    // row ... so it can be thrown away.
538:                    // REVISIT: does this need to be in a finally
539:                    // block, to ensure that it is executed?
540:                    clearCurrentRow();
541:
542:                    if (hashtableBuilt) {
543:                        // This is where we get the scan properties for a subquery
544:                        scanProperties = getScanProperties();
545:                        // This is where we get the positioner info for inner tables
546:                        if (runTimeStatisticsOn) {
547:                            startPositionString = printStartPosition();
548:                            stopPositionString = printStopPosition();
549:                        }
550:
551:                        // close the hash table, eating any exception
552:                        hashtable.close();
553:                        hashtable = null;
554:                        hashtableBuilt = false;
555:                    }
556:                    startPosition = null;
557:                    stopPosition = null;
558:
559:                    super .close();
560:                } else if (SanityManager.DEBUG)
561:                    SanityManager.DEBUG("CloseRepeatInfo",
562:                            "Close of HashScanResultSet repeated");
563:
564:                closeTime += getElapsedMillis(beginTime);
565:            }
566:
567:            /**
568:             * Return the total amount of time spent in this ResultSet
569:             *
570:             * @param type	CURRENT_RESULTSET_ONLY - time spent only in this ResultSet
571:             *				ENTIRE_RESULTSET_TREE  - time spent in this ResultSet and below.
572:             *
573:             * @return long		The total amount of time spent (in milliseconds).
574:             */
575:            public long getTimeSpent(int type) {
576:                long totTime = constructorTime + openTime + nextTime
577:                        + closeTime;
578:
579:                /* RESOLVE - subtract out store time later, when available */
580:                if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) {
581:                    return totTime;
582:                } else {
583:                    return totTime;
584:                }
585:            }
586:
587:            /**
588:             * @see NoPutResultSet#getScanIsolationLevel
589:             */
590:            public int getScanIsolationLevel() {
591:                return isolationLevel;
592:            }
593:
594:            /**
595:             * @see NoPutResultSet#requiresRelocking
596:             */
597:            public boolean requiresRelocking() {
598:                // IndexRowToBaseRow needs to relock if we didn't keep the lock
599:                return (((isolationLevel == TransactionController.ISOLATION_READ_COMMITTED)
600:                        || (isolationLevel == TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK) || (isolationLevel == TransactionController.ISOLATION_READ_UNCOMMITTED)));
601:
602:            }
603:
604:            //
605:            // CursorResultSet interface
606:            //
607:
608:            /**
609:             * This result set has its row location from
610:             * the last fetch done. If the cursor is closed,
611:             * a null is returned.
612:             *
613:             * @see CursorResultSet
614:             *
615:             * @return the row location of the current cursor row.
616:             * @exception StandardException thrown on failure to get row location
617:             */
618:            public RowLocation getRowLocation() throws StandardException {
619:                if (!isOpen)
620:                    return null;
621:
622:                if (!hashtableBuilt)
623:                    return null;
624:
625:                /* This method should only be called if the last column
626:                 * in the current row is a RowLocation.
627:                 */
628:                if (SanityManager.DEBUG) {
629:                    SanityManager
630:                            .ASSERT(currentRow != null,
631:                                    "There must be a current row when fetching the row location");
632:                    Object rlCandidate = currentRow.getColumn(currentRow
633:                            .nColumns());
634:                    if (!(rlCandidate instanceof  RowLocation)) {
635:                        SanityManager
636:                                .THROWASSERT("rlCandidate expected to be instanceof RowLocation, not "
637:                                        + rlCandidate.getClass().getName());
638:                    }
639:                }
640:
641:                return (RowLocation) currentRow
642:                        .getColumn(currentRow.nColumns());
643:            }
644:
645:            /**
646:             * This result set has its row from the last fetch done. 
647:             * If the cursor is closed, a null is returned.
648:             *
649:             * @see CursorResultSet
650:             *
651:             * @return the last row returned;
652:             * @exception StandardException thrown on failure.
653:             */
654:            /* RESOLVE - this should return activation.getCurrentRow(resultSetNumber),
655:             * once there is such a method.  (currentRow is redundant)
656:             */
657:            public ExecRow getCurrentRow() throws StandardException {
658:                /* Doesn't make sense to call this method for this node since
659:                 * joins are not updatable.
660:                 */
661:                if (SanityManager.DEBUG) {
662:                    SanityManager
663:                            .THROWASSERT("getCurrentRow() not expected to be called for HSRS");
664:                }
665:
666:                return null;
667:            }
668:
669:            public String printStartPosition() {
670:                return printPosition(startSearchOperator, startKeyGetter,
671:                        startPosition);
672:            }
673:
674:            public String printStopPosition() {
675:                if (sameStartStopPosition) {
676:                    return printPosition(stopSearchOperator, startKeyGetter,
677:                            startPosition);
678:                } else {
679:                    return printPosition(stopSearchOperator, stopKeyGetter,
680:                            stopPosition);
681:                }
682:            }
683:
684:            /**
685:             * Return a start or stop positioner as a String.
686:             */
687:            private String printPosition(int searchOperator,
688:                    GeneratedMethod positionGetter, ExecIndexRow eiRow) {
689:                String idt = "";
690:
691:                String output = "";
692:                if (positionGetter == null) {
693:                    return "\t"
694:                            + MessageService.getTextMessage(SQLState.LANG_NONE)
695:                            + "\n";
696:                }
697:
698:                ExecIndexRow positioner = null;
699:
700:                try {
701:                    positioner = (ExecIndexRow) positionGetter
702:                            .invoke(activation);
703:                } catch (StandardException e) {
704:
705:                    if (eiRow == null) {
706:                        return "\t"
707:                                + MessageService
708:                                        .getTextMessage(SQLState.LANG_POSITION_NOT_AVAIL);
709:                    }
710:                    return "\t"
711:                            + MessageService
712:                                    .getTextMessage(SQLState.LANG_UNEXPECTED_EXC_GETTING_POSITIONER)
713:                            + "\n";
714:                }
715:
716:                if (positioner == null) {
717:                    return "\t"
718:                            + MessageService.getTextMessage(SQLState.LANG_NONE)
719:                            + "\n";
720:                }
721:
722:                String searchOp = null;
723:
724:                switch (searchOperator) {
725:                case ScanController.GE:
726:                    searchOp = ">=";
727:                    break;
728:
729:                case ScanController.GT:
730:                    searchOp = ">";
731:                    break;
732:
733:                default:
734:                    if (SanityManager.DEBUG) {
735:                        SanityManager.THROWASSERT("Unknown search operator "
736:                                + searchOperator);
737:                    }
738:
739:                    // This is not internationalized because we should never
740:                    // reach here.
741:                    searchOp = "unknown value (" + searchOperator + ")";
742:                    break;
743:                }
744:
745:                output += "\t"
746:                        + MessageService.getTextMessage(
747:                                SQLState.LANG_POSITIONER, searchOp, String
748:                                        .valueOf(positioner.nColumns())) + "\n";
749:
750:                output += "\t"
751:                        + MessageService
752:                                .getTextMessage(SQLState.LANG_ORDERED_NULL_SEMANTICS)
753:                        + "\n";
754:                for (int position = 0; position < positioner.nColumns(); position++) {
755:                    if (positioner.areNullsOrdered(position)) {
756:                        output = output + position + " ";
757:                    }
758:                }
759:
760:                return output + "\n";
761:            }
762:
763:            public Properties getScanProperties() {
764:                return scanProperties;
765:            }
766:
767:            /**
768:             * Is this ResultSet or it's source result set for update
769:             * 
770:             * @return Whether or not the result set is for update.
771:             */
772:            public boolean isForUpdate() {
773:                return forUpdate;
774:            }
775:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.