aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeAgg.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-04-12 19:19:24 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-04-12 19:19:24 -0400
commitd64713df7e5996ab3ab337b5e0901cf2c53773f9 (patch)
tree7105a61bf9fef5cef674cea7f1305dfeb77aa39a /src/backend/executor/nodeAgg.c
parent88543ecfec9c754b5f14b898bccbc68d941748b3 (diff)
downloadpostgresql-d64713df7e5996ab3ab337b5e0901cf2c53773f9.tar.gz
postgresql-d64713df7e5996ab3ab337b5e0901cf2c53773f9.zip
Pass collations to functions in FunctionCallInfoData, not FmgrInfo.
Since collation is effectively an argument, not a property of the function, FmgrInfo is really the wrong place for it; and this becomes critical in cases where a cached FmgrInfo is used for varying purposes that might need different collation settings. Fix by passing it in FunctionCallInfoData instead. In particular this allows a clean fix for bug #5970 (record_cmp not working). This requires touching a bit more code than the original method, but nobody ever thought that collations would not be an invasive patch...
Diffstat (limited to 'src/backend/executor/nodeAgg.c')
-rw-r--r--src/backend/executor/nodeAgg.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 47555bab55b..13d77234801 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -130,6 +130,9 @@ typedef struct AggStatePerAggData
FmgrInfo transfn;
FmgrInfo finalfn;
+ /* Input collation derived for aggregate */
+ Oid aggCollation;
+
/* number of sorting columns */
int numSortCols;
@@ -430,6 +433,7 @@ advance_transition_function(AggState *aggstate,
*/
InitFunctionCallInfoData(*fcinfo, &(peraggstate->transfn),
numArguments + 1,
+ peraggstate->aggCollation,
(void *) aggstate, NULL);
fcinfo->arg[0] = pergroupstate->transValue;
fcinfo->argnull[0] = pergroupstate->transValueIsNull;
@@ -597,6 +601,8 @@ process_ordered_aggregate_single(AggState *aggstate,
/*
* If DISTINCT mode, and not distinct from prior, skip it.
+ *
+ * Note: we assume equality functions don't care about collation.
*/
if (isDistinct &&
haveOldVal &&
@@ -737,6 +743,7 @@ finalize_aggregate(AggState *aggstate,
FunctionCallInfoData fcinfo;
InitFunctionCallInfoData(fcinfo, &(peraggstate->finalfn), 1,
+ peraggstate->aggCollation,
(void *) aggstate, NULL);
fcinfo.arg[0] = pergroupstate->transValue;
fcinfo.argnull[0] = pergroupstate->transValueIsNull;
@@ -1676,16 +1683,16 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
&finalfnexpr);
fmgr_info(transfn_oid, &peraggstate->transfn);
- fmgr_info_set_collation(aggref->inputcollid, &peraggstate->transfn);
fmgr_info_set_expr((Node *) transfnexpr, &peraggstate->transfn);
if (OidIsValid(finalfn_oid))
{
fmgr_info(finalfn_oid, &peraggstate->finalfn);
- fmgr_info_set_collation(aggref->inputcollid, &peraggstate->finalfn);
fmgr_info_set_expr((Node *) finalfnexpr, &peraggstate->finalfn);
}
+ peraggstate->aggCollation = aggref->inputcollid;
+
get_typlenbyval(aggref->aggtype,
&peraggstate->resulttypeLen,
&peraggstate->resulttypeByVal);
@@ -1833,8 +1840,6 @@ ExecInitAgg(Agg *node, EState *estate, int eflags)
SortGroupClause *sortcl = (SortGroupClause *) lfirst(lc);
fmgr_info(get_opcode(sortcl->eqop), &peraggstate->equalfns[i]);
- fmgr_info_set_collation(aggref->inputcollid,
- &peraggstate->equalfns[i]);
i++;
}
Assert(i == numDistinctCols);