* @return the sort controller
*/
private ScanController loadSorter()
throws StandardException
{
SortController sorter;
long sortId;
ExecRow sourceRow;
ExecRow inputRow;
int inputRowCountEstimate = (int) optimizerEstimatedRowCount;
boolean inOrder = isInSortedOrder;
tc = getTransactionController();
ColumnOrdering[] currentOrdering = order;
/*
** Do we have any distinct aggregates? If so, we'll need
** a separate sort. We use all of the sorting columns and
** drop the aggregation on the distinct column. Then
** we'll feed this into the sorter again w/o the distinct
** column in the ordering list.
*/
if (aggInfoList.hasDistinct())
{
hasDistinctAggregate = true;
GenericAggregator[] aggsNoDistinct = getSortAggregators(aggInfoList, true,
activation.getLanguageConnectionContext(), source);
SortObserver sortObserver = new AggregateSortObserver(true, aggsNoDistinct, aggregates,
sortTemplateRow);
sortId = tc.createSort((Properties)null,
sortTemplateRow.getRowArray(),
order,
sortObserver,
false, // not in order
inputRowCountEstimate, // est rows, -1 means no idea
maxRowSize // est rowsize
);
sorter = tc.openSort(sortId);
distinctAggSortId = sortId;
dropDistinctAggSort = true;
while ((sourceRow = source.getNextRowCore())!=null)
{
sorter.insert(sourceRow.getRowArray());
rowsInput++;
}
/*
** End the sort and open up the result set
*/
source.close();
sortProperties = sorter.getSortInfo().getAllSortInfo(sortProperties);
sorter.completedInserts();
scanController =
tc.openSortScan(sortId, activation.getResultSetHoldability());
/*
** Aggs are initialized and input rows
** are in order. All we have to do is
** another sort to remove (merge) the
** duplicates in the distinct column
*/
inOrder = true;
inputRowCountEstimate = rowsInput;
/*
** Drop the last column from the ordering. The
** last column is the distinct column. Don't
** pay any attention to the fact that the ordering
** object's name happens to correspond to a techo
** band from the 80's.
**
** If there aren't any ordering columns other
** than the distinct (i.e. for scalar distincts)
** just skip the 2nd sort altogether -- we'll
** do the aggregate merge ourselves rather than
** force a 2nd sort.
*/
if (order.length == 1)
{
return scanController;
}
ColumnOrdering[] newOrder = new ColumnOrdering[order.length - 1];
System.arraycopy(order, 0, newOrder, 0, order.length - 1);
currentOrdering = newOrder;
}
SortObserver sortObserver = new AggregateSortObserver(true, aggregates, aggregates,
sortTemplateRow);
sortId = tc.createSort((Properties)null,
sortTemplateRow.getRowArray(),
currentOrdering,
sortObserver,
inOrder,
inputRowCountEstimate, // est rows
maxRowSize // est rowsize
);
sorter = tc.openSort(sortId);
genericSortId = sortId;
dropGenericSort = true;
/* The sorter is responsible for doing the cloning */
while ((inputRow = getNextRowFromRS()) != null)
{
sorter.insert(inputRow.getRowArray());
}
source.close();
sortProperties = sorter.getSortInfo().getAllSortInfo(sortProperties);
sorter.completedInserts();
return tc.openSortScan(sortId, activation.getResultSetHoldability());
}