mirror of
https://github.com/postgres/postgres.git
synced 2025-08-28 18:48:04 +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:
@@ -41,10 +41,10 @@ typedef Datum (*PGFunction) (FunctionCallInfo fcinfo);
|
||||
* to be called multiple times, the lookup need be done only once and the
|
||||
* info struct saved for re-use.
|
||||
*
|
||||
* Note that fn_collation and fn_expr really are parse-time-determined
|
||||
* information about the arguments, rather than about the function itself.
|
||||
* But it's convenient to store them here rather than in FunctionCallInfoData,
|
||||
* where they might more logically belong.
|
||||
* Note that fn_expr really is parse-time-determined information about the
|
||||
* arguments, rather than about the function itself. But it's convenient
|
||||
* to store it here rather than in FunctionCallInfoData, where it might more
|
||||
* logically belong.
|
||||
*/
|
||||
typedef struct FmgrInfo
|
||||
{
|
||||
@@ -55,7 +55,6 @@ typedef struct FmgrInfo
|
||||
bool fn_strict; /* function is "strict" (NULL in => NULL out) */
|
||||
bool fn_retset; /* function returns a set */
|
||||
unsigned char fn_stats; /* collect stats if track_functions > this */
|
||||
Oid fn_collation; /* collation that function should use */
|
||||
void *fn_extra; /* extra space for use by handler */
|
||||
MemoryContext fn_mcxt; /* memory context to store fn_extra in */
|
||||
fmNodePtr fn_expr; /* expression parse tree for call, or NULL */
|
||||
@@ -69,6 +68,7 @@ typedef struct FunctionCallInfoData
|
||||
FmgrInfo *flinfo; /* ptr to lookup info used for this call */
|
||||
fmNodePtr context; /* pass info about context of call */
|
||||
fmNodePtr resultinfo; /* pass or return extra info about result */
|
||||
Oid fncollation; /* collation for function to use */
|
||||
bool isnull; /* function must set true if result is NULL */
|
||||
short nargs; /* # arguments actually passed */
|
||||
Datum arg[FUNC_MAX_ARGS]; /* Arguments passed to function */
|
||||
@@ -89,9 +89,7 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
|
||||
extern void fmgr_info_cxt(Oid functionId, FmgrInfo *finfo,
|
||||
MemoryContext mcxt);
|
||||
|
||||
/* Macros for setting the fn_collation and fn_expr fields */
|
||||
#define fmgr_info_set_collation(collationId, finfo) \
|
||||
((finfo)->fn_collation = (collationId))
|
||||
/* Convenience macro for setting the fn_expr field */
|
||||
#define fmgr_info_set_expr(expr, finfo) \
|
||||
((finfo)->fn_expr = (expr))
|
||||
|
||||
@@ -108,11 +106,12 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
|
||||
* explicitly set each required element to false, so we don't try to zero
|
||||
* out the argnull[] array in the macro.
|
||||
*/
|
||||
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Context, Resultinfo) \
|
||||
#define InitFunctionCallInfoData(Fcinfo, Flinfo, Nargs, Collation, Context, Resultinfo) \
|
||||
do { \
|
||||
(Fcinfo).flinfo = (Flinfo); \
|
||||
(Fcinfo).context = (Context); \
|
||||
(Fcinfo).resultinfo = (Resultinfo); \
|
||||
(Fcinfo).fncollation = (Collation); \
|
||||
(Fcinfo).isnull = false; \
|
||||
(Fcinfo).nargs = (Nargs); \
|
||||
} while (0)
|
||||
@@ -150,8 +149,7 @@ extern void fmgr_info_copy(FmgrInfo *dstinfo, FmgrInfo *srcinfo,
|
||||
/*
|
||||
* Get collation function should use.
|
||||
*/
|
||||
#define PG_GET_COLLATION() \
|
||||
(fcinfo->flinfo ? fcinfo->flinfo->fn_collation : InvalidOid)
|
||||
#define PG_GET_COLLATION() (fcinfo->fncollation)
|
||||
|
||||
/*
|
||||
* Get number of arguments passed to function.
|
||||
@@ -434,56 +432,68 @@ extern int no_such_variable
|
||||
* directly-computed parameter list. Note that neither arguments nor result
|
||||
* are allowed to be NULL.
|
||||
*/
|
||||
extern Datum DirectFunctionCall1(PGFunction func, Datum arg1);
|
||||
extern Datum DirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2);
|
||||
extern Datum DirectFunctionCall3(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall1Coll(PGFunction func, Oid collation,
|
||||
Datum arg1);
|
||||
extern Datum DirectFunctionCall2Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2);
|
||||
extern Datum DirectFunctionCall3Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3);
|
||||
extern Datum DirectFunctionCall4(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall4Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4);
|
||||
extern Datum DirectFunctionCall5(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall5Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5);
|
||||
extern Datum DirectFunctionCall6(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall6Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6);
|
||||
extern Datum DirectFunctionCall7(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall7Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7);
|
||||
extern Datum DirectFunctionCall8(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall8Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8);
|
||||
extern Datum DirectFunctionCall9(PGFunction func, Datum arg1, Datum arg2,
|
||||
extern Datum DirectFunctionCall9Coll(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8,
|
||||
Datum arg9);
|
||||
|
||||
/* The same, but passing a collation to use */
|
||||
extern Datum DirectFunctionCall1WithCollation(PGFunction func, Oid collation,
|
||||
Datum arg1);
|
||||
extern Datum DirectFunctionCall2WithCollation(PGFunction func, Oid collation,
|
||||
Datum arg1, Datum arg2);
|
||||
|
||||
/* These are for invocation of a previously-looked-up function with a
|
||||
* directly-computed parameter list. Note that neither arguments nor result
|
||||
* are allowed to be NULL.
|
||||
*/
|
||||
extern Datum FunctionCall1(FmgrInfo *flinfo, Datum arg1);
|
||||
extern Datum FunctionCall2(FmgrInfo *flinfo, Datum arg1, Datum arg2);
|
||||
extern Datum FunctionCall3(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall1Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1);
|
||||
extern Datum FunctionCall2Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2);
|
||||
extern Datum FunctionCall3Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3);
|
||||
extern Datum FunctionCall4(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall4Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4);
|
||||
extern Datum FunctionCall5(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall5Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5);
|
||||
extern Datum FunctionCall6(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall6Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6);
|
||||
extern Datum FunctionCall7(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall7Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7);
|
||||
extern Datum FunctionCall8(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall8Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8);
|
||||
extern Datum FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
extern Datum FunctionCall9Coll(FmgrInfo *flinfo, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8,
|
||||
Datum arg9);
|
||||
@@ -494,29 +504,100 @@ extern Datum FunctionCall9(FmgrInfo *flinfo, Datum arg1, Datum arg2,
|
||||
* by FunctionCallN(). If the same function is to be invoked repeatedly,
|
||||
* do the FunctionLookup() once and then use FunctionCallN().
|
||||
*/
|
||||
extern Datum OidFunctionCall0(Oid functionId);
|
||||
extern Datum OidFunctionCall1(Oid functionId, Datum arg1);
|
||||
extern Datum OidFunctionCall2(Oid functionId, Datum arg1, Datum arg2);
|
||||
extern Datum OidFunctionCall3(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall0Coll(Oid functionId, Oid collation);
|
||||
extern Datum OidFunctionCall1Coll(Oid functionId, Oid collation,
|
||||
Datum arg1);
|
||||
extern Datum OidFunctionCall2Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2);
|
||||
extern Datum OidFunctionCall3Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3);
|
||||
extern Datum OidFunctionCall4(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall4Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4);
|
||||
extern Datum OidFunctionCall5(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall5Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5);
|
||||
extern Datum OidFunctionCall6(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall6Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6);
|
||||
extern Datum OidFunctionCall7(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall7Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7);
|
||||
extern Datum OidFunctionCall8(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall8Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8);
|
||||
extern Datum OidFunctionCall9(Oid functionId, Datum arg1, Datum arg2,
|
||||
extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation,
|
||||
Datum arg1, Datum arg2,
|
||||
Datum arg3, Datum arg4, Datum arg5,
|
||||
Datum arg6, Datum arg7, Datum arg8,
|
||||
Datum arg9);
|
||||
|
||||
/* These macros allow the collation argument to be omitted (with a default of
|
||||
* InvalidOid, ie, no collation). They exist mostly for backwards
|
||||
* compatibility of source code.
|
||||
*/
|
||||
#define DirectFunctionCall1(func, arg1) \
|
||||
DirectFunctionCall1Coll(func, InvalidOid, arg1)
|
||||
#define DirectFunctionCall2(func, arg1, arg2) \
|
||||
DirectFunctionCall2Coll(func, InvalidOid, arg1, arg2)
|
||||
#define DirectFunctionCall3(func, arg1, arg2, arg3) \
|
||||
DirectFunctionCall3Coll(func, InvalidOid, arg1, arg2, arg3)
|
||||
#define DirectFunctionCall4(func, arg1, arg2, arg3, arg4) \
|
||||
DirectFunctionCall4Coll(func, InvalidOid, arg1, arg2, arg3, arg4)
|
||||
#define DirectFunctionCall5(func, arg1, arg2, arg3, arg4, arg5) \
|
||||
DirectFunctionCall5Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||
#define DirectFunctionCall6(func, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||
DirectFunctionCall6Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
#define DirectFunctionCall7(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||
DirectFunctionCall7Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
#define DirectFunctionCall8(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||
DirectFunctionCall8Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
#define DirectFunctionCall9(func, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||
DirectFunctionCall9Coll(func, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
#define FunctionCall1(flinfo, arg1) \
|
||||
FunctionCall1Coll(flinfo, InvalidOid, arg1)
|
||||
#define FunctionCall2(flinfo, arg1, arg2) \
|
||||
FunctionCall2Coll(flinfo, InvalidOid, arg1, arg2)
|
||||
#define FunctionCall3(flinfo, arg1, arg2, arg3) \
|
||||
FunctionCall3Coll(flinfo, InvalidOid, arg1, arg2, arg3)
|
||||
#define FunctionCall4(flinfo, arg1, arg2, arg3, arg4) \
|
||||
FunctionCall4Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4)
|
||||
#define FunctionCall5(flinfo, arg1, arg2, arg3, arg4, arg5) \
|
||||
FunctionCall5Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||
#define FunctionCall6(flinfo, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||
FunctionCall6Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
#define FunctionCall7(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||
FunctionCall7Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
#define FunctionCall8(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||
FunctionCall8Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
#define FunctionCall9(flinfo, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||
FunctionCall9Coll(flinfo, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
#define OidFunctionCall0(functionId) \
|
||||
OidFunctionCall0Coll(functionId, InvalidOid)
|
||||
#define OidFunctionCall1(functionId, arg1) \
|
||||
OidFunctionCall1Coll(functionId, InvalidOid, arg1)
|
||||
#define OidFunctionCall2(functionId, arg1, arg2) \
|
||||
OidFunctionCall2Coll(functionId, InvalidOid, arg1, arg2)
|
||||
#define OidFunctionCall3(functionId, arg1, arg2, arg3) \
|
||||
OidFunctionCall3Coll(functionId, InvalidOid, arg1, arg2, arg3)
|
||||
#define OidFunctionCall4(functionId, arg1, arg2, arg3, arg4) \
|
||||
OidFunctionCall4Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4)
|
||||
#define OidFunctionCall5(functionId, arg1, arg2, arg3, arg4, arg5) \
|
||||
OidFunctionCall5Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5)
|
||||
#define OidFunctionCall6(functionId, arg1, arg2, arg3, arg4, arg5, arg6) \
|
||||
OidFunctionCall6Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6)
|
||||
#define OidFunctionCall7(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
|
||||
OidFunctionCall7Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7)
|
||||
#define OidFunctionCall8(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) \
|
||||
OidFunctionCall8Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
|
||||
#define OidFunctionCall9(functionId, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) \
|
||||
OidFunctionCall9Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
|
||||
|
||||
|
||||
/* Special cases for convenient invocation of datatype I/O functions. */
|
||||
extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
|
||||
Oid typioparam, int32 typmod);
|
||||
|
Reference in New Issue
Block a user