Skip to content

Commit

Permalink
Call eq_func correctly in time_bucket_gapfill
Browse files Browse the repository at this point in the history
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
  • Loading branch information
mkindahl committed Aug 22, 2023
1 parent 4256009 commit 3db6922
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 4 deletions.
2 changes: 2 additions & 0 deletions .unreleased/bugfix_5991
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixes: #5991 Call eq_func correctly in time_bucket_gapfill
Thanks: @willsbit for reporting a crash in time_bucket_gapfill
10 changes: 6 additions & 4 deletions tsl/src/nodes/gapfill/gapfill_exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
31 changes: 31 additions & 0 deletions tsl/test/shared/expected/gapfill.out
Original file line number Diff line number Diff line change
Expand Up @@ -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)

7 changes: 7 additions & 0 deletions tsl/test/shared/sql/gapfill.sql
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 3db6922

Please sign in to comment.