1 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 import org.apache.derby.iapi.services.i18n.MessageService; 27 28 import org.apache.derby.iapi.sql.Activation; 29 import org.apache.derby.iapi.sql.ResultSet; 30 import org.apache.derby.iapi.sql.execute.ExecRow; 31 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 32 import org.apache.derby.iapi.sql.execute.ExecutionContext; 33 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 34 import org.apache.derby.iapi.sql.execute.TemporaryRowHolder; 35 36 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 37 38 import org.apache.derby.iapi.store.access.ConglomerateController; 39 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 40 import org.apache.derby.iapi.store.access.Qualifier; 41 import org.apache.derby.iapi.store.access.ScanController; 42 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 43 import org.apache.derby.iapi.store.access.TransactionController; 44 45 import org.apache.derby.iapi.types.DataValueDescriptor; 46 47 import org.apache.derby.iapi.types.Orderable; 48 import org.apache.derby.iapi.types.RowLocation; 49 50 import org.apache.derby.iapi.services.sanity.SanityManager; 51 52 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 53 import org.apache.derby.iapi.services.stream.InfoStreams; 54 55 import org.apache.derby.iapi.services.monitor.Monitor; 56 57 import org.apache.derby.iapi.services.loader.GeneratedMethod; 58 import org.apache.derby.iapi.services.io.FormatableBitSet; 59 60 import org.apache.derby.iapi.reference.SQLState; 61 62 import java.util.Properties ; 63 import java.util.Hashtable ; 64 65 75 class TableScanResultSet extends NoPutResultSetImpl 76 implements CursorResultSet, Cloneable 77 { 78 protected ScanController scanController; 79 protected boolean scanControllerOpened; 80 protected boolean isKeyed; 81 protected boolean firstScan = true; 82 protected ExecIndexRow startPosition; 83 protected ExecIndexRow stopPosition; 84 protected ExecRow candidate; 85 86 protected long conglomId; 89 protected DynamicCompiledOpenConglomInfo dcoci; 90 protected StaticCompiledOpenConglomInfo scoci; 91 protected GeneratedMethod resultRowAllocator; 92 protected GeneratedMethod startKeyGetter; 93 protected int startSearchOperator; 94 protected GeneratedMethod stopKeyGetter; 95 protected int stopSearchOperator; 96 public Qualifier[][] qualifiers; 97 public String tableName; 98 public String userSuppliedOptimizerOverrides; 99 public String indexName; 100 protected boolean runTimeStatisticsOn; 101 protected FormatableBitSet accessedCols; 102 protected int[] indexCols; public int rowsPerRead; 104 public boolean forUpdate; 105 private boolean sameStartStopPosition; 106 private boolean nextDone; 107 private RowLocation rlTemplate; 108 109 public int isolationLevel; 110 public int lockMode; 111 112 private Properties scanProperties; 114 public String startPositionString; 115 public String stopPositionString; 116 public boolean isConstraint; 117 public boolean coarserLock; 118 public boolean oneRowScan; 119 120 protected long rowsThisScan; 121 122 private long estimatedRowCount; 123 124 130 protected Hashtable past2FutureTbl; 131 protected TemporaryRowHolder futureForUpdateRows; protected TemporaryRowHolderResultSet futureRowResultSet; protected boolean skipFutureRowHolder; protected boolean sourceDrained; protected boolean currentRowPrescanned; protected boolean compareToLastKey; protected ExecRow lastCursorKey; 138 private ExecRow sparseRow; private FormatableBitSet sparseRowMap; 141 private boolean qualify; 145 146 private boolean currentRowIsValid; 151 152 private boolean scanRepositioned; 155 156 TableScanResultSet(long conglomId, 160 StaticCompiledOpenConglomInfo scoci, 161 Activation activation, 162 GeneratedMethod resultRowAllocator, 163 int resultSetNumber, 164 GeneratedMethod startKeyGetter, int startSearchOperator, 165 GeneratedMethod stopKeyGetter, int stopSearchOperator, 166 boolean sameStartStopPosition, 167 Qualifier[][] qualifiers, 168 String tableName, 169 String userSuppliedOptimizerOverrides, 170 String indexName, 171 boolean isConstraint, 172 boolean forUpdate, 173 int colRefItem, 174 int indexColItem, 175 int lockMode, 176 boolean tableLocked, 177 int isolationLevel, 178 int rowsPerRead, 179 boolean oneRowScan, 180 double optimizerEstimatedRowCount, 181 double optimizerEstimatedCost) 182 throws StandardException 183 { 184 super(activation, 185 resultSetNumber, 186 optimizerEstimatedRowCount, 187 optimizerEstimatedCost); 188 189 this.conglomId = conglomId; 190 191 196 this.scoci = scoci; 197 198 if (SanityManager.DEBUG) { 199 SanityManager.ASSERT( activation!=null, "table scan must get activation context"); 200 SanityManager.ASSERT( resultRowAllocator!= null, "table scan must get row allocator"); 201 if (sameStartStopPosition) 202 { 203 SanityManager.ASSERT(stopKeyGetter == null, 204 "stopKeyGetter expected to be null when sameStartStopPosition is true"); 205 } 206 } 207 208 this.resultRowAllocator = resultRowAllocator; 209 210 this.startKeyGetter = startKeyGetter; 211 this.startSearchOperator = startSearchOperator; 212 this.stopKeyGetter = stopKeyGetter; 213 this.stopSearchOperator = stopSearchOperator; 214 this.sameStartStopPosition = sameStartStopPosition; 215 this.qualifiers = qualifiers; 216 this.tableName = tableName; 217 this.userSuppliedOptimizerOverrides = userSuppliedOptimizerOverrides; 218 this.indexName = indexName; 219 this.isConstraint = isConstraint; 220 this.forUpdate = forUpdate; 221 this.rowsPerRead = rowsPerRead; 222 this.oneRowScan = oneRowScan; 223 224 this.accessedCols = null; 227 if (colRefItem != -1) 228 { 229 this.accessedCols = (FormatableBitSet)(activation.getPreparedStatement(). 230 getSavedObject(colRefItem)); 231 } 232 if (indexColItem != -1) 233 { 234 this.indexCols = (int[])(activation.getPreparedStatement(). 235 getSavedObject(indexColItem)); 236 } 237 if (indexCols != null) 238 activation.setForUpdateIndexScan(this); 239 240 this.lockMode = lockMode; 241 242 243 if (isolationLevel == ExecutionContext.UNSPECIFIED_ISOLATION_LEVEL) 245 { 246 isolationLevel = lcc.getCurrentIsolationLevel(); 247 } 248 249 if (isolationLevel == ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL) 250 { 251 this.isolationLevel = TransactionController.ISOLATION_SERIALIZABLE; 252 } 253 else 254 { 255 261 262 270 271 if (! tableLocked) 272 { 273 this.lockMode = TransactionController.MODE_RECORD; 274 } 275 276 if (isolationLevel == 277 ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL) 278 { 279 285 if ((! forUpdate) && canGetInstantaneousLocks()) 286 { 287 this.isolationLevel = 288 TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK; 289 } 290 else 291 { 292 this.isolationLevel = 293 TransactionController.ISOLATION_READ_COMMITTED; 294 } 295 } 296 else if (isolationLevel == 297 ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL) 298 { 299 this.isolationLevel = 300 TransactionController.ISOLATION_READ_UNCOMMITTED; 301 } 302 else if (isolationLevel == 303 ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL) 304 { 305 this.isolationLevel = 306 TransactionController.ISOLATION_REPEATABLE_READ; 307 } 308 } 309 310 if (SanityManager.DEBUG) 311 { 312 SanityManager.ASSERT( 313 ((isolationLevel == 314 ExecutionContext.READ_COMMITTED_ISOLATION_LEVEL) || 315 (isolationLevel == 316 ExecutionContext.READ_UNCOMMITTED_ISOLATION_LEVEL) || 317 (isolationLevel == 318 ExecutionContext.REPEATABLE_READ_ISOLATION_LEVEL) || 319 (isolationLevel == 320 ExecutionContext.SERIALIZABLE_ISOLATION_LEVEL)), 321 322 "Invalid isolation level - " + isolationLevel); 323 } 324 325 runTimeStatisticsOn = (activation != null && 326 activation.getLanguageConnectionContext().getRunTimeStatisticsMode()); 327 328 329 candidate = (ExecRow) resultRowAllocator.invoke(activation); 330 constructorTime += getElapsedMillis(beginTime); 331 332 333 qualify = true; 334 currentRowIsValid = false; 335 scanRepositioned = false; 336 } 337 338 342 349 public void openCore() throws StandardException 350 { 351 if (SanityManager.DEBUG) 352 SanityManager.ASSERT( ! isOpen, "TableScanResultSet already open"); 353 354 TransactionController tc = activation.getTransactionController(); 356 357 if (dcoci == null) 358 dcoci = tc.getDynamicCompiledConglomInfo(conglomId); 359 360 361 if (startKeyGetter != null) 362 { 363 startPosition = (ExecIndexRow) startKeyGetter.invoke(activation); 364 if (sameStartStopPosition) 365 { 366 stopPosition = startPosition; 367 } 368 } 369 if (stopKeyGetter != null) 370 { 371 stopPosition = (ExecIndexRow) stopKeyGetter.invoke(activation); 372 } 373 374 377 378 if (firstScan) 386 { 387 openScanController(tc); 388 389 isKeyed = scanController.isKeyed(); 390 391 399 if (SanityManager.DEBUG) 400 { 401 if (SanityManager.DEBUG_ON("ScanTrace")) 402 { 403 } 405 } 406 } 407 408 if (skipScan(startPosition, stopPosition)) 412 { 413 scanControllerOpened = false; 414 } 415 419 else if (! firstScan) 420 { 421 openScanController(tc); 422 } 423 424 430 if (forUpdate && isKeyed) 431 { 432 activation.setIndexScanController(scanController); 433 activation.setIndexConglomerateNumber(conglomId); 434 } 435 436 firstScan = false; 437 isOpen = true; 438 numOpens++; 439 nextDone = false; 440 openTime += getElapsedMillis(beginTime); 441 } 442 443 448 protected void openScanController(TransactionController tc) 449 throws StandardException 450 { 451 DataValueDescriptor[] startPositionRow = 452 startPosition == null ? null : startPosition.getRowArray(); 453 DataValueDescriptor[] stopPositionRow = 454 stopPosition == null ? null : stopPosition.getRowArray(); 455 456 if (qualifiers != null) 458 { 459 clearOrderableCache(qualifiers); 460 } 461 462 if (tc == null) 464 tc = activation.getTransactionController(); 465 466 int openMode = 0; 467 if (forUpdate) 468 { 469 openMode = TransactionController.OPENMODE_FORUPDATE; 470 471 if (activation.isCursorActivation()) 472 openMode |= TransactionController.OPENMODE_USE_UPDATE_LOCKS; 473 } 474 475 scanController = tc.openCompiledScan( 476 activation.getResultSetHoldability(), 477 openMode, 478 lockMode, 479 isolationLevel, 480 accessedCols, 481 startPositionRow, 482 startSearchOperator, 484 qualifiers, 485 stopPositionRow, 486 stopSearchOperator, 488 scoci, 489 dcoci); 490 491 492 scanControllerOpened = true; 493 494 rowsThisScan = 0; 495 496 501 estimatedRowCount = scanController.getEstimatedRowCount(); 502 activation.informOfRowCount( 503 this, 504 scanController.getEstimatedRowCount() 505 ); 506 } 507 508 511 private void reopenScanController() 512 throws StandardException 513 { 514 DataValueDescriptor[] startPositionRow = 515 startPosition == null ? null : startPosition.getRowArray(); 516 DataValueDescriptor[] stopPositionRow = 517 stopPosition == null ? null : stopPosition.getRowArray(); 518 519 if (qualifiers != null) 521 { 522 clearOrderableCache(qualifiers); 523 } 524 525 scanController.reopenScan( 526 startPositionRow, 527 startSearchOperator, 528 qualifiers, 529 stopPositionRow, 530 stopSearchOperator); 531 532 533 scanControllerOpened = true; 534 535 rowsThisScan = 0; 536 } 537 538 546 public void reopenCore() throws StandardException 547 { 548 beginTime = getCurrentTimeMillis(); 549 if (SanityManager.DEBUG) 550 SanityManager.ASSERT(isOpen, "TableScanResultSet not open, cannot reopen"); 551 552 if (startKeyGetter != null) 553 { 554 startPosition = (ExecIndexRow) startKeyGetter.invoke(activation); 555 if (sameStartStopPosition) 556 { 557 stopPosition = startPosition; 558 } 559 } 560 if (stopKeyGetter != null) 561 { 562 stopPosition = (ExecIndexRow) stopKeyGetter.invoke(activation); 563 } 564 565 if (skipScan(startPosition, stopPosition)) 569 { 570 scanControllerOpened = false; 571 } 572 else 573 { 574 if (scanController == null) 575 openScanController((TransactionController)null); 576 else 577 reopenScanController(); 578 579 } 580 581 numOpens++; 582 nextDone = false; 583 openTime += getElapsedMillis(beginTime); 584 } 585 586 592 private void getSparseRowAndMap() throws StandardException 593 { 594 int numCols = 1, colPos; 595 for (int i = 0; i < indexCols.length; i++) 596 { 597 colPos = (indexCols[i] > 0) ? indexCols[i] : -indexCols[i]; 598 if (colPos > numCols) 599 numCols = colPos; 600 } 601 sparseRow = new ValueRow(numCols); 602 sparseRowMap = new FormatableBitSet(numCols); 603 for (int i = 0; i < indexCols.length; i++) 604 { 605 if (accessedCols.get(i)) 606 { 607 colPos = (indexCols[i] > 0) ? indexCols[i] : -indexCols[i]; 608 sparseRow.setColumn(colPos, candidate.getColumn(i + 1)); 609 sparseRowMap.set(colPos - 1); 610 } 611 } 612 } 613 614 615 620 public ExecRow getNextRowCore() throws StandardException 621 { 622 checkCancellationFlag(); 623 624 if (currentRow == null || scanRepositioned) 625 { 626 currentRow = 627 getCompactRow(candidate, accessedCols, (FormatableBitSet) null, isKeyed); 628 } 629 630 beginTime = getCurrentTimeMillis(); 631 632 ExecRow result = null; 633 634 638 if (futureForUpdateRows != null) 639 { 640 currentRowPrescanned = false; 641 if (! skipFutureRowHolder) 642 { 643 if (futureRowResultSet == null) 644 { 645 futureRowResultSet = (TemporaryRowHolderResultSet) futureForUpdateRows.getResultSet(); 646 futureRowResultSet.openCore(); 647 } 648 649 ExecRow ridRow = futureRowResultSet.getNextRowCore(); 650 651 if (ridRow != null) 652 { 653 657 futureRowResultSet.deleteCurrentRow(); 658 RowLocation rl = (RowLocation) ridRow.getColumn(1); 659 ConglomerateController baseCC = activation.getHeapConglomerateController(); 660 if (sparseRow == null) 661 getSparseRowAndMap(); 662 baseCC.fetch( 663 rl, sparseRow.getRowArray(), sparseRowMap); 664 RowLocation rl2 = (RowLocation) rl.getClone(); 665 currentRow.setColumn(currentRow.nColumns(), rl2); 666 candidate.setColumn(candidate.nColumns(), rl2); 668 result = currentRow; 669 currentRowPrescanned = true; 670 } 671 else if (sourceDrained) 672 { 673 currentRowPrescanned = true; 674 currentRow = null; 675 } 676 677 if (currentRowPrescanned) 678 { 679 setCurrentRow(result); 680 681 nextTime += getElapsedMillis(beginTime); 682 return result; 683 } 684 } 685 } 686 687 if ( isOpen && !nextDone) 688 { 689 692 nextDone = oneRowScan; 693 694 if (scanControllerOpened) 695 { 696 boolean moreRows; 697 698 while (moreRows = 699 scanController.fetchNext(candidate.getRowArray())) 700 { 701 rowsSeen++; 702 rowsThisScan++; 703 704 713 if ((! sameStartStopPosition) && skipRow(candidate)) 714 { 715 rowsFiltered++; 716 continue; 717 } 718 719 724 if (past2FutureTbl != null) 725 { 726 RowLocation rowLoc = (RowLocation) currentRow.getColumn(currentRow.nColumns()); 727 if (past2FutureTbl.get(rowLoc) != null) 728 { 729 past2FutureTbl.remove(rowLoc); 730 continue; 731 } 732 } 733 734 result = currentRow; 735 736 break; 737 } 738 739 751 if (! moreRows) 752 { 753 setRowCountIfPossible(rowsThisScan); 754 currentRow = null; 755 } 756 } 757 } 758 759 setCurrentRow(result); 760 currentRowIsValid = true; 761 scanRepositioned = false; 762 qualify = true; 763 764 nextTime += getElapsedMillis(beginTime); 765 return result; 766 } 767 768 773 public void close() throws StandardException 774 { 775 beginTime = getCurrentTimeMillis(); 776 if ( isOpen ) 777 { 778 782 if (SanityManager.DEBUG) 783 { 784 if (SanityManager.DEBUG_ON("ScanTrace")) 785 { 786 } 788 } 789 790 clearCurrentRow(); 795 ; 796 if (scanController != null) 797 { 798 if (runTimeStatisticsOn) 800 { 801 scanProperties = getScanProperties(); 803 startPositionString = printStartPosition(); 804 stopPositionString = printStopPosition(); 805 } 806 scanController.close(); 807 scanController = null; activation.clearIndexScanInfo(); 809 } 810 scanControllerOpened = false; 811 startPosition = null; 812 stopPosition = null; 813 814 super.close(); 815 816 if (indexCols != null) 817 { 818 ConglomerateController borrowedBaseCC = activation.getHeapConglomerateController(); 819 if (borrowedBaseCC != null) 820 { 821 borrowedBaseCC.close(); 822 activation.clearHeapConglomerateController(); 823 } 824 } 825 if (futureRowResultSet != null) 826 futureRowResultSet.close(); 827 } 828 else 829 if (SanityManager.DEBUG) 830 SanityManager.DEBUG("CloseRepeatInfo","Close of TableScanResultSet repeated"); 831 832 closeTime += getElapsedMillis(beginTime); 833 } 834 835 843 public long getTimeSpent(int type) 844 { 845 long totTime = constructorTime + openTime + nextTime + closeTime; 846 847 848 if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) 849 { 850 return totTime; 851 } 852 else 853 { 854 return totTime; 855 } 856 } 857 858 859 863 873 public RowLocation getRowLocation() throws StandardException 874 { 875 RowLocation rl; 876 877 if (! isOpen) return null; 878 879 if ( ! scanControllerOpened) 880 return null; 881 882 887 if (isKeyed) 888 { 889 if (SanityManager.DEBUG) 890 { 891 SanityManager.ASSERT(currentRow != null, 892 "There must be a current row when fetching the row location"); 893 } 894 895 rl = (RowLocation) currentRow.getColumn( 896 currentRow.nColumns()); 897 } 898 else 899 { 900 if (currentRowIsValid) { 901 if (rlTemplate == null) 903 rlTemplate = scanController.newRowLocationTemplate(); 904 rl = rlTemplate; 905 try { 906 scanController.fetchLocation(rl); 907 } catch (StandardException se) { 908 if (se.getMessageId(). 909 equals(SQLState.HEAP_SCAN_NOT_POSITIONED)) { 910 throw StandardException. 913 newException(SQLState.NO_CURRENT_ROW); 914 } 915 throw se; 916 } 917 } else { 918 rl = null; 919 } 920 } 921 922 return rl; 923 } 924 925 936 939 public ExecRow getCurrentRow() throws StandardException 940 { 941 ExecRow result = null; 942 943 if (SanityManager.DEBUG) 944 SanityManager.ASSERT(isOpen, "TSRS expected to be open"); 945 946 if (currentRowPrescanned) 947 return currentRow; 948 949 955 try 956 { 957 if ((currentRow == null) || 958 (!currentRowIsValid) || 959 (!scanControllerOpened) || 960 (qualify && scanController.isCurrentPositionDeleted()) || 961 (qualify && (!scanController.doesCurrentPositionQualify()))) 962 { 963 return null; 964 } 965 } 966 catch (StandardException se) 967 { 968 if (se.getMessageId().equals(SQLState.AM_SCAN_NOT_POSITIONED)) 969 { 970 se=StandardException.newException(SQLState.NO_CURRENT_ROW); 972 throw se; 973 } 974 } 975 976 result = (ExecRow) resultRowAllocator.invoke(activation); 977 currentRow = 978 getCompactRow(result, accessedCols, (FormatableBitSet) null, isKeyed); 979 980 try 981 { 982 scanController.fetchWithoutQualify(result.getRowArray()); 983 } 984 catch (StandardException se) 985 { 986 if (se.getMessageId().equals(SQLState.AM_RECORD_NOT_FOUND)) 987 { 988 return null; 992 } 993 else 994 { 995 throw se; 996 } 997 } 998 999 setCurrentRow(result); 1000 return currentRow; 1001 } 1002 1003 1009 public void positionScanAtRowLocation(RowLocation rl) 1010 throws StandardException 1011 { 1012 if (!isKeyed) { 1015 currentRowIsValid = scanController.positionAtRowLocation(rl); 1016 } 1017 qualify = false; 1018 scanRepositioned = true; 1019 } 1020 1021 1025 1060 1061 1064 1101 1102 1105 1175 1176 1177 1180 1253 1254 public String printStartPosition() 1255 { 1256 return printPosition(startSearchOperator, startKeyGetter, startPosition); 1257 } 1258 1259 public String printStopPosition() 1260 { 1261 if (sameStartStopPosition) 1262 { 1263 return printPosition(stopSearchOperator, startKeyGetter, startPosition); 1264 } 1265 else 1266 { 1267 return printPosition(stopSearchOperator, stopKeyGetter, stopPosition); 1268 } 1269 } 1270 1271 1277 private String printPosition(int searchOperator, 1278 GeneratedMethod positionGetter, 1279 ExecIndexRow positioner) 1280 { 1281 String idt = ""; 1282 String output = ""; 1283 if (positionGetter == null) 1284 { 1285 return "\t" + 1286 MessageService.getTextMessage(SQLState.LANG_NONE) + 1287 "\n"; 1288 } 1289 1290 if (positioner == null) 1291 { 1292 try 1293 { 1294 positioner = (ExecIndexRow)positionGetter.invoke(activation); 1295 } 1296 catch (StandardException e) 1297 { 1298 if (e.getSQLState() == SQLState.LANG_UNEXPECTED_USER_EXCEPTION ) 1303 return "\t" + MessageService.getTextMessage( 1304 SQLState.LANG_POSITION_NOT_AVAIL); 1305 return "\t" + MessageService.getTextMessage( 1306 SQLState.LANG_UNEXPECTED_EXC_GETTING_POSITIONER, 1307 e.toString()); 1308 } 1309 } 1310 if (positioner == null) 1311 { 1312 return "\t" + 1313 MessageService.getTextMessage(SQLState.LANG_NONE) + 1314 "\n"; 1315 } 1316 String searchOp = null; 1317 1318 switch (searchOperator) 1319 { 1320 case ScanController.GE: 1321 searchOp = ">="; 1322 break; 1323 1324 case ScanController.GT: 1325 searchOp = ">"; 1326 break; 1327 1328 default: 1329 if (SanityManager.DEBUG) 1330 { 1331 SanityManager.THROWASSERT("Unknown search operator " + 1332 searchOperator); 1333 } 1334 1335 searchOp = "unknown value (" + searchOperator + ")"; 1338 break; 1339 } 1340 1341 output = output + "\t" + 1342 MessageService.getTextMessage( 1343 SQLState.LANG_POSITIONER, 1344 searchOp, 1345 String.valueOf(positioner.nColumns())) + 1346 "\n"; 1347 1348 output = output + "\t" + 1349 MessageService.getTextMessage( 1350 SQLState.LANG_ORDERED_NULL_SEMANTICS) + 1351 "\n"; 1352 for (int position = 0; position < positioner.nColumns(); position++) 1353 { 1354 if (positioner.areNullsOrdered(position)) 1355 { 1356 output = output + position + " "; 1357 } 1358 } 1359 1360 return output + "\n"; 1361 } 1362 1363 public Properties getScanProperties() 1364 { 1365 if (scanProperties == null) 1366 { 1367 scanProperties = new Properties (); 1368 } 1369 try 1370 { 1371 if (scanController != null) 1372 { 1373 scanController.getScanInfo().getAllScanInfo(scanProperties); 1374 1378 coarserLock = scanController.isTableLocked() && 1379 (lockMode == TransactionController.MODE_RECORD); 1380 } 1381 } 1382 catch(StandardException se) 1383 { 1384 } 1386 1387 return scanProperties; 1388 } 1389 1390 1393 public int getScanIsolationLevel() 1394 { 1395 return isolationLevel; 1396 } 1397 1398 1401 public boolean requiresRelocking() 1402 { 1403 return( 1404 isolationLevel == 1405 TransactionController.ISOLATION_READ_COMMITTED_NOHOLDLOCK); 1406 } 1407 1408 1424 protected final void setRowCountIfPossible(long rowsThisScan) 1425 throws StandardException 1426 { 1427 1432 if ( ( ! scanController.isKeyed() ) && 1433 (qualifiers == null || qualifiers.length == 0) && 1434 ( ! forUpdate ) ) 1435 { 1436 1437 long diff = rowsThisScan - estimatedRowCount; 1439 1440 long tenPerCent = estimatedRowCount / 10; 1441 1442 if (diff < 0) 1443 diff = -diff; 1444 1445 if (diff > tenPerCent) 1446 scanController.setEstimatedRowCount(rowsThisScan); 1447 } 1448 } 1449 1450 1454 protected boolean canGetInstantaneousLocks() 1455 { 1456 return false; 1457 } 1458 1459 1460 1465 public boolean isForUpdate() 1466 { 1467 return forUpdate; 1468 } 1469 1470 1474 public Object clone() 1475 { 1476 Object clo = null; 1477 try { 1478 clo = super.clone(); 1479 } 1480 catch (CloneNotSupportedException e) {} 1481 return clo; 1482 } 1483} 1484 | Popular Tags |