@ -755,7 +755,7 @@ process_ordered_aggregate_single(AggState *aggstate,
( ( oldIsNull & & * isNull ) | |
( ! oldIsNull & & ! * isNull & &
oldAbbrevVal = = newAbbrevVal & &
DatumGetBool ( FunctionCall2 ( & pertrans - > equalfnOne ,
DatumGetBool ( FunctionCall2 ( & pertrans - > equalfns [ 0 ] ,
oldVal , * newVal ) ) ) ) )
{
/* equal to prior, so forget this one */
@ -802,7 +802,7 @@ process_ordered_aggregate_multi(AggState *aggstate,
AggStatePerTrans pertrans ,
AggStatePerGroup pergroupstate )
{
ExprContext * tmp context = aggstate - > tmpcontext ;
MemoryContext work context = aggstate - > tmpcontext - > ecxt_per_tuple_memory ;
FunctionCallInfo fcinfo = & pertrans - > transfn_fcinfo ;
TupleTableSlot * slot1 = pertrans - > sortslot ;
TupleTableSlot * slot2 = pertrans - > uniqslot ;
@ -811,7 +811,6 @@ process_ordered_aggregate_multi(AggState *aggstate,
Datum newAbbrevVal = ( Datum ) 0 ;
Datum oldAbbrevVal = ( Datum ) 0 ;
bool haveOldValue = false ;
TupleTableSlot * save = aggstate - > tmpcontext - > ecxt_outertuple ;
int i ;
tuplesort_performsort ( pertrans - > sortstates [ aggstate - > current_set ] ) ;
@ -825,20 +824,22 @@ process_ordered_aggregate_multi(AggState *aggstate,
{
CHECK_FOR_INTERRUPTS ( ) ;
tmpcontext - > ecxt_outertuple = slot1 ;
tmpcontext - > ecxt_innertuple = slot2 ;
/*
* Extract the first numTransInputs columns as datums to pass to the
* transfn . ( This will help execTuplesMatch too , so we do it
* immediately . )
*/
slot_getsomeattrs ( slot1 , numTransInputs ) ;
if ( numDistinctCols = = 0 | |
! haveOldValue | |
newAbbrevVal ! = oldAbbrevVal | |
! ExecQual ( pertrans - > equalfnMulti , tmpcontext ) )
! execTuplesMatch ( slot1 , slot2 ,
numDistinctCols ,
pertrans - > sortColIdx ,
pertrans - > equalfns ,
workcontext ) )
{
/*
* Extract the first numTransInputs columns as datums to pass to
* the transfn .
*/
slot_getsomeattrs ( slot1 , numTransInputs ) ;
/* Load values into fcinfo */
/* Start from 1, since the 0th arg will be the transition value */
for ( i = 0 ; i < numTransInputs ; i + + )
@ -856,14 +857,15 @@ process_ordered_aggregate_multi(AggState *aggstate,
slot2 = slot1 ;
slot1 = tmpslot ;
/* avoid ExecQual () calls by reusing abbreviated keys */
/* avoid execTuplesMatch () calls by reusing abbreviated keys */
oldAbbrevVal = newAbbrevVal ;
haveOldValue = true ;
}
}
/* Reset context each time */
ResetExprContext ( tmpcontext ) ;
/* Reset context each time, unless execTuplesMatch did it for us */
if ( numDistinctCols = = 0 )
MemoryContextReset ( workcontext ) ;
ExecClearTuple ( slot1 ) ;
}
@ -873,9 +875,6 @@ process_ordered_aggregate_multi(AggState *aggstate,
tuplesort_end ( pertrans - > sortstates [ aggstate - > current_set ] ) ;
pertrans - > sortstates [ aggstate - > current_set ] = NULL ;
/* restore previous slot, potentially in use for grouping sets */
tmpcontext - > ecxt_outertuple = save ;
}
/*
@ -1277,9 +1276,7 @@ build_hash_table(AggState *aggstate)
Assert ( perhash - > aggnode - > numGroups > 0 ) ;
perhash - > hashtable = BuildTupleHashTable ( & aggstate - > ss . ps ,
perhash - > hashslot - > tts_tupleDescriptor ,
perhash - > numCols ,
perhash - > hashtable = BuildTupleHashTable ( perhash - > numCols ,
perhash - > hashGrpColIdxHash ,
perhash - > eqfunctions ,
perhash - > hashfunctions ,
@ -1317,7 +1314,6 @@ find_hash_columns(AggState *aggstate)
Bitmapset * base_colnos ;
List * outerTlist = outerPlanState ( aggstate ) - > plan - > targetlist ;
int numHashes = aggstate - > num_hashes ;
EState * estate = aggstate - > ss . ps . state ;
int j ;
/* Find Vars that will be needed in tlist and qual */
@ -1397,12 +1393,6 @@ find_hash_columns(AggState *aggstate)
}
hashDesc = ExecTypeFromTL ( hashTlist , false ) ;
execTuplesHashPrepare ( perhash - > numCols ,
perhash - > aggnode - > grpOperators ,
& perhash - > eqfunctions ,
& perhash - > hashfunctions ) ;
perhash - > hashslot = ExecAllocTableSlot ( & estate - > es_tupleTable ) ;
ExecSetSlotDescriptor ( perhash - > hashslot , hashDesc ) ;
list_free ( hashTlist ) ;
@ -1704,14 +1694,17 @@ agg_retrieve_direct(AggState *aggstate)
* of the next grouping set
* - - - - - - - - - -
*/
tmpcontext - > ecxt_innertuple = econtext - > ecxt_outertuple ;
if ( aggstate - > input_done | |
( node - > aggstrategy ! = AGG_PLAIN & &
aggstate - > projected_set ! = - 1 & &
aggstate - > projected_set < ( numGroupingSets - 1 ) & &
nextSetSize > 0 & &
! ExecQualAndReset ( aggstate - > phase - > eqfunctions [ nextSetSize - 1 ] ,
tmpcontext ) ) )
! execTuplesMatch ( econtext - > ecxt_outertuple ,
tmpcontext - > ecxt_outertuple ,
nextSetSize ,
node - > grpColIdx ,
aggstate - > phase - > eqfunctions ,
tmpcontext - > ecxt_per_tuple_memory ) ) )
{
aggstate - > projected_set + = 1 ;
@ -1854,9 +1847,12 @@ agg_retrieve_direct(AggState *aggstate)
*/
if ( node - > aggstrategy ! = AGG_PLAIN )
{
tmpcontext - > ecxt_innertuple = firstSlot ;
if ( ! ExecQual ( aggstate - > phase - > eqfunctions [ node - > numCols - 1 ] ,
tmpcontext ) )
if ( ! execTuplesMatch ( firstSlot ,
outerslot ,
node - > numCols ,
node - > grpColIdx ,
aggstate - > phase - > eqfunctions ,
tmpcontext - > ecxt_per_tuple_memory ) )
{
aggstate - > grp_firstTuple = ExecCopySlotTuple ( outerslot ) ;
break ;
@ -2082,7 +2078,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
AggStatePerGroup * pergroups ;
Plan * outerPlan ;
ExprContext * econtext ;
TupleDesc scanDesc ;
int numaggs ,
transno ,
aggno ;
@ -2238,9 +2233,9 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
* initialize source tuple type .
*/
ExecAssignScanTypeFromOuterPlan ( & aggstate - > ss ) ;
scanDesc = aggstate - > ss . ss_ScanTupleSlot - > tts_tupleDescriptor ;
if ( node - > chain )
ExecSetSlotDescriptor ( aggstate - > sort_slot , scanDesc ) ;
ExecSetSlotDescriptor ( aggstate - > sort_slot ,
aggstate - > ss . ss_ScanTupleSlot - > tts_tupleDescriptor ) ;
/*
* Initialize result tuple type and projection info .
@ -2360,43 +2355,11 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
*/
if ( aggnode - > aggstrategy = = AGG_SORTED )
{
int i = 0 ;
Assert ( aggnode - > numCols > 0 ) ;
/*
* Build a separate function for each subset of columns that
* need to be compared .
*/
phasedata - > eqfunctions =
( ExprState * * ) palloc0 ( aggnode - > numCols * sizeof ( ExprState * ) ) ;
/* for each grouping set */
for ( i = 0 ; i < phasedata - > numsets ; i + + )
{
int length = phasedata - > gset_lengths [ i ] ;
if ( phasedata - > eqfunctions [ length - 1 ] ! = NULL )
continue ;
phasedata - > eqfunctions [ length - 1 ] =
execTuplesMatchPrepare ( scanDesc ,
length ,
aggnode - > grpColIdx ,
aggnode - > grpOperators ,
( PlanState * ) aggstate ) ;
}
/* and for all grouped columns, unless already computed */
if ( phasedata - > eqfunctions [ aggnode - > numCols - 1 ] = = NULL )
{
phasedata - > eqfunctions [ aggnode - > numCols - 1 ] =
execTuplesMatchPrepare ( scanDesc ,
aggnode - > numCols ,
aggnode - > grpColIdx ,
aggnode - > grpOperators ,
( PlanState * ) aggstate ) ;
}
execTuplesMatchPrepare ( aggnode - > numCols ,
aggnode - > grpOperators ) ;
}
phasedata - > aggnode = aggnode ;
@ -2449,6 +2412,16 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
*/
if ( use_hashing )
{
for ( i = 0 ; i < numHashes ; + + i )
{
aggstate - > perhash [ i ] . hashslot = ExecInitExtraTupleSlot ( estate ) ;
execTuplesHashPrepare ( aggstate - > perhash [ i ] . numCols ,
aggstate - > perhash [ i ] . aggnode - > grpOperators ,
& aggstate - > perhash [ i ] . eqfunctions ,
& aggstate - > perhash [ i ] . hashfunctions ) ;
}
/* this is an array of pointers, not structures */
aggstate - > hash_pergroup = pergroups ;
@ -3128,28 +3101,24 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
if ( aggref - > aggdistinct )
{
Oid * ops ;
Assert ( numArguments > 0 ) ;
Assert ( list_length ( aggref - > aggdistinct ) = = numDistinctCols ) ;
ops = palloc ( numDistinctCols * sizeof ( Oid ) ) ;
/*
* We need the equal function for each DISTINCT comparison we will
* make .
*/
pertrans - > equalfns =
( FmgrInfo * ) palloc ( numDistinctCols * sizeof ( FmgrInfo ) ) ;
i = 0 ;
foreach ( lc , aggref - > aggdistinct )
ops [ i + + ] = ( ( SortGroupClause * ) lfirst ( lc ) ) - > eqop ;
{
SortGroupClause * sortcl = ( SortGroupClause * ) lfirst ( lc ) ;
/* lookup / build the necessary comparators */
if ( numDistinctCols = = 1 )
fmgr_info ( get_opcode ( ops [ 0 ] ) , & pertrans - > equalfnOne ) ;
else
pertrans - > equalfnMulti =
execTuplesMatchPrepare ( pertrans - > sortdesc ,
numDistinctCols ,
pertrans - > sortColIdx ,
ops ,
& aggstate - > ss . ps ) ;
pfree ( ops ) ;
fmgr_info ( get_opcode ( sortcl - > eqop ) , & pertrans - > equalfns [ i ] ) ;
i + + ;
}
Assert ( i = = numDistinctCols ) ;
}
pertrans - > sortstates = ( Tuplesortstate * * )