Re: BUG #17158: Distinct ROW fails with Postgres 14
От | Tom Lane |
---|---|
Тема | Re: BUG #17158: Distinct ROW fails with Postgres 14 |
Дата | |
Msg-id | 4092959.1631302070@sss.pgh.pa.us обсуждение исходный текст |
Ответ на | Re: BUG #17158: Distinct ROW fails with Postgres 14 (Peter Eisentraut <peter.eisentraut@enterprisedb.com>) |
Ответы |
Re: BUG #17158: Distinct ROW fails with Postgres 14
|
Список | pgsql-bugs |
Peter Eisentraut <peter.eisentraut@enterprisedb.com> writes: > On 02.09.21 10:15, Peter Eisentraut wrote: >> On 31.08.21 22:43, Tom Lane wrote: >>> I find variant 1 a bit cleaner, and safer. I'd rather default to >>> assuming that RECORD doesn't hash, when we don't have enough info >>> to be sure. >> Ok, here is a more polished patch for that. > committed I apologize for not having found the time to review this before it went in ... but what you did in hash_array is pretty awful: /* * The type cache doesn't believe that record is hashable (see * cache_record_field_properties()), but since we're here, we're * committed to hashing, so we can assume it does. Worst case, if any * components of the record don't support hashing, we will fail at * execution. */ if (element_type == RECORDOID) { MemoryContext oldcontext; TypeCacheEntry *record_typentry; oldcontext = MemoryContextSwitchTo(CacheMemoryContext); /* * Make fake type cache entry structure. Note that we can't just * modify typentry, since that points directly into the type cache. */ record_typentry = palloc(sizeof(*record_typentry)); /* fill in what we need below */ record_typentry->typlen = typentry->typlen; record_typentry->typbyval = typentry->typbyval; record_typentry->typalign = typentry->typalign; fmgr_info(F_HASH_RECORD, &record_typentry->hash_proc_finfo); MemoryContextSwitchTo(oldcontext); typentry = record_typentry; } fcinfo->flinfo->fn_extra = (void *) typentry; } The reason skink has been falling over since this went in is that this kluge didn't bother to fill record_typentry->type_id, which results in the next call seeing an undefined value in if (typentry == NULL || typentry->type_id != element_type) which most likely will cause it to allocate another dummy typcache entry; lather, rinse, repeat for each call. But even with that fixed, I do not think this is even a little bit acceptable, because it will permanently leak a TypeCacheEntry plus subsidiary FmgrInfo data for each query that uses hash_array. Perhaps it'd work to put the phony entry into fcinfo->flinfo->fn_mcxt instead of CacheMemoryContext. BTW, skink's failure can be reproduced pretty quickly by running the attached under valgrind. regards, tom lane create temp table graph0( f int, t int, label text ); insert into graph0 values (1, 2, 'arc 1 -> 2'), (1, 3, 'arc 1 -> 3'), (2, 3, 'arc 2 -> 3'), (1, 4, 'arc 1 -> 4'), (4, 5, 'arc 4 -> 5'); with recursive search_graph(f, t, label) as ( select * from graph0 g union distinct select g.* from graph0 g, search_graph sg where g.f = sg.t ) search depth first by f, t set seq select * from search_graph order by seq;
В списке pgsql-bugs по дате отправления: