mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +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:
@ -3127,6 +3127,7 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||
Oid collation = PG_GET_COLLATION();
|
||||
int ndims1 = ARR_NDIM(array1);
|
||||
int ndims2 = ARR_NDIM(array2);
|
||||
int *dims1 = ARR_DIMS(array1);
|
||||
@ -3184,7 +3185,7 @@ array_eq(PG_FUNCTION_ARGS)
|
||||
* apply the operator to each pair of array elements.
|
||||
*/
|
||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||
NULL, NULL);
|
||||
collation, NULL, NULL);
|
||||
|
||||
/* Loop over source data */
|
||||
nitems = ArrayGetNItems(ndims1, dims1);
|
||||
@ -3367,8 +3368,7 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
*/
|
||||
typentry = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
|
||||
if (typentry == NULL ||
|
||||
typentry->type_id != element_type ||
|
||||
typentry->cmp_proc_finfo.fn_collation != collation)
|
||||
typentry->type_id != element_type)
|
||||
{
|
||||
typentry = lookup_type_cache(element_type,
|
||||
TYPECACHE_CMP_PROC_FINFO);
|
||||
@ -3378,7 +3378,6 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
errmsg("could not identify a comparison function for type %s",
|
||||
format_type_be(element_type))));
|
||||
fcinfo->flinfo->fn_extra = (void *) typentry;
|
||||
typentry->cmp_proc_finfo.fn_collation = collation;
|
||||
}
|
||||
typlen = typentry->typlen;
|
||||
typbyval = typentry->typbyval;
|
||||
@ -3388,7 +3387,7 @@ array_cmp(FunctionCallInfo fcinfo)
|
||||
* apply the operator to each pair of array elements.
|
||||
*/
|
||||
InitFunctionCallInfoData(locfcinfo, &typentry->cmp_proc_finfo, 2,
|
||||
NULL, NULL);
|
||||
collation, NULL, NULL);
|
||||
|
||||
/* Loop over source data */
|
||||
min_nitems = Min(nitems1, nitems2);
|
||||
@ -3573,7 +3572,7 @@ hash_array(PG_FUNCTION_ARGS)
|
||||
* apply the hash function to each array element.
|
||||
*/
|
||||
InitFunctionCallInfoData(locfcinfo, &typentry->hash_proc_finfo, 1,
|
||||
NULL, NULL);
|
||||
InvalidOid, NULL, NULL);
|
||||
|
||||
/* Loop over source data */
|
||||
nitems = ArrayGetNItems(ndims, dims);
|
||||
@ -3647,8 +3646,8 @@ hash_array(PG_FUNCTION_ARGS)
|
||||
* When matchall is false, return true if any members of array1 are in array2.
|
||||
*/
|
||||
static bool
|
||||
array_contain_compare(ArrayType *array1, ArrayType *array2, bool matchall,
|
||||
void **fn_extra)
|
||||
array_contain_compare(ArrayType *array1, ArrayType *array2, Oid collation,
|
||||
bool matchall, void **fn_extra)
|
||||
{
|
||||
bool result = matchall;
|
||||
Oid element_type = ARR_ELEMTYPE(array1);
|
||||
@ -3707,7 +3706,7 @@ array_contain_compare(ArrayType *array1, ArrayType *array2, bool matchall,
|
||||
* Apply the comparison operator to each pair of array elements.
|
||||
*/
|
||||
InitFunctionCallInfoData(locfcinfo, &typentry->eq_opr_finfo, 2,
|
||||
NULL, NULL);
|
||||
collation, NULL, NULL);
|
||||
|
||||
/* Loop over source data */
|
||||
nelems1 = ArrayGetNItems(ARR_NDIM(array1), ARR_DIMS(array1));
|
||||
@ -3811,9 +3810,10 @@ arrayoverlap(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||
Oid collation = PG_GET_COLLATION();
|
||||
bool result;
|
||||
|
||||
result = array_contain_compare(array1, array2, false,
|
||||
result = array_contain_compare(array1, array2, collation, false,
|
||||
&fcinfo->flinfo->fn_extra);
|
||||
|
||||
/* Avoid leaking memory when handed toasted input. */
|
||||
@ -3828,9 +3828,10 @@ arraycontains(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||
Oid collation = PG_GET_COLLATION();
|
||||
bool result;
|
||||
|
||||
result = array_contain_compare(array2, array1, true,
|
||||
result = array_contain_compare(array2, array1, collation, true,
|
||||
&fcinfo->flinfo->fn_extra);
|
||||
|
||||
/* Avoid leaking memory when handed toasted input. */
|
||||
@ -3845,9 +3846,10 @@ arraycontained(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array1 = PG_GETARG_ARRAYTYPE_P(0);
|
||||
ArrayType *array2 = PG_GETARG_ARRAYTYPE_P(1);
|
||||
Oid collation = PG_GET_COLLATION();
|
||||
bool result;
|
||||
|
||||
result = array_contain_compare(array1, array2, true,
|
||||
result = array_contain_compare(array1, array2, collation, true,
|
||||
&fcinfo->flinfo->fn_extra);
|
||||
|
||||
/* Avoid leaking memory when handed toasted input. */
|
||||
|
Reference in New Issue
Block a user