Hello hackers, I met SIGSEGV when using `array_position()` with record type arguments, so I've written a patch which corrects this problem. It seems that `array_position...()` sets wrong memory context for the cached function (in this case `record_eq()`) which is used to find a matching element.
The problem is reproducable with the following query. SELECT array_position(ids, (1, 1)) FROM (VALUES (ARRAY[(0, 0)]), (ARRAY[(1, 1)])) AS _(ids);
From 8868ae0050ec382bc1bae2b993742eb2a40bbb14 Mon Sep 17 00:00:00 2001 From: Junseok Yang <jsy...@bitnine.net> Date: Thu, 8 Dec 2016 18:25:21 -0800 Subject: [PATCH] Fix memory context bugs in `array_position...()` When `array_position()` is called with record type arguments, it uses `record_eq()` to find a matching element. Before calling `record_eq()`, it stores `FmgrInfo` of `record_eq()` to its `FmgrInfo` as extra data in the context of `ecxt_per_query_memory`. However, it sets the context of extra data for `FmgrInfo` of `record_eq()` to `CurrentMemoryContext` which is `ecxt_per_tuple_memory`. And `record_eq()` also stores extra data in the context set by `array_position()`. In this scenario, if `array_position()` is called more than twice over tuples in a query, the process for this session will be terminated with SIGSEGV because the extra data for `record_eq()` should be already freed after the first tuple was processed. `array_positions()` has the same issue. --- src/backend/utils/adt/array_userfuncs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c index 8d6fa41..9eb678a 100644 --- a/src/backend/utils/adt/array_userfuncs.c +++ b/src/backend/utils/adt/array_userfuncs.c @@ -795,7 +795,8 @@ array_position_common(FunctionCallInfo fcinfo) format_type_be(element_type)))); my_extra->element_type = element_type; - fmgr_info(typentry->eq_opr_finfo.fn_oid, &my_extra->proc); + fmgr_info_cxt(typentry->eq_opr_finfo.fn_oid, &my_extra->proc, + fcinfo->flinfo->fn_mcxt); } /* Examine each array element until we find a match. */ @@ -933,7 +934,8 @@ array_positions(PG_FUNCTION_ARGS) format_type_be(element_type)))); my_extra->element_type = element_type; - fmgr_info(typentry->eq_opr_finfo.fn_oid, &my_extra->proc); + fmgr_info_cxt(typentry->eq_opr_finfo.fn_oid, &my_extra->proc, + fcinfo->flinfo->fn_mcxt); } /* -- 2.7.4
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers