1 21 22 package org.apache.derby.impl.sql.execute; 23 24 import org.apache.derby.iapi.services.monitor.Monitor; 25 26 import org.apache.derby.iapi.services.sanity.SanityManager; 27 28 import org.apache.derby.iapi.services.stream.HeaderPrintWriter; 29 import org.apache.derby.iapi.services.stream.InfoStreams; 30 31 import org.apache.derby.iapi.sql.execute.CursorResultSet; 32 import org.apache.derby.iapi.sql.execute.ExecRow; 33 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 34 35 import org.apache.derby.iapi.types.DataValueDescriptor; 36 37 import org.apache.derby.iapi.sql.Activation; 38 import org.apache.derby.iapi.sql.ResultSet; 39 40 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 41 import org.apache.derby.iapi.sql.conn.StatementContext; 42 43 import org.apache.derby.iapi.store.access.ConglomerateController; 44 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo; 45 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo; 46 import org.apache.derby.iapi.store.access.TransactionController; 47 48 import org.apache.derby.iapi.services.loader.GeneratedMethod; 49 50 import org.apache.derby.iapi.reference.SQLState; 51 import org.apache.derby.iapi.error.StandardException; 52 53 import org.apache.derby.iapi.types.RowLocation; 54 55 import org.apache.derby.iapi.services.io.FormatableBitSet; 56 57 import org.apache.derby.catalog.types.ReferencedColumnsDescriptorImpl; 58 59 67 class IndexRowToBaseRowResultSet extends NoPutResultSetImpl 68 implements CursorResultSet { 69 70 private long conglomId; 73 public NoPutResultSet source; 74 private GeneratedMethod resultRowAllocator; 75 private GeneratedMethod restriction; 76 private long baseConglomId; 77 public FormatableBitSet accessedHeapCols; 78 private FormatableBitSet accessedIndexCols; 79 private FormatableBitSet accessedAllCols; 81 public String indexName; 82 private int[] indexCols; 83 private DynamicCompiledOpenConglomInfo dcoci; 84 private StaticCompiledOpenConglomInfo scoci; 85 86 private ConglomerateController baseCC; 88 private boolean closeBaseCCHere; 89 private ExecRow resultRow; 90 private ExecRow compactRow; 91 private boolean forUpdate; 92 private DataValueDescriptor[] rowArray; 93 94 RowLocation baseRowLocation; 96 97 100 boolean copiedFromSource; 101 102 103 public long restrictionTime; 104 105 protected boolean currentRowPrescanned; 106 private boolean sourceIsForUpdateIndexScan; 107 108 IndexRowToBaseRowResultSet( 112 long conglomId, 113 int scociItem, 114 Activation a, 115 NoPutResultSet source, 116 GeneratedMethod resultRowAllocator, 117 int resultSetNumber, 118 String indexName, 119 int heapColRefItem, 120 int indexColRefItem, 121 int indexColMapItem, 122 GeneratedMethod restriction, 123 boolean forUpdate, 124 double optimizerEstimatedRowCount, 125 double optimizerEstimatedCost) 126 throws StandardException 127 { 128 super(a, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost); 129 scoci = (StaticCompiledOpenConglomInfo)(activation.getPreparedStatement(). 130 getSavedObject(scociItem)); 131 TransactionController tc = activation.getTransactionController(); 132 dcoci = tc.getDynamicCompiledConglomInfo(conglomId); 133 this.source = source; 134 this.resultRowAllocator = resultRowAllocator; 135 this.indexName = indexName; 136 this.forUpdate = forUpdate; 137 this.restriction = restriction; 138 139 142 143 this.accessedHeapCols = null; 146 if (heapColRefItem != -1) 147 { 148 this.accessedHeapCols = (FormatableBitSet)(a.getPreparedStatement(). 149 getSavedObject(heapColRefItem)); 150 } 151 if (indexColRefItem != -1) 152 { 153 this.accessedIndexCols = (FormatableBitSet)(a.getPreparedStatement(). 154 getSavedObject(indexColRefItem)); 155 } 156 if (accessedIndexCols == null) 157 accessedAllCols = accessedHeapCols; 158 else 159 { 160 accessedAllCols = new FormatableBitSet(accessedHeapCols); 161 accessedAllCols.or(accessedIndexCols); 162 } 163 164 indexCols = ((ReferencedColumnsDescriptorImpl) (a.getPreparedStatement(). 166 getSavedObject(indexColMapItem))).getReferencedColumnPositions(); 167 168 169 resultRow = (ExecRow) resultRowAllocator.invoke(activation); 170 171 compactRow = 172 getCompactRow(resultRow, 173 accessedHeapCols, 174 accessedIndexCols, 175 false); 176 177 181 if (accessedHeapCols == null) 182 { 183 rowArray = resultRow.getRowArray(); 184 } 185 else 186 { 187 int arraySize = accessedHeapCols.getNumBitsSet(); 189 int accessedHeapColsSize = accessedHeapCols.size(); 190 191 rowArray = new DataValueDescriptor[accessedHeapColsSize]; 192 193 int partialIndex = 0; 195 int numFromIndex = 0; 196 for (int index = 0; index < accessedHeapColsSize; index++) 197 { 198 if (accessedIndexCols != null && accessedIndexCols.get(index)) 199 { 200 numFromIndex++; 201 continue; 202 } 203 if (accessedHeapCols.get(index)) 204 { 205 rowArray[index] = 206 resultRow.getRowArray()[index]; 207 partialIndex++; 208 } 209 } 210 } 211 212 constructorTime += getElapsedMillis(beginTime); 213 214 } 215 216 220 225 public void openCore() throws StandardException 226 { 227 boolean lockingRequired = false; 228 TransactionController tc; 229 230 if (SanityManager.DEBUG) 234 { 235 SanityManager.ASSERT( ! isOpen, 236 "IndexRowToBaseRowResultSet already open"); 237 } 238 239 beginTime = getCurrentTimeMillis(); 240 241 source.openCore(); 242 if ((source instanceof TableScanResultSet) && 243 ((TableScanResultSet) source).indexCols != null) 244 sourceIsForUpdateIndexScan = true; 245 246 252 if (source.requiresRelocking()) 253 { 254 lockingRequired = true; 255 } 256 257 tc = activation.getTransactionController(); 258 259 int openMode; 260 int isolationLevel; 261 262 if (forUpdate) 263 { 264 openMode = TransactionController.OPENMODE_FORUPDATE; 265 } 266 else 267 { 268 openMode = 0; 269 } 270 isolationLevel = source.getScanIsolationLevel(); 271 272 if (!lockingRequired) 273 { 274 openMode |= TransactionController.OPENMODE_SECONDARY_LOCKED; 278 } 279 280 285 if (forUpdate) 286 { 287 baseCC = activation.getHeapConglomerateController(); 288 } 289 290 if (baseCC == null) 291 { 292 baseCC = 293 tc.openCompiledConglomerate( 294 activation.getResultSetHoldability(), 295 openMode, 296 TransactionController.MODE_RECORD, 298 isolationLevel, 299 scoci, 300 dcoci); 301 closeBaseCCHere = true; 302 } 303 304 isOpen = true; 305 numOpens++; 306 openTime += getElapsedMillis(beginTime); 307 } 308 309 314 public void reopenCore() throws StandardException { 315 TransactionController tc; 316 317 if (SanityManager.DEBUG) 318 { 319 SanityManager.ASSERT(isOpen, 320 "IndexRowToBaseRowResultSet already open"); 321 } 322 323 beginTime = getCurrentTimeMillis(); 324 325 source.reopenCore(); 326 327 numOpens++; 328 openTime += getElapsedMillis(beginTime); 329 } 330 331 344 public ExecRow getNextRowCore() throws StandardException { 345 346 ExecRow sourceRow = null; 347 ExecRow retval = null; 348 boolean restrict = false; 349 DataValueDescriptor restrictBoolean; 350 long beginRT = 0; 351 352 beginTime = getCurrentTimeMillis(); 353 if ( ! isOpen ) { 354 throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, "next"); 355 } 356 357 363 if (sourceIsForUpdateIndexScan && ((TableScanResultSet) source).futureForUpdateRows != null) 364 { 365 currentRowPrescanned = false; 366 TableScanResultSet src = (TableScanResultSet) source; 367 368 if (src.futureRowResultSet == null) 369 { 370 src.futureRowResultSet = (TemporaryRowHolderResultSet) src.futureForUpdateRows.getResultSet(); 371 src.futureRowResultSet.openCore(); 372 } 373 374 ExecRow ridRow = src.futureRowResultSet.getNextRowCore(); 375 376 currentRow = null; 377 378 if (ridRow != null) 379 { 380 386 src.futureRowResultSet.deleteCurrentRow(); 387 baseRowLocation = (RowLocation) ridRow.getColumn(1); 388 baseCC.fetch( 389 baseRowLocation, compactRow.getRowArray(), accessedAllCols); 390 391 currentRow = compactRow; 392 currentRowPrescanned = true; 393 } 394 else if (src.sourceDrained) 395 currentRowPrescanned = true; 396 397 if (currentRowPrescanned) 398 { 399 setCurrentRow(currentRow); 400 401 nextTime += getElapsedMillis(beginTime); 402 return currentRow; 403 } 404 } 405 406 411 do 412 { 413 sourceRow = source.getNextRowCore(); 414 415 if (sourceRow != null) { 416 417 if (SanityManager.DEBUG) { 418 SanityManager.ASSERT( 419 sourceRow.getColumn(sourceRow.nColumns()) 420 instanceof RowLocation, 421 "Last column of source row is not a RowLocation" 422 ); 423 } 424 425 baseRowLocation = (RowLocation) 426 sourceRow.getColumn(sourceRow.nColumns()); 427 428 boolean row_exists = 430 baseCC.fetch( 431 baseRowLocation, rowArray, accessedHeapCols); 432 433 if (row_exists) 434 { 435 443 if (! copiedFromSource) 444 { 445 copiedFromSource = true; 446 447 for (int index = 0; index < indexCols.length; index++) 449 { 450 if (indexCols[index] != -1) 451 { 452 compactRow.setColumn( 453 index + 1, 454 sourceRow.getColumn(indexCols[index] + 1)); 455 } 456 } 457 } 458 459 setCurrentRow(compactRow); 460 461 restrictBoolean = (DataValueDescriptor) 462 ((restriction == null) ? 463 null : restriction.invoke(activation)); 464 465 restrictionTime += getElapsedMillis(beginRT); 466 467 restrict = (restrictBoolean == null) || 470 ((! restrictBoolean.isNull()) && 471 restrictBoolean.getBoolean()); 472 } 473 474 if (! restrict || ! row_exists) 475 { 476 rowsFiltered++; 477 clearCurrentRow(); 478 baseRowLocation = null; 479 480 } 481 else 482 { 483 currentRow = compactRow; 484 } 485 486 487 rowsSeen++; 488 489 retval = currentRow; 490 } else { 491 clearCurrentRow(); 492 baseRowLocation = null; 493 494 retval = null; 495 } 496 } 497 while ( (sourceRow != null) && (! restrict ) ); 498 499 nextTime += getElapsedMillis(beginTime); 500 return retval; 501 } 502 503 509 public void close() throws StandardException 510 { 511 beginTime = getCurrentTimeMillis(); 512 if ( isOpen ) { 513 514 clearCurrentRow(); 519 520 if (closeBaseCCHere) 521 { 522 530 if (baseCC != null) 531 baseCC.close(); 532 } 533 534 538 baseCC = null; 539 source.close(); 540 541 super.close(); 542 } 543 else if (SanityManager.DEBUG) { 544 SanityManager.DEBUG("CloseRepeatInfo","Close of IndexRowToBaseRowResultSet repeated"); 545 } 546 547 closeTime += getElapsedMillis(beginTime); 548 } 549 550 558 public long getTimeSpent(int type) 559 { 560 long totTime = constructorTime + openTime + nextTime + closeTime; 561 562 if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) 563 { 564 return totTime - source.getTimeSpent(ENTIRE_RESULTSET_TREE); 565 } 566 else 567 { 568 return totTime; 569 } 570 } 571 572 583 public RowLocation getRowLocation() throws StandardException { 584 return baseRowLocation; 585 } 586 587 594 public void positionScanAtRowLocation(RowLocation rl) 595 throws StandardException 596 { 597 baseRowLocation = rl; 598 source.positionScanAtRowLocation(rl); 599 } 600 601 608 611 public ExecRow getCurrentRow() throws StandardException { 612 ExecRow sourceRow = null; 613 614 if (SanityManager.DEBUG) { 615 SanityManager.ASSERT(isOpen, 616 "IndexRowToBaseRowResultSet is expected to be open"); 617 } 618 619 if (currentRowPrescanned) 620 return currentRow; 621 622 623 if (currentRow == null) 624 { 625 return null; 626 } 627 628 sourceRow = activation.getExecutionFactory(). 632 getValueRow(indexCols.length); 633 sourceRow.setRowArray(rowArray); 634 boolean row_exists = 636 baseCC.fetch( 637 baseRowLocation, rowArray, (FormatableBitSet) null); 638 if (row_exists) { 639 setCurrentRow(sourceRow); 640 } else { 641 clearCurrentRow(); 642 } 643 return currentRow; 644 } 645 646 653 public boolean isForUpdate() 654 { 655 return source.isForUpdate(); 656 } 657 658 } 659 | Popular Tags |