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.Activation; 35 import org.apache.derby.iapi.sql.ResultSet; 36 import org.apache.derby.iapi.sql.execute.ExecRow; 37 import org.apache.derby.iapi.sql.execute.ExecIndexRow; 38 import org.apache.derby.iapi.sql.execute.NoPutResultSet; 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.execute.ExecutionFactory; 50 import org.apache.derby.iapi.sql.execute.ExecutionContext; 51 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext; 52 53 import org.apache.derby.iapi.error.StandardException; 54 55 import org.apache.derby.iapi.types.RowLocation; 56 57 import org.apache.derby.iapi.services.io.FormatableArrayHolder; 58 59 import java.util.Properties ; 60 import java.util.Vector ; 61 import java.util.Enumeration ; 62 63 71 class GroupedAggregateResultSet extends GenericAggregateResultSet 72 implements CursorResultSet { 73 74 75 public int rowsInput; 76 public int rowsReturned; 77 78 private ColumnOrdering[] order; 81 private ExecIndexRow sortTemplateRow; 82 public boolean hasDistinctAggregate; public boolean isInSortedOrder; private int maxRowSize; 85 86 private ScanController scanController; 88 89 private ExecIndexRow sourceExecIndexRow; 91 92 private ExecIndexRow sortResultRow; 93 94 private ExecIndexRow currSortedRow; 96 private boolean nextCalled; 97 98 private long distinctAggSortId; 100 private boolean dropDistinctAggSort; 101 private long genericSortId; 102 private boolean dropGenericSort; 103 private TransactionController tc; 104 105 public Properties sortProperties = new Properties (); 107 108 127 GroupedAggregateResultSet(NoPutResultSet s, 128 boolean isInSortedOrder, 129 int aggregateItem, 130 int orderingItem, 131 Activation a, 132 GeneratedMethod ra, 133 int maxRowSize, 134 int resultSetNumber, 135 double optimizerEstimatedRowCount, 136 double optimizerEstimatedCost) throws StandardException 137 { 138 super(s, aggregateItem, a, ra, resultSetNumber, optimizerEstimatedRowCount, optimizerEstimatedCost); 139 this.isInSortedOrder = isInSortedOrder; 140 sortTemplateRow = getExecutionFactory().getIndexableRow((ExecRow) rowAllocator.invoke(activation)); 141 order = (ColumnOrdering[]) 142 ((FormatableArrayHolder) 143 (a.getPreparedStatement().getSavedObject(orderingItem))) 144 .getArray(ColumnOrdering.class); 145 146 if (SanityManager.DEBUG) 147 { 148 SanityManager.DEBUG("AggregateTrace","execution time: "+ 149 a.getPreparedStatement().getSavedObject(aggregateItem)); 150 } 151 152 constructorTime += getElapsedMillis(beginTime); 153 } 154 155 156 162 168 public void openCore() throws StandardException 169 { 170 beginTime = getCurrentTimeMillis(); 171 if (SanityManager.DEBUG) 175 SanityManager.ASSERT( ! isOpen, "GroupedAggregateResultSet already open"); 176 177 sortResultRow = getExecutionFactory().getIndexableRow(sortTemplateRow.getClone()); 178 sourceExecIndexRow = getExecutionFactory().getIndexableRow(sortTemplateRow.getClone()); 179 180 source.openCore(); 181 182 187 if (isInSortedOrder) 188 { 189 currSortedRow = getNextRowFromRS(); 190 if (currSortedRow != null) 191 { 192 currSortedRow = (ExecIndexRow) currSortedRow.getClone(); 193 initializeVectorAggregation(currSortedRow); 194 } 195 } 196 else 197 { 198 201 scanController = loadSorter(); 202 } 203 204 isOpen = true; 205 numOpens++; 206 207 openTime += getElapsedMillis(beginTime); 208 } 209 210 221 private ScanController loadSorter() 222 throws StandardException 223 { 224 SortController sorter; 225 long sortId; 226 ExecRow sourceRow; 227 ExecRow inputRow; 228 int inputRowCountEstimate = (int) optimizerEstimatedRowCount; 229 boolean inOrder = isInSortedOrder; 230 231 tc = getTransactionController(); 232 233 ColumnOrdering[] currentOrdering = order; 234 235 242 if (aggInfoList.hasDistinct()) 243 { 244 hasDistinctAggregate = true; 245 246 GenericAggregator[] aggsNoDistinct = getSortAggregators(aggInfoList, true, 247 activation.getLanguageConnectionContext(), source); 248 SortObserver sortObserver = new AggregateSortObserver(true, aggsNoDistinct, aggregates, 249 sortTemplateRow); 250 251 sortId = tc.createSort((Properties )null, 252 sortTemplateRow.getRowArray(), 253 order, 254 sortObserver, 255 false, inputRowCountEstimate, maxRowSize ); 259 sorter = tc.openSort(sortId); 260 distinctAggSortId = sortId; 261 dropDistinctAggSort = true; 262 263 while ((sourceRow = source.getNextRowCore())!=null) 264 { 265 sorter.insert(sourceRow.getRowArray()); 266 rowsInput++; 267 } 268 269 272 source.close(); 273 sortProperties = sorter.getSortInfo().getAllSortInfo(sortProperties); 274 sorter.close(); 275 276 scanController = 277 tc.openSortScan(sortId, activation.getResultSetHoldability()); 278 279 285 inOrder = true; 286 inputRowCountEstimate = rowsInput; 287 288 301 if (order.length == 1) 302 { 303 return scanController; 304 } 305 306 ColumnOrdering[] newOrder = new ColumnOrdering[order.length - 1]; 307 System.arraycopy(order, 0, newOrder, 0, order.length - 1); 308 currentOrdering = newOrder; 309 } 310 311 SortObserver sortObserver = new AggregateSortObserver(true, aggregates, aggregates, 312 sortTemplateRow); 313 314 sortId = tc.createSort((Properties )null, 315 sortTemplateRow.getRowArray(), 316 currentOrdering, 317 sortObserver, 318 inOrder, 319 inputRowCountEstimate, maxRowSize ); 322 sorter = tc.openSort(sortId); 323 genericSortId = sortId; 324 dropGenericSort = true; 325 326 327 while ((inputRow = getNextRowFromRS()) != null) 328 { 329 sorter.insert(inputRow.getRowArray()); 330 } 331 source.close(); 332 sortProperties = sorter.getSortInfo().getAllSortInfo(sortProperties); 333 sorter.close(); 334 335 return tc.openSortScan(sortId, activation.getResultSetHoldability()); 336 } 337 338 339 347 public ExecRow getNextRowCore() throws StandardException 348 { 349 if (!isOpen) 350 { 351 return null; 352 } 353 354 beginTime = getCurrentTimeMillis(); 355 356 if (isInSortedOrder) 358 { 359 if (currSortedRow == null) 361 { 362 nextTime += getElapsedMillis(beginTime); 363 return null; 364 } 365 366 ExecIndexRow nextRow = getNextRowFromRS(); 367 368 369 while (nextRow != null) 370 { 371 374 if (! sameGroupingValues(currSortedRow, nextRow)) 375 { 376 ExecIndexRow result = currSortedRow; 377 378 379 currSortedRow = (ExecIndexRow) nextRow.getClone(); 380 initializeVectorAggregation(currSortedRow); 381 382 nextTime += getElapsedMillis(beginTime); 383 rowsReturned++; 384 return finishAggregation(result); 385 } 386 else 387 { 388 389 initializeVectorAggregation(nextRow); 390 mergeVectorAggregates(nextRow, currSortedRow); 391 } 392 393 nextRow = getNextRowFromRS(); 395 } 396 397 ExecIndexRow result = currSortedRow; 399 currSortedRow = null; 400 nextTime += getElapsedMillis(beginTime); 401 return finishAggregation(result); 402 } 403 else 404 { 405 ExecIndexRow sortResult = null; 406 407 if ((sortResult = getNextRowFromRS()) != null) 408 { 409 setCurrentRow(sortResult); 410 } 411 412 418 if (sortResult != null) 419 { 420 sortResult = finishAggregation(sortResult); 421 currentRow = sortResult; 422 } 423 424 if (sortResult != null) 425 { 426 rowsReturned++; 427 } 428 429 nextTime += getElapsedMillis(beginTime); 430 return sortResult; 431 } 432 } 433 434 447 private boolean sameGroupingValues(ExecRow currRow, ExecRow newRow) 448 throws StandardException 449 { 450 for (int index = 0; index < order.length; index++) 451 { 452 DataValueDescriptor currOrderable = currRow.getColumn(order[index].getColumnId() + 1); 453 DataValueDescriptor newOrderable = newRow.getColumn(order[index].getColumnId() + 1); 454 if (! (currOrderable.compare(DataValueDescriptor.ORDER_OP_EQUALS, newOrderable, true, true))) 455 { 456 return false; 457 } 458 } 459 return true; 460 } 461 462 468 public void close() throws StandardException 469 { 470 beginTime = getCurrentTimeMillis(); 471 if ( isOpen ) 472 { 473 clearCurrentRow(); 478 479 sortResultRow = null; 480 sourceExecIndexRow = null; 481 closeSource(); 482 483 if (dropDistinctAggSort) 484 { 485 tc.dropSort(distinctAggSortId); 486 dropDistinctAggSort = false; 487 } 488 489 if (dropGenericSort) 490 { 491 tc.dropSort(genericSortId); 492 dropGenericSort = false; 493 } 494 super.close(); 495 } 496 else 497 if (SanityManager.DEBUG) 498 SanityManager.DEBUG("CloseRepeatInfo","Close of SortResultSet repeated"); 499 500 closeTime += getElapsedMillis(beginTime); 501 502 isOpen = false; 503 } 504 505 513 public long getTimeSpent(int type) 514 { 515 long totTime = constructorTime + openTime + nextTime + 516 closeTime; 517 518 if (type == NoPutResultSet.CURRENT_RESULTSET_ONLY) 519 { 520 return totTime - originalSource.getTimeSpent(ENTIRE_RESULTSET_TREE); 521 } 522 else 523 { 524 return totTime; 525 } 526 } 527 528 534 544 public RowLocation getRowLocation() throws StandardException 545 { 546 if (! isOpen) return null; 547 548 RowLocation rl; 551 rl = scanController.newRowLocationTemplate(); 552 scanController.fetchLocation(rl); 553 return rl; 554 } 555 556 565 568 public ExecRow getCurrentRow() throws StandardException 569 { 570 if (SanityManager.DEBUG) 571 SanityManager.ASSERT(isOpen, "SortResultSet expected to be open"); 572 573 return currentRow; 574 } 575 576 584 private ExecIndexRow getNextRowFromRS() 585 throws StandardException 586 { 587 return (scanController == null) ? 588 getRowFromResultSet() : 589 getRowFromSorter(); 590 } 591 592 595 private ExecIndexRow getRowFromResultSet() 596 throws StandardException 597 { 598 ExecRow sourceRow; 599 ExecIndexRow inputRow = null; 600 601 if ((sourceRow = source.getNextRowCore()) != null) 602 { 603 rowsInput++; 604 sourceExecIndexRow.execRowToExecIndexRow(sourceRow); 605 inputRow = sourceExecIndexRow; 606 } 607 608 return inputRow; 609 } 610 611 612 616 private ExecIndexRow getRowFromSorter() 617 throws StandardException 618 { 619 ExecIndexRow inputRow = null; 620 621 if (scanController.next()) 622 { 623 currentRow = sortResultRow; 627 628 inputRow = getExecutionFactory().getIndexableRow(currentRow); 629 630 scanController.fetch(inputRow.getRowArray()); 631 } 632 return inputRow; 633 } 634 635 640 public void closeSource() throws StandardException 641 { 642 if (scanController == null) 643 { 644 649 source.close(); 650 } 651 else 652 { 653 scanController.close(); 654 scanController = null; 655 } 656 } 657 658 674 private void initializeVectorAggregation(ExecRow row) 675 throws StandardException 676 { 677 int size = aggregates.length; 678 679 if (SanityManager.DEBUG) 680 { 681 SanityManager.ASSERT(row != null, 682 "Null row passed to initializeVectorAggregation"); 683 } 684 685 for (int i = 0; i < size; i++) 686 { 687 GenericAggregator currAggregate = aggregates[i]; 688 689 currAggregate.initialize(row); 691 692 currAggregate.accumulate(row, row); 694 } 695 } 696 697 706 private void mergeVectorAggregates(ExecRow newRow, ExecRow currRow) 707 throws StandardException 708 { 709 for (int i = 0; i < aggregates.length; i++) 710 { 711 GenericAggregator currAggregate = aggregates[i]; 712 713 currAggregate.merge(newRow, currRow); 715 } 716 } 717 718 } 719 | Popular Tags |