On 11/05/2016 03:11 PM, Andrew Dunstan wrote:
>
>
> On 11/05/2016 01:13 PM, Tom Lane wrote:
>> Andrew Dunstan <and...@dunslane.net> writes:
>>> On 11/05/2016 11:46 AM, Tom Lane wrote:
>>>> That may be a good fix for robustness purposes, but it seems pretty
>>>> horrid
>>>> from an efficiency standpoint.  Where is this call, and should we be
>>>> modifying it to provide a flinfo?
>>> I thought of providing an flinfo, but I couldn't see a simple way to do
>>> it that would provide something much longer lived than the function
>>> call, in which case it seemed a bit pointless. That's why I asked for
>>> assistance :-)
>> Hmm.  The problem is that the intermediate layer in btree_gist (and
>> probably btree_gin too, didn't look) does not pass through the
>> FunctionCallInfo data structure that's provided by the GIST AM.
>> That wasn't needed up to now, because none of the supported data types
>> are complex enough that any cached state would be useful, but trying
>> to extend it to enums exposes the shortcoming.
>>
>> We could fix this, but it would be pretty invasive since it would
>> require
>> touching just about every function in btree_gist/gin.  Not entirely sure
>> that it's worth it.  On the other hand, the problem might well come up
>> again in future, perhaps for a datatype where the penalty for lack of
>> a cache is greater --- eg, it would be pretty painful to support
>> record_cmp without caching.  And the changes ought to be relatively
>> mechanical, even if they are extensive.
>
>
>
> Yeah. I think it's probably worth doing. btree_gin is probably a
> better place to start because it's largely macro-ized.



So looking at this we have:

    static Datum
    gin_btree_compare_prefix(FunctionCallInfo fcinfo)
    {
        Datum       a = PG_GETARG_DATUM(0);
        Datum       b = PG_GETARG_DATUM(1);
        QueryInfo  *data = (QueryInfo *) PG_GETARG_POINTER(3);
        int32       res,
                    cmp;

        cmp = DatumGetInt32(DirectFunctionCall2Coll(
                                                    data->typecmp,
                                                    PG_GET_COLLATION(),
                                       (data->strategy ==
    BTLessStrategyNumber ||
                                     data->strategy ==
    BTLessEqualStrategyNumber)
                                                    ? data->datum : a,
                                                    b));

and then the referred to routine in the enum case looks like this:

    Datum
    gin_enum_cmp(PG_FUNCTION_ARGS)
    {
       Oid     a = PG_GETARG_OID(0);
       Oid     b = PG_GETARG_OID(1);
       int     res = 0;

       if (ENUM_IS_LEFTMOST(a))
       {
           res = (ENUM_IS_LEFTMOST(b)) ? 0 : -1;
       }
       else if (ENUM_IS_LEFTMOST(b))
       {
           res = 1;
       }
       else
       {
           res = DatumGetInt32(DirectFunctionCall2(enum_cmp,
                                                   ObjectIdGetDatum(a),
                                                   ObjectIdGetDatum(b)));
       }

       PG_RETURN_INT32(res);
    }


I'm not entirely sure how I should replace those DirectFunctionCall2 calls.

cheers

andrew

-- 
Andrew Dunstan                https://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services




-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to