1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.sanity.SanityManager; 25 import org.apache.derby.iapi.error.StandardException; 26 import org.apache.derby.iapi.types.DataValueFactory; 27 import org.apache.derby.iapi.types.RowLocation; 28 import org.apache.derby.iapi.sql.execute.ExecRow; 29 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 30 import org.apache.derby.iapi.sql.execute.ScanQualifier; 31 import org.apache.derby.iapi.store.access.ConglomerateController; 32 import org.apache.derby.iapi.store.access.ScanController; 33 import org.apache.derby.iapi.store.access.TransactionController; 34 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 35 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 36 import org.apache.derby.iapi.sql.execute.CursorResultSet; 37 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 38 import org.apache.derby.iapi.sql.Activation; 39 import org.apache.derby.iapi.types.RefDataValue; 40 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 41 import org.apache.derby.iapi.services.io.FormatableBitSet; 42 import org.apache.derby.iapi.services.loader.GeneratedMethod; 43 import org.apache.derby.iapi.store.access.Qualifier; 44 import org.apache.derby.iapi.sql.execute.ExecutionContext; 45 import org.apache.derby.iapi.sql.execute.TemporaryRowHolder; 46 import java.util.Vector ; 47 import java.util.Properties ; 48 import org.apache.derby.iapi.reference.SQLState; 49 import org.apache.derby.iapi.services.i18n.MessageService; 50 51 52 53 61 class DependentResultSet extends NoPutResultSetImpl implements CursorResultSet 62 { 63 64 65 ConglomerateController heapCC; 66 RowLocation baseRowLocation; ExecRow indexRow; IndexRow indexQualifierRow; ScanController indexSC; StaticCompiledOpenConglomInfo indexScoci; 71 DynamicCompiledOpenConglomInfo indexDcoci; 72 int numFkColumns; 73 boolean isOpen; boolean deferred; 75 TemporaryRowHolderResultSet source; TransactionController tc; 77 String parentResultSetId; 78 int[] fkColArray; 79 RowLocation rowLocation; 80 TemporaryRowHolder[] sourceRowHolders; 81 TemporaryRowHolderResultSet[] sourceResultSets; 82 int[] sourceOpened; 83 int sArrayIndex; 84 Vector sVector; 85 86 87 protected ScanController scanController; 88 protected boolean scanControllerOpened; 89 protected boolean isKeyed; 90 protected boolean firstScan = true; 91 protected ExecIndexRow startPosition; 92 protected ExecIndexRow stopPosition; 93 protected ExecRow candidate; 94 95 protected long conglomId; 98 protected DynamicCompiledOpenConglomInfo heapDcoci; 99 protected StaticCompiledOpenConglomInfo heapScoci; 100 protected GeneratedMethod resultRowAllocator; 101 protected GeneratedMethod startKeyGetter; 102 protected int startSearchOperator; 103 protected GeneratedMethod stopKeyGetter; 104 protected int stopSearchOperator; 105 protected Qualifier[][] qualifiers; 106 public String tableName; 107 public String userSuppliedOptimizerOverrides; 108 public String indexName; 109 protected boolean runTimeStatisticsOn; 110 protected FormatableBitSet accessedCols; 111 public int rowsPerRead; 112 public boolean forUpdate; 113 private boolean sameStartStopPosition; 114 public int isolationLevel; 115 public int lockMode; 116 117 118 private Properties scanProperties; 120 public String startPositionString; 121 public String stopPositionString; 122 public boolean isConstraint; 123 public boolean coarserLock; 124 public boolean oneRowScan; 125 protected long rowsThisScan; 126 127 DependentResultSet( 131 long conglomId, 132 StaticCompiledOpenConglomInfo scoci, 133 Activation activation, 134 GeneratedMethod resultRowAllocator, 135 int resultSetNumber, 136 GeneratedMethod startKeyGetter, int startSearchOperator, 137 GeneratedMethod stopKeyGetter, int stopSearchOperator, 138 boolean sameStartStopPosition, 139 Qualifier[][] qualifiers, 140 String tableName, 141 String userSuppliedOptimizerOverrides, 142 String indexName, 143 boolean isConstraint, 144 boolean forUpdate, 145 int colRefItem, 146 int lockMode, 147 boolean tableLocked, 148 int isolationLevel, 149 int rowsPerRead, 150 boolean oneRowScan, 151 double optimizerEstimatedRowCount, 152 double optimizerEstimatedCost, 153 String parentResultSetId, 154 long fkIndexConglomId, 155 int fkColArrayItem, 156 int rltItem 157 ) throws StandardException 158 { 159 super(activation, 160 resultSetNumber, 161 optimizerEstimatedRowCount, 162 optimizerEstimatedCost); 163 164 this.conglomId = conglomId; 165 166 171 this.heapScoci = scoci; 172 heapDcoci = activation.getTransactionController().getDynamicCompiledConglomInfo(conglomId); 173 174 if (SanityManager.DEBUG) { 175 SanityManager.ASSERT( activation!=null, "table scan must get activation context"); 176 SanityManager.ASSERT( resultRowAllocator!= null, "table scan must get row allocator"); 177 if (sameStartStopPosition) 178 { 179 SanityManager.ASSERT(stopKeyGetter == null, 180 "stopKeyGetter expected to be null when sameStartStopPosition is true"); 181 } 182 } 183 184 this.resultRowAllocator = resultRowAllocator; 185 186 this.startKeyGetter = startKeyGetter; 187 this.startSearchOperator = startSearchOperator; 188 this.stopKeyGetter = stopKeyGetter; 189 this.stopSearchOperator = stopSearchOperator; 190 this.sameStartStopPosition = sameStartStopPosition; 191 this.qualifiers = qualifiers; 192 this.tableName = tableName; 193 this.userSuppliedOptimizerOverrides = userSuppliedOptimizerOverrides; 194 this.indexName = "On Foreign Key"; this.isConstraint = isConstraint; 196 this.forUpdate = forUpdate; 197 this.rowsPerRead = rowsPerRead; 198 this.oneRowScan = oneRowScan; 199 200 this.accessedCols = null; 203 if (colRefItem != -1) 204 { 205 this.accessedCols = (FormatableBitSet)(activation.getPreparedStatement(). 206 getSavedObject(colRefItem)); 207 } 208 209 210 if (! tableLocked) 214 { 215 this.lockMode = TransactionController.MODE_RECORD; 216 }else 217 { 218 this.lockMode = lockMode; 219 } 220 221 222 this.isolationLevel = TransactionController.ISOLATION_REPEATABLE_READ; 226 227 runTimeStatisticsOn = (activation != null && 228 activation.getLanguageConnectionContext().getRunTimeStatisticsMode()); 229 230 231 candidate = (ExecRow) resultRowAllocator.invoke(activation); 232 233 234 tc = activation.getTransactionController(); 235 indexDcoci = tc.getDynamicCompiledConglomInfo(fkIndexConglomId); 237 indexScoci = tc.getStaticCompiledConglomInfo(fkIndexConglomId); 238 239 this.parentResultSetId = parentResultSetId; 240 this.fkColArray = (int[])(activation.getPreparedStatement(). 241 getSavedObject(fkColArrayItem)); 242 243 this.rowLocation = (RowLocation)(activation.getPreparedStatement(). 244 getSavedObject(rltItem)); 245 numFkColumns = fkColArray.length; 246 indexQualifierRow = new IndexRow(numFkColumns); 247 constructorTime += getElapsedMillis(beginTime); 248 } 249 250 251 258 259 260 private ScanController openIndexScanController(ExecRow searchRow) throws StandardException 261 { 262 setupQualifierRow(searchRow); 263 indexSC = tc.openCompiledScan( 264 false, TransactionController.OPENMODE_FORUPDATE, lockMode, isolationLevel, (FormatableBitSet)null, indexQualifierRow.getRowArray(), ScanController.GE, null, indexQualifierRow.getRowArray(), ScanController.GT, indexScoci, 275 indexDcoci 276 ); 277 278 return indexSC; 279 280 } 281 282 283 private void reopenIndexScanController(ExecRow searchRow) throws StandardException 285 { 286 287 setupQualifierRow(searchRow); 288 indexSC.reopenScan( 289 indexQualifierRow.getRowArray(), ScanController.GE, null, indexQualifierRow.getRowArray(), ScanController.GT ); 295 } 296 297 298 303 private void setupQualifierRow(ExecRow searchRow) 304 { 305 Object [] indexColArray = indexQualifierRow.getRowArray(); 306 Object [] baseColArray = searchRow.getRowArray(); 307 308 for (int i = 0; i < numFkColumns; i++) 309 { 310 indexColArray[i] = baseColArray[fkColArray[i] - 1]; 311 } 312 } 313 314 315 private void openIndexScan(ExecRow searchRow) throws StandardException 316 { 317 318 if (indexSC == null) 319 { 320 indexSC = openIndexScanController(searchRow); 321 indexRow = indexQualifierRow.getClone(); 323 indexRow.setColumn(numFkColumns + 1, rowLocation.getClone()); 324 325 }else 326 { 327 reopenIndexScanController(searchRow); 328 } 329 } 330 331 332 339 private ExecRow fetchIndexRow() 340 throws StandardException 341 { 342 if (!indexSC.fetchNext(indexRow.getRowArray())) 343 { 344 return null; 345 } 346 return indexRow; 347 } 348 349 350 351 357 private ExecRow fetchBaseRow() 358 throws StandardException 359 { 360 361 if (currentRow == null) 362 { 363 currentRow = 364 getCompactRow(candidate, accessedCols, (FormatableBitSet) null, isKeyed); 365 } 366 367 baseRowLocation = (RowLocation) indexRow.getColumn(indexRow.getRowArray().length); 368 boolean base_row_exists = 369 heapCC.fetch( 370 baseRowLocation, candidate.getRowArray(),accessedCols); 371 372 if (SanityManager.DEBUG) 373 { 374 SanityManager.ASSERT(base_row_exists, "base row disappeared."); 375 } 376 377 return currentRow; 378 } 379 380 381 ExecRow searchRow = null; 383 public ExecRow getNextRowCore() throws StandardException 385 { 386 387 beginTime = getCurrentTimeMillis(); 388 if (searchRow == null) 389 { 390 if((searchRow = getNextParentRow())!=null) 392 openIndexScan(searchRow); 393 } 394 395 ExecRow currentIndexRow = null; 396 while(searchRow != null) 397 { 398 currentIndexRow = fetchIndexRow(); 401 402 if(currentIndexRow !=null) 403 break; 404 if((searchRow = getNextParentRow())!=null) 405 openIndexScan(searchRow); 406 } 407 408 nextTime += getElapsedMillis(beginTime); 409 if(currentIndexRow!= null) 410 { 411 rowsSeen++; 412 return fetchBaseRow(); 413 }else 414 { 415 return currentIndexRow; 416 } 417 418 419 } 420 421 422 private ExecRow getNextParentRow() throws StandardException 424 { 425 426 ExecRow cRow; 427 TemporaryRowHolder rowHolder; 428 429 if(sourceOpened[sArrayIndex] == 0) 430 { 431 rowHolder = sourceRowHolders[sArrayIndex]; 432 source = (TemporaryRowHolderResultSet)rowHolder.getResultSet(); 433 source.open(); sourceOpened[sArrayIndex] = -1; 435 sourceResultSets[sArrayIndex] = source; 436 } 437 438 if(sourceOpened[sArrayIndex] == 1) 439 { 440 source = sourceResultSets[sArrayIndex]; 441 source.reStartScan(sourceRowHolders[sArrayIndex].getTemporaryConglomId(), 442 sourceRowHolders[sArrayIndex].getPositionIndexConglomId()); 443 sourceOpened[sArrayIndex] = -1; 444 445 } 446 447 if(sVector.size() > sourceRowHolders.length) 448 { 449 addNewSources(); 450 } 451 452 cRow = source.getNextRow(); 453 while(cRow == null && (sArrayIndex+1) < sourceRowHolders.length) 454 { 455 456 sArrayIndex++; 458 if(sourceOpened[sArrayIndex] == 0) 459 { 460 rowHolder = sourceRowHolders[sArrayIndex]; 461 source = (TemporaryRowHolderResultSet)rowHolder.getResultSet(); 462 source.open(); sourceOpened[sArrayIndex] = -1; 464 sourceResultSets[sArrayIndex] = source; 465 } 466 467 if(sourceOpened[sArrayIndex] == 1) 468 { 469 source = sourceResultSets[sArrayIndex]; 470 source.reStartScan(sourceRowHolders[sArrayIndex].getTemporaryConglomId(), 471 sourceRowHolders[sArrayIndex].getPositionIndexConglomId()); 472 sourceOpened[sArrayIndex] = -1; 473 } 474 475 cRow = source.getNextRow(); 476 } 477 478 if(cRow == null) 479 { 480 sArrayIndex = 0; 482 for(int i =0 ; i < sourceOpened.length ; i++) 484 sourceOpened[i] = 1; 485 } 486 487 return cRow; 488 } 489 490 491 492 497 public ConglomerateController openHeapConglomerateController() 498 throws StandardException 499 { 500 return tc.openCompiledConglomerate( 501 false, 502 TransactionController.OPENMODE_FORUPDATE, 503 lockMode, 504 isolationLevel, 505 heapScoci, 506 heapDcoci); 507 } 508 509 510 511 512 515 public void close() 516 throws StandardException 517 { 518 if (runTimeStatisticsOn) 521 { 522 startPositionString = printStartPosition(); 523 stopPositionString = printStopPosition(); 524 scanProperties = getScanProperties(); 525 } 526 527 if (indexSC != null) 528 { 529 indexSC.close(); 530 indexSC = null; 531 } 532 533 if ( heapCC != null ) 534 { 535 heapCC.close(); 536 heapCC = null; 537 } 538 if(isOpen) 539 { 540 source.close(); 541 } 542 543 closeTime += getElapsedMillis(beginTime); 544 } 545 546 public void finish() throws StandardException 547 { 548 if (source != null) 549 source.finish(); 550 finishAndRTS(); 551 } 552 553 public void openCore() throws StandardException 554 { 555 556 sVector = activation.getParentResultSet(parentResultSetId); 557 int size = sVector.size(); 558 sourceRowHolders = new TemporaryRowHolder[size]; 559 sourceOpened = new int[size]; 560 sourceResultSets = new TemporaryRowHolderResultSet[size]; 561 for(int i = 0 ; i < size ; i++) 562 { 563 sourceRowHolders[i] = (TemporaryRowHolder)sVector.elementAt(i); 564 sourceOpened[i] = 0; 565 } 566 567 heapCC = openHeapConglomerateController(); 569 numOpens++; 570 openTime += getElapsedMillis(beginTime); 571 } 572 573 574 private void addNewSources() 575 { 576 int size = sVector.size(); 577 TemporaryRowHolder[] tsourceRowHolders = new TemporaryRowHolder[size]; 578 int[] tsourceOpened = new int[size]; 579 TemporaryRowHolderResultSet[] tsourceResultSets = new TemporaryRowHolderResultSet[size]; 580 581 System.arraycopy(sourceRowHolders, 0, tsourceRowHolders, 0 , sourceRowHolders.length); 583 System.arraycopy(sourceOpened, 0, tsourceOpened , 0 ,sourceOpened.length); 584 System.arraycopy(sourceResultSets , 0, tsourceResultSets ,0 ,sourceResultSets.length); 585 586 for(int i = sourceRowHolders.length; i < size ; i++) 588 { 589 tsourceRowHolders[i] = (TemporaryRowHolder)sVector.elementAt(i); 590 tsourceOpened[i] = 0; 591 } 592 593 sourceRowHolders = tsourceRowHolders; 594 sourceOpened = tsourceOpened ; 595 sourceResultSets = tsourceResultSets; 596 } 597 598 599 600 604 private boolean canGetInstantaneousLocks() 605 { 606 return false; 607 } 608 609 610 public long getTimeSpent(int type) 611 { 612 return constructorTime + openTime + nextTime + closeTime; 613 } 614 615 616 public RowLocation getRowLocation() throws StandardException 618 { 619 return baseRowLocation; 620 } 621 622 public ExecRow getCurrentRow() throws StandardException 623 { 624 return currentRow; 625 } 626 627 628 public Properties getScanProperties() 629 { 630 if (scanProperties == null) 631 { 632 scanProperties = new Properties (); 633 } 634 try 635 { 636 if (indexSC != null) 637 { 638 indexSC.getScanInfo().getAllScanInfo(scanProperties); 639 643 coarserLock = indexSC.isTableLocked() && 644 (lockMode == TransactionController.MODE_RECORD); 645 } 646 } 647 catch(StandardException se) 648 { 649 } 651 652 return scanProperties; 653 } 654 655 public String printStartPosition() 656 { 657 return printPosition(ScanController.GE, indexQualifierRow); 658 } 659 660 public String printStopPosition() 661 { 662 return printPosition(ScanController.GT, indexQualifierRow); 663 } 664 665 666 672 private String printPosition(int searchOperator, ExecIndexRow positioner) 673 { 674 String idt = ""; 675 String output = ""; 676 677 String searchOp = null; 678 switch (searchOperator) 679 { 680 case ScanController.GE: 681 searchOp = ">="; 682 break; 683 684 case ScanController.GT: 685 searchOp = ">"; 686 break; 687 688 default: 689 if (SanityManager.DEBUG) 690 { 691 SanityManager.THROWASSERT("Unknown search operator " + 692 searchOperator); 693 } 694 695 searchOp = "unknown value (" + searchOperator + ")"; 698 break; 699 } 700 701 if(positioner !=null) 702 { 703 output = output + "\t" + 704 MessageService.getTextMessage( 705 SQLState.LANG_POSITIONER, 706 searchOp, 707 String.valueOf(positioner.nColumns())) + 708 "\n"; 709 710 output = output + "\t" + 711 MessageService.getTextMessage( 712 SQLState.LANG_ORDERED_NULL_SEMANTICS) + 713 "\n"; 714 for (int position = 0; position < positioner.nColumns(); position++) 715 { 716 if (positioner.areNullsOrdered(position)) 717 { 718 output = output + position + " "; 719 } 720 } 721 722 } 723 724 return output + "\n"; 725 } 726 727 728 731 public String printQualifiers() 732 { 733 String idt = ""; 735 return idt + MessageService.getTextMessage(SQLState.LANG_NONE); 736 } 737 } 738 739 740 741 742 743 744 745 746 747 748 749 | Popular Tags |