Re: btree_gin and btree_gist for enums

Поиск
Список
Период
Сортировка
От Andrew Dunstan
Тема Re: btree_gin and btree_gist for enums
Дата
Msg-id 03f7d748-0f89-e8e1-094d-f04e1026b93d@dunslane.net
обсуждение исходный текст
Ответ на Re: btree_gin and btree_gist for enums  (Emre Hasegeli <emre@hasegeli.com>)
Ответы Re: btree_gin and btree_gist for enums
Список pgsql-hackers

On 11/04/2016 04:14 PM, Emre Hasegeli wrote:
> The GiST part of it doesn't really work.  The current patch compares
> oids.  We need to change it to compare enumsortorder.  I could make it
> fail easily:
>
>> regression=# create type e as enum ('0', '2', '3');
>> CREATE TYPE
>> regression=# alter type e add value '1' after '0';
>> ALTER TYPE
>> regression=# create table t as select (i % 4)::text::e from generate_series(0, 100000) as i;
>> SELECT 100001
>> regression=# create index on t using gist (e);
>> SEGFAULT


It calls the enum routines which use the sortorder if necessary. It's 
not necessary to use sortorder in the case of evenly numbered enum oids 
as we have carefully arranged for them to be directly comparable, and 
all the initially allocated oids are even, a very nifty efficiency 
measure devised by Tom when we added enum extension.

The real problem here is that enum_cmp_internal assumes that 
fcinfo->flinfo has been set up, and DirectFunctionCallN doesn't, it sets 
it to NULL.

The patch below cures the problem. I'm not sure if there is a better 
way. Thoughts?

cheers

andrew


diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index 47d5355..64ba7a7 100644
--- a/src/backend/utils/adt/enum.c
+++ b/src/backend/utils/adt/enum.c
@@ -261,7 +261,7 @@ enum_send(PG_FUNCTION_ARGS) static int enum_cmp_internal(Oid arg1, Oid arg2, FunctionCallInfo
fcinfo){
 
-   TypeCacheEntry *tcache;
+   TypeCacheEntry *tcache = NULL;
    /* Equal OIDs are equal no matter what */    if (arg1 == arg2)
@@ -277,7 +277,8 @@ enum_cmp_internal(Oid arg1, Oid arg2, 
FunctionCallInfo fcinfo)    }
    /* Locate the typcache entry for the enum type */
-   tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;
+   if (fcinfo->flinfo != NULL)
+       tcache = (TypeCacheEntry *) fcinfo->flinfo->fn_extra;    if (tcache == NULL)    {        HeapTuple   enum_tup;
@@ -296,7 +297,8 @@ enum_cmp_internal(Oid arg1, Oid arg2, 
FunctionCallInfo fcinfo)        ReleaseSysCache(enum_tup);        /* Now locate and remember the typcache entry */
 tcache = lookup_type_cache(typeoid, 0);
 
-       fcinfo->flinfo->fn_extra = (void *) tcache;
+       if (fcinfo->flinfo != NULL)
+           fcinfo->flinfo->fn_extra = (void *) tcache;    }
    /* The remaining comparison logic is in typcache.c */






В списке pgsql-hackers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: Re: Add PGDLLEXPORT to PG_FUNCTION_INFO_V1
Следующее
От: Tom Lane
Дата:
Сообщение: Re: btree_gin and btree_gist for enums