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.services.io.Formatable; 32 33 import org.apache.derby.iapi.sql.execute.CursorResultSet; 34 import org.apache.derby.iapi.sql.ResultSet; 35 import org.apache.derby.iapi.sql.execute.ExecRow; 36 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 37 38 import org.apache.derby.iapi.sql.Activation; 39 40 import org.apache.derby.iapi.store.access.ColumnOrdering; 41 import org.apache.derby.iapi.types.DataValueDescriptor; 42 import org.apache.derby.iapi.store.access.SortObserver; 43 import org.apache.derby.iapi.store.access.TransactionController; 44 import org.apache.derby.iapi.store.access.SortController; 45 import org.apache.derby.iapi.store.access.ScanController; 46 47 import org.apache.derby.iapi.services.loader.GeneratedMethod; 48 49 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 50 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.FormatableArrayHolder; 56 57 import java.util.Properties ; 58 import java.util.Vector ; 59 import java.util.Enumeration ; 60 61 114 class SortResultSet extends NoPutResultSetImpl 115 implements CursorResultSet 116 { 117 118 119 public int rowsInput; 120 public int rowsReturned; 121 public boolean distinct; 122 123 public NoPutResultSet source; 126 private GeneratedMethod rowAllocator; 127 private ColumnOrdering[] order; 128 private ColumnOrdering[] savedOrder; 129 private SortObserver observer; 130 private ExecRow sortTemplateRow; 131 public boolean isInSortedOrder; private NoPutResultSet originalSource; private int maxRowSize; 134 135 private ScanController scanController; 137 138 140 private ExecRow sortResultRow; 141 142 private ExecRow currSortedRow; 144 private boolean nextCalled; 145 private int numColumns; 146 147 private long genericSortId; 149 private boolean dropGenericSort; 150 151 private boolean sorted; 153 154 public Properties sortProperties = new Properties (); 156 157 175 public SortResultSet(NoPutResultSet s, 176 boolean distinct, 177 boolean isInSortedOrder, 178 int orderingItem, 179 Activation a, 180 GeneratedMethod ra, 181 int maxRowSize, 182 int resultSetNumber, 183 double optimizerEstimatedRowCount, 184 double optimizerEstimatedCost) throws StandardException 185 { 186 super(a, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost); 187 this.distinct = distinct; 188 this.isInSortedOrder = isInSortedOrder; 189 source = s; 190 originalSource = s; 191 rowAllocator = ra; 192 this.maxRowSize = maxRowSize; 193 sortTemplateRow = (ExecRow) rowAllocator.invoke(activation); 194 order = (ColumnOrdering[]) 195 ((FormatableArrayHolder) 196 (a.getPreparedStatement().getSavedObject(orderingItem))) 197 .getArray(ColumnOrdering.class); 198 199 205 savedOrder = order; 206 207 211 observer = new BasicSortObserver(true, distinct, sortTemplateRow, true); 212 213 constructorTime += getElapsedMillis(beginTime); 214 } 215 216 217 223 229 public void openCore() throws StandardException 230 { 231 nextCalled = false; 232 beginTime = getCurrentTimeMillis(); 233 if (SanityManager.DEBUG) 237 SanityManager.ASSERT( ! isOpen, "SortResultSet already open"); 238 239 245 order = savedOrder; 246 247 sortResultRow = sortTemplateRow.getClone(); 248 249 source.openCore(); 250 251 256 if (isInSortedOrder && distinct) 257 { 258 currSortedRow = getNextRowFromRS(); 259 if (currSortedRow != null) 260 { 261 currSortedRow = (ExecRow) currSortedRow.getClone(); 262 } 263 } 264 else 265 { 266 269 scanController = loadSorter(); 270 sorted = true; 271 } 272 273 isOpen = true; 274 numOpens++; 275 276 openTime += getElapsedMillis(beginTime); 277 } 278 279 289 private ScanController loadSorter() 290 throws StandardException 291 { 292 SortController sorter; 293 long sortId; 294 ExecRow sourceRow; 295 ExecRow inputRow; 296 boolean inOrder = (order.length == 0 || isInSortedOrder); 297 int inputRowCountEstimate = (int) optimizerEstimatedRowCount; 298 299 TransactionController tc = getTransactionController(); 302 sortId = tc.createSort((Properties )null, 303 sortTemplateRow.getRowArray(), 304 order, 305 observer, 306 inOrder, 307 inputRowCountEstimate, maxRowSize ); 310 sorter = tc.openSort(sortId); 311 genericSortId = sortId; 312 dropGenericSort = true; 313 314 315 while ((inputRow = getNextRowFromRS()) != null) 316 { 317 318 sorter.insert(inputRow.getRowArray()); 319 } 320 source.close(); 321 sortProperties = sorter.getSortInfo().getAllSortInfo(sortProperties); 322 sorter.close(); 323 324 return tc.openSortScan(sortId, activation.getResultSetHoldability()); 325 } 326 327 328 336 public ExecRow getNextRowCore() throws StandardException 337 { 338 if (!isOpen) 339 { 340 return null; 341 } 342 343 beginTime = getCurrentTimeMillis(); 344 345 if (isInSortedOrder && distinct) 347 { 348 if (currSortedRow == null) 350 { 351 nextTime += getElapsedMillis(beginTime); 352 return null; 353 } 354 355 358 if (! nextCalled) 359 { 360 nextCalled = true; 361 numColumns = currSortedRow.getRowArray().length; 362 nextTime += getElapsedMillis(beginTime); 363 rowsReturned++; 364 setCurrentRow(currSortedRow); 365 return currSortedRow; 366 } 367 368 ExecRow sortResult = getNextRowFromRS(); 369 370 371 while (sortResult != null) 372 { 373 374 if (! filterRow(currSortedRow, sortResult)) 375 { 376 377 currSortedRow = (ExecRow) sortResult.getClone(); 378 setCurrentRow(currSortedRow); 379 nextTime += getElapsedMillis(beginTime); 380 rowsReturned++; 381 return currSortedRow; 382 } 383 384 sortResult = getNextRowFromRS(); 386 } 387 388 currSortedRow = null; 390 nextTime += getElapsedMillis(beginTime); 391 return null; 392 } 393 else 394 { 395 ExecRow sortResult = getNextRowFromRS(); 396 397 if (sortResult != null) 398 { 399 setCurrentRow(sortResult); 400 rowsReturned++; 401 } 402 nextTime += getElapsedMillis(beginTime); 403 return sortResult; 404 } 405 } 406 407 419 private boolean filterRow(ExecRow currRow, ExecRow newRow) 420 throws StandardException 421 { 422 for (int index = 1; index <= numColumns; index++) 423 { 424 DataValueDescriptor currOrderable = currRow.getColumn(index); 425 DataValueDescriptor newOrderable = newRow.getColumn(index); 426 if (! (currOrderable.compare(DataValueDescriptor.ORDER_OP_EQUALS, newOrderable, true, true))) 427 { 428 return false; 429 } 430 } 431 return true; 432 } 433 434 440 public void close() throws StandardException 441 { 442 beginTime = getCurrentTimeMillis(); 443 if ( isOpen ) 444 { 445 clearCurrentRow(); 450 451 sortResultRow = null; 452 closeSource(); 453 454 if (dropGenericSort) 455 { 456 getTransactionController().dropSort(genericSortId); 457 dropGenericSort = false; 458 } 459 super.close(); 460 } 461 else 462 if (SanityManager.DEBUG) 463 SanityManager.DEBUG("CloseRepeatInfo","Close of SortResultSet repeated"); 464 465 closeTime += getElapsedMillis(beginTime); 466 467 isOpen = false; 468 } 469 470 public void finish() throws StandardException 471 { 472 source.finish(); 473 finishAndRTS(); 474 } 475 476 484 public long getTimeSpent(int type) 485 { 486 long totTime = constructorTime + openTime + nextTime + 487 closeTime; 488 489 if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) 490 { 491 return totTime - originalSource.getTimeSpent(ENTIRE_RESULTSET_TREE); 492 } 493 else 494 { 495 return totTime; 496 } 497 } 498 499 505 515 public RowLocation getRowLocation() throws StandardException 516 { 517 if (! isOpen) return null; 518 519 RowLocation rl; 522 rl = scanController.newRowLocationTemplate(); 523 scanController.fetchLocation(rl); 524 return rl; 525 } 526 527 536 539 public ExecRow getCurrentRow() throws StandardException 540 { 541 if (SanityManager.DEBUG) 542 SanityManager.ASSERT(isOpen, "SortResultSet expected to be open"); 543 544 548 return currentRow; 549 } 550 551 559 private ExecRow getNextRowFromRS() 560 throws StandardException 561 { 562 return (scanController == null) ? 563 getRowFromResultSet() : 564 getRowFromSorter(); 565 } 566 567 570 private ExecRow getRowFromResultSet() 571 throws StandardException 572 { 573 ExecRow sourceRow; 574 ExecRow inputRow = null; 575 576 if ((sourceRow = source.getNextRowCore()) != null) 577 { 578 rowsInput++; 579 inputRow = sourceRow; 580 } 581 582 return inputRow; 583 } 584 585 586 590 private ExecRow getRowFromSorter() 591 throws StandardException 592 { 593 ExecRow inputRow = null; 594 595 if (scanController.next()) 596 { 597 currentRow = sortResultRow; 601 602 inputRow = sortResultRow; 603 604 scanController.fetch(inputRow.getRowArray()); 605 } 606 return inputRow; 607 } 608 609 612 private void closeSource() throws StandardException 613 { 614 if (scanController == null) 615 { 616 621 source.close(); 622 } 623 else 624 { 625 scanController.close(); 626 scanController = null; 627 } 628 } 629 } 630 | Popular Tags |