Call eq_func correctly in time_bucket_gapfill

The equality comparison function is called using
`DirectFunctionCall2Coll`, which do not set the `fcinfo->flinfo` when
calling the PostgreSQL function.  Since `array_eq` uses
`fcinfo->flinfo->fn_extra` for caching, and `flinfo` is null, this
causes a crash.

Fix this issue by using `FunctionCall2Coll` instead, which sets
`fcinfo->flinfo` before calling the PostgreSQL function.

Fixes #5981
This commit is contained in:
Mats Kindahl 2023-08-21 17:35:19 +02:00 committed by Mats Kindahl
parent 4256009e4c
commit 3db6922960
4 changed files with 46 additions and 4 deletions

2
.unreleased/bugfix_5991 Normal file
View File

@ -0,0 +1,2 @@
Fixes: #5991 Call eq_func correctly in time_bucket_gapfill
Thanks: @willsbit for reporting a crash in time_bucket_gapfill

View File

@ -1040,10 +1040,12 @@ gapfill_state_is_new_group(GapFillState *state, TupleTableSlot *slot)
continue;
if (isnull != column.group->isnull)
return true;
if (!DatumGetBool(DirectFunctionCall2Coll(column.group->eq_func.fn_addr,
column.group->collation,
value,
column.group->value)))
/* We need to use FunctionCall2Coll here since equality comparison
* functions can try to access flinfo (see arrayfuncs.c). */
if (!DatumGetBool(FunctionCall2Coll(&column.group->eq_func,
column.group->collation,
value,
column.group->value)))
return true;
}
}

View File

@ -3324,3 +3324,34 @@ SELECT time_bucket_gapfill('2 month'::interval, ts, 'Europe/Berlin', '2000-01-01
RESET timezone;
DROP INDEX gapfill_plan_test_indx;
-- Test gapfill with arrays (#5981)
SELECT time_bucket_gapfill(5, ts, 1, 100) as ts, int_arr, locf(last(value, ts))
FROM (
SELECT ARRAY[1,2,3,4]::int[] as int_arr, x as ts, x+500000 as value
FROM generate_series(1, 10, 100) as x
) t
GROUP BY 1, 2
ts | int_arr | locf
----+-----------+--------
0 | {1,2,3,4} | 500001
5 | {1,2,3,4} | 500001
10 | {1,2,3,4} | 500001
15 | {1,2,3,4} | 500001
20 | {1,2,3,4} | 500001
25 | {1,2,3,4} | 500001
30 | {1,2,3,4} | 500001
35 | {1,2,3,4} | 500001
40 | {1,2,3,4} | 500001
45 | {1,2,3,4} | 500001
50 | {1,2,3,4} | 500001
55 | {1,2,3,4} | 500001
60 | {1,2,3,4} | 500001
65 | {1,2,3,4} | 500001
70 | {1,2,3,4} | 500001
75 | {1,2,3,4} | 500001
80 | {1,2,3,4} | 500001
85 | {1,2,3,4} | 500001
90 | {1,2,3,4} | 500001
95 | {1,2,3,4} | 500001
(20 rows)

View File

@ -1506,3 +1506,10 @@ RESET timezone;
DROP INDEX gapfill_plan_test_indx;
-- Test gapfill with arrays (#5981)
SELECT time_bucket_gapfill(5, ts, 1, 100) as ts, int_arr, locf(last(value, ts))
FROM (
SELECT ARRAY[1,2,3,4]::int[] as int_arr, x as ts, x+500000 as value
FROM generate_series(1, 10, 100) as x
) t
GROUP BY 1, 2