Problem with tupdesc in jsonb_to_recordset
Dmitry Dolgov <9erthalion6@gmail.com>
From: Dmitry Dolgov <9erthalion6@gmail.com>
To: PostgreSQL-development <pgsql-hackers@postgresql.org>, PostgreSQL mailing lists <pgsql-bugs@postgresql.org>
Date: 2018-07-10T20:39:28Z
Lists: pgsql-bugs, pgsql-hackers
Attachments
- populate_recordset.patch (text/x-patch) patch
Hi,
I've found out that currently in some situations jsonb_to_recordset can lead to
a crash. Minimal example that I've managed to create looks like this:
CREATE OR REPLACE FUNCTION test(data JSONB)
RETURNS INTEGER AS $$
DECLARE
test_var int;
BEGIN
WITH jsonb_values AS (
SELECT
(SELECT SUM(value)
FROM jsonb_to_recordset(element #> '{values}')
AS q(value INTEGER)) AS value_sum
FROM jsonb_array_elements(data) AS element
) SELECT SUM(value_sum) FROM jsonb_values INTO test_var;
RETURN test_var;
END;
$$ LANGUAGE plpgsql;
And then:
=# SELECT test('[
{
"values": [
{
"value": 1
},
{
"value": 3
}
]
},
{
"values": [
{
"value": 1
},
{
"value": 3
}
]
}
]' :: JSONB);
server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
After brief investigation it looks like an issue with tupdesc from the function
cache:
if (!cache)
{
fcinfo->flinfo->fn_extra = cache =
MemoryContextAllocZero(fcinfo->flinfo->fn_mcxt, sizeof(*cache));
//...
rsi->setDesc = cache->c.io.composite.tupdesc;
Then after the first call of populate_recordset_worker rsi->setDesc is being
reset since we never increased tdrefcount and the next call will use wrong
cache data. Apparently, it can be fixed by incrementing a tdrefcount (see the
attached patch).
Commits
-
Fix crash in json{b}_populate_recordset() and json{b}_to_recordset().
- 9a5e8ed283e5 11.0 landed
- 4984784f836a 12.0 landed
-
Support domains over composite types.
- 37a795a60b4f 11.0 cited