Re: Emitting JSON to file using COPY TO

From: Andrew Dunstan <andrew(at)dunslane(dot)net>
To: Joe Conway <mail(at)joeconway(dot)com>, jian he <jian(dot)universality(at)gmail(dot)com>, Daniel Verite <daniel(at)manitou-mail(dot)org>
Cc: Masahiko Sawada <sawada(dot)mshk(at)gmail(dot)com>, Junwang Zhao <zhjwpku(at)gmail(dot)com>, Florents Tselai <florents(dot)tselai(at)gmail(dot)com>, "Andrey M(dot) Borodin" <x4mmm(at)yandex-team(dot)ru>, Dean Rasheed <dean(dot)a(dot)rasheed(at)gmail(dot)com>, Davin Shearer <davin(at)apache(dot)org>, PostgreSQL development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: Emitting JSON to file using COPY TO
Date: 2026-03-20 12:41:55
Message-ID: 2732ec01-112c-40ae-8b17-a6df5f30b266@dunslane.net
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-general pgsql-hackers


On 2026-03-19 Th 12:06 PM, Joe Conway wrote:
> On 3/19/26 11:02, Andrew Dunstan wrote:
>>
>> On 2026-03-18 We 9:58 PM, jian he wrote:
>>> On Wed, Mar 18, 2026 at 10:37 PM Daniel Verite
>>> <daniel(at)manitou-mail(dot)org> wrote:
>>>> Currently there's no difference in output between the null
>>>> json value and the SQL null.
>>>>
>>>> postgres=# create table tbl  (j jsonb);
>>>> postgres=# insert into tbl values('null');
>>>> postgres=# insert into tbl values(null);
>>>> postgres=# copy tbl to stdout with (format json);
>>>> {"j":null}
>>>> {"j":null}
>>>>
>>>> Does it have to be that way or are there valid distinct outputs
>>>> that  we could use to avoid this ambiguity?
>>>>
>>> This is an existing (quite old) behavior of
>>> composite_to_json->datum_to_json_internal, IMHO.
>>>
>>> ```
>>>      if (is_null)
>>>      {
>>>          appendBinaryStringInfo(result, "null", strlen("null"));
>>>          return;
>>>      }
>>> ```
>>> produce the same results as
>>> ```
>>> case JSONTYPE_JSON:
>>>      /* JSON and JSONB output will already be escaped */
>>>      outputstr = OidOutputFunctionCall(outfuncoid, val);
>>>      appendStringInfoString(result, outputstr);
>>>      pfree(outputstr);
>>>      break;
>>> ```
>>>
>>> Therefore I intended to document it as below:
>>>
>>>    <refsect2 id="sql-copy-json-format" xreflabel="JSON Format">
>>>     <title>JSON Format</title>
>>>      <para>
>>>        When the <literal>json</literal> format is used, data is
>>> exported with one JSON object per line,
>>>        where each line corresponds to a single record.
>>>        The <literal>json</literal> format has no standard way to
>>> distinguish between an SQL <literal>NULL</literal> and a JSON
>>> <literal>null</literal> literal.
>>>        In the examples that follow, the following table containing JSON
>>> data will be used:
>>> <programlisting>
>>> CREATE TABLE my_test (a jsonb, b int);
>>> INSERT INTO my_test VALUES ('null', 1), (NULL, 1);
>>> </programlisting>
>>>
>>>      When exporting this table using the <literal>json</literal>
>>> format:
>>> <programlisting>
>>> COPY my_test TO STDOUT (FORMAT JSON);
>>> </programlisting>
>>>      In the resulting output, both the SQL <literal>NULL</literal> and
>>> the JSON <literal>null</literal> are rendered identically:
>>> <screen>
>>> {"a":null,"b":1}
>>> {"a":null,"b":1}
>>> </screen>
>>>     </para>
>>>    </refsect2>
>>>
>>>
>>>
>>> what do you think?
>>>
>>>
>>>
>>
>> I can live with that, if others can.
>
> +1
> WFM
>

pushed with that addition.

cheers

andrew

--
Andrew Dunstan
EDB: https://www.enterprisedb.com

In response to

Responses

Browse pgsql-general by date

  From Date Subject
Next Message Joe Conway 2026-03-20 12:58:45 Re: Emitting JSON to file using COPY TO
Previous Message Joe Conway 2026-03-19 16:06:13 Re: Emitting JSON to file using COPY TO

Browse pgsql-hackers by date

  From Date Subject
Next Message Joe Conway 2026-03-20 12:58:45 Re: Emitting JSON to file using COPY TO
Previous Message Marco Nenciarini 2026-03-20 12:40:42 Re: BUG: Cascading standby fails to reconnect after falling back to archive recovery