From 3db692296028ea3c7407150a76aaa1feed6c5b4e Mon Sep 17 00:00:00 2001 From: Mats Kindahl Date: Mon, 21 Aug 2023 17:35:19 +0200 Subject: [PATCH] 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 --- .unreleased/bugfix_5991 | 2 ++ tsl/src/nodes/gapfill/gapfill_exec.c | 10 +++++---- tsl/test/shared/expected/gapfill.out | 31 ++++++++++++++++++++++++++++ tsl/test/shared/sql/gapfill.sql | 7 +++++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 .unreleased/bugfix_5991 diff --git a/.unreleased/bugfix_5991 b/.unreleased/bugfix_5991 new file mode 100644 index 00000000000..96dc1b67ec3 --- /dev/null +++ b/.unreleased/bugfix_5991 @@ -0,0 +1,2 @@ +Fixes: #5991 Call eq_func correctly in time_bucket_gapfill +Thanks: @willsbit for reporting a crash in time_bucket_gapfill diff --git a/tsl/src/nodes/gapfill/gapfill_exec.c b/tsl/src/nodes/gapfill/gapfill_exec.c index 36dfc0bf656..94ec6cc2f01 100644 --- a/tsl/src/nodes/gapfill/gapfill_exec.c +++ b/tsl/src/nodes/gapfill/gapfill_exec.c @@ -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; } } diff --git a/tsl/test/shared/expected/gapfill.out b/tsl/test/shared/expected/gapfill.out index 43ac7cfe5e1..46ed6d5a3cb 100644 --- a/tsl/test/shared/expected/gapfill.out +++ b/tsl/test/shared/expected/gapfill.out @@ -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) + diff --git a/tsl/test/shared/sql/gapfill.sql b/tsl/test/shared/sql/gapfill.sql index a9b414cfe08..86e848f73ae 100644 --- a/tsl/test/shared/sql/gapfill.sql +++ b/tsl/test/shared/sql/gapfill.sql @@ -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