mirror of
https://github.com/postgres/postgres.git
synced 2025-06-13 07:41:39 +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:
@ -137,12 +137,13 @@ gistindex_keytest(IndexScanDesc scan,
|
||||
*/
|
||||
recheck = true;
|
||||
|
||||
test = FunctionCall5(&key->sk_func,
|
||||
PointerGetDatum(&de),
|
||||
key->sk_argument,
|
||||
Int32GetDatum(key->sk_strategy),
|
||||
ObjectIdGetDatum(key->sk_subtype),
|
||||
PointerGetDatum(&recheck));
|
||||
test = FunctionCall5Coll(&key->sk_func,
|
||||
key->sk_collation,
|
||||
PointerGetDatum(&de),
|
||||
key->sk_argument,
|
||||
Int32GetDatum(key->sk_strategy),
|
||||
ObjectIdGetDatum(key->sk_subtype),
|
||||
PointerGetDatum(&recheck));
|
||||
|
||||
if (!DatumGetBool(test))
|
||||
return false;
|
||||
@ -195,11 +196,12 @@ gistindex_keytest(IndexScanDesc scan,
|
||||
* can't tolerate lossy distance calculations on leaf tuples;
|
||||
* there is no opportunity to re-sort the tuples afterwards.
|
||||
*/
|
||||
dist = FunctionCall4(&key->sk_func,
|
||||
PointerGetDatum(&de),
|
||||
key->sk_argument,
|
||||
Int32GetDatum(key->sk_strategy),
|
||||
ObjectIdGetDatum(key->sk_subtype));
|
||||
dist = FunctionCall4Coll(&key->sk_func,
|
||||
key->sk_collation,
|
||||
PointerGetDatum(&de),
|
||||
key->sk_argument,
|
||||
Int32GetDatum(key->sk_strategy),
|
||||
ObjectIdGetDatum(key->sk_subtype));
|
||||
|
||||
*distance_p = DatumGetFloat8(dist);
|
||||
}
|
||||
|
@ -169,8 +169,7 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||
* comparisons. The original operator is passed to the Consistent
|
||||
* function in the form of its strategy number, which is available
|
||||
* from the sk_strategy field, and its subtype from the sk_subtype
|
||||
* field. Also, preserve sk_func.fn_collation which is the input
|
||||
* collation for the operator.
|
||||
* field.
|
||||
*
|
||||
* Next, if any of keys is a NULL and that key is not marked with
|
||||
* SK_SEARCHNULL/SK_SEARCHNOTNULL then nothing can be found (ie, we
|
||||
@ -181,10 +180,8 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||
for (i = 0; i < scan->numberOfKeys; i++)
|
||||
{
|
||||
ScanKey skey = scan->keyData + i;
|
||||
Oid collation = skey->sk_func.fn_collation;
|
||||
|
||||
skey->sk_func = so->giststate->consistentFn[skey->sk_attno - 1];
|
||||
skey->sk_func.fn_collation = collation;
|
||||
|
||||
if (skey->sk_flags & SK_ISNULL)
|
||||
{
|
||||
@ -205,16 +202,13 @@ gistrescan(PG_FUNCTION_ARGS)
|
||||
* all comparisons. The original operator is passed to the Distance
|
||||
* function in the form of its strategy number, which is available
|
||||
* from the sk_strategy field, and its subtype from the sk_subtype
|
||||
* field. Also, preserve sk_func.fn_collation which is the input
|
||||
* collation for the operator.
|
||||
* field.
|
||||
*/
|
||||
for (i = 0; i < scan->numberOfOrderBys; i++)
|
||||
{
|
||||
ScanKey skey = scan->orderByData + i;
|
||||
Oid collation = skey->sk_func.fn_collation;
|
||||
|
||||
skey->sk_func = so->giststate->distanceFn[skey->sk_attno - 1];
|
||||
skey->sk_func.fn_collation = collation;
|
||||
|
||||
/* Check we actually have a distance function ... */
|
||||
if (!OidIsValid(skey->sk_func.fn_oid))
|
||||
|
Reference in New Issue
Block a user