Problem with tupdesc in jsonb_to_recordset

Поиск
Список
Период
Сортировка
От Dmitry Dolgov
Тема Problem with tupdesc in jsonb_to_recordset
Дата
Msg-id CA+q6zcWzN9ztCfR47ZwgTr1KLnuO6BAY6FurxXhovP4hxr+yOQ@mail.gmail.com
обсуждение исходный текст
Ответы Re: Problem with tupdesc in jsonb_to_recordset  (Michael Paquier <michael@paquier.xyz>)
Список pgsql-hackers
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).

Вложения

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Alvaro Herrera
Дата:
Сообщение: Re: patch to allow disable of WAL recycling
Следующее
От: Tomas Vondra
Дата:
Сообщение: Re: cost_sort() improvements