Commit eba2ce17 authored by Tom Lane's avatar Tom Lane

Fix another crash in json{b}_populate_recordset and json{b}_to_recordset.

populate_recordset_worker() failed to consider the possibility that the
supplied JSON data contains no rows, so that update_cached_tupdesc never
got called.  This led to a null-pointer dereference since commit 9a5e8ed28;
before that it led to a bogus "set-valued function called in context that
cannot accept a set" error.  Fix by forcing the update to happen.

Per bug #15514.  Back-patch to v11 as 9a5e8ed28 was.  (If we were excited
about the bogus error, we could perhaps go back further, but it'd take more
work to figure out how to fix it in older branches.  Given the lack of
field complaints about that aspect, I'm not excited.)

Discussion: https://postgr.es/m/15514-59d5b4c4065b178b@postgresql.org
parent fe375d33
......@@ -3658,6 +3658,12 @@ populate_recordset_worker(FunctionCallInfo fcinfo, const char *funcname,
if (PG_ARGISNULL(json_arg_num))
PG_RETURN_NULL();
/*
* Forcibly update the cached tupdesc, to ensure we have the right tupdesc
* to return even if the JSON contains no rows.
*/
update_cached_tupdesc(&cache->c.io.composite, cache->fn_mcxt);
state = palloc0(sizeof(PopulateRecordsetState));
/* make tuplestore in a sufficiently long-lived memory context */
......
......@@ -1851,6 +1851,19 @@ FROM (VALUES (1),(2)) v(i);
2 | (2,43)
(4 rows)
-- empty array is a corner case
SELECT json_populate_recordset(null::record, '[]');
ERROR: record type has not been registered
SELECT json_populate_recordset(row(1,2), '[]');
json_populate_recordset
-------------------------
(0 rows)
SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q;
a | b | c
---+---+---
(0 rows)
-- composite domain
SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]');
json_populate_recordset
......
......@@ -2533,6 +2533,19 @@ FROM (VALUES (1),(2)) v(i);
2 | (2,43)
(4 rows)
-- empty array is a corner case
SELECT jsonb_populate_recordset(null::record, '[]');
ERROR: record type has not been registered
SELECT jsonb_populate_recordset(row(1,2), '[]');
jsonb_populate_recordset
--------------------------
(0 rows)
SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q;
a | b | c
---+---+---
(0 rows)
-- composite domain
SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]');
jsonb_populate_recordset
......
......@@ -550,6 +550,11 @@ SELECT json_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]');
SELECT i, json_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]')
FROM (VALUES (1),(2)) v(i);
-- empty array is a corner case
SELECT json_populate_recordset(null::record, '[]');
SELECT json_populate_recordset(row(1,2), '[]');
SELECT * FROM json_populate_recordset(NULL::jpop,'[]') q;
-- composite domain
SELECT json_populate_recordset(null::j_ordered_pair, '[{"x": 0, "y": 1}]');
SELECT json_populate_recordset(row(1,2)::j_ordered_pair, '[{"x": 0}, {"y": 3}]');
......
......@@ -666,6 +666,11 @@ SELECT jsonb_populate_recordset(row(1,2), '[{"f1": 0, "f2": 1}]');
SELECT i, jsonb_populate_recordset(row(i,50), '[{"f1":"42"},{"f2":"43"}]')
FROM (VALUES (1),(2)) v(i);
-- empty array is a corner case
SELECT jsonb_populate_recordset(null::record, '[]');
SELECT jsonb_populate_recordset(row(1,2), '[]');
SELECT * FROM jsonb_populate_recordset(NULL::jbpop,'[]') q;
-- composite domain
SELECT jsonb_populate_recordset(null::jb_ordered_pair, '[{"x": 0, "y": 1}]');
SELECT jsonb_populate_recordset(row(1,2)::jb_ordered_pair, '[{"x": 0}, {"y": 3}]');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment