1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-30 21:42:05 +03:00

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...
This commit is contained in:
Tom Lane
2011-04-12 19:19:24 -04:00
parent 88543ecfec
commit d64713df7e
49 changed files with 552 additions and 418 deletions

View File

@ -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);