| From: | Andrew Dunstan <andrew(at)dunslane(dot)net> |
|---|---|
| To: | jian he <jian(dot)universality(at)gmail(dot)com> |
| Cc: | Joe Conway <mail(at)joeconway(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>, Daniel Verite <daniel(at)manitou-mail(dot)org>, 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-09 12:23:09 |
| Message-ID: | 5d279aa8-d9c0-4c52-b5ff-a97fd12d3f34@dunslane.net |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-general pgsql-hackers |
On 2026-03-08 Su 11:48 PM, jian he wrote:
> On Mon, Mar 9, 2026 at 3:44 AM Andrew Dunstan<andrew(at)dunslane(dot)net> wrote:
>> Hmm. But should we be scribbling on slot->tts_tupleDescriptor like that?
>> How about something like this?:
>>
>> - * Full table or query without column list. Ensure the slot uses
>> - * cstate->tupDesc so that the datum is stamped with the right type;
>> - * for queries output type is RECORDOID this must be the blessed
>> - * descriptor so that composite_to_json can look it up via
>> - * lookup_rowtype_tupdesc.
>> + * Full table or query without column list. For queries, the slot's
>> + * TupleDesc may carry RECORDOID, which is not registered in the
>> type
>> + * cache and would cause composite_to_json's lookup_rowtype_tupdesc
>> + * call to fail. Build a HeapTuple stamped with the blessed
>> + * descriptor so the type can be looked up correctly.
>> */
>> if (!cstate->rel && slot->tts_tupleDescriptor->tdtypeid ==
>> RECORDOID)
>> - slot->tts_tupleDescriptor = cstate->queryDesc->tupDesc;
>> + {
>> + HeapTuple tup;
>>
>> - rowdata = ExecFetchSlotHeapTupleDatum(slot);
>> + tup = heap_form_tuple(cstate->tupDesc,
>> + slot->tts_values,
>> + slot->tts_isnull);
>> + rowdata = HeapTupleGetDatum(tup);
>> + }
>> + else
>> + {
>> + rowdata = ExecFetchSlotHeapTupleDatum(slot);
>> + }
>>
> This is better. I've tried to get rid of json_projvalues and json_projnulls.
> Just using heap_form_tuple, but it won't work.
>
> I incorporated the v28-0004 COPY column list into v9-0002.
> With this patch set, we added four fields to the struct CopyToStateData.
>
> + StringInfo json_buf; /* reusable buffer for JSON output,
> + * initialized in BeginCopyTo */
> + TupleDesc tupDesc; /* Descriptor for JSON output; for a column
> + * list this is a projected descriptor */
> + Datum *json_projvalues; /* pre-allocated projection values, or
> + * NULL */
> + bool *json_projnulls; /* pre-allocated projection nulls, or NULL */
>
> Using the script in
> https://www.postgresql.org/message-id/CACJufxFFZqxC3p4WjpTEi4riaJm%3DpADX%2Bpy0yQ0%3DRWTn5cqK3Q%40mail.gmail.com
> I tested it again on macOS and Linux, and there are no regressions for
> COPY TO with the TEXT and CSV formats.
>
OK, I think we're really close now. Here is a tiny fixup patch that
fixes an error message and a comment, and adds a missing test case.
cheers
andrew
--
Andrew Dunstan
EDB:https://www.enterprisedb.com
| Attachment | Content-Type | Size |
|---|---|---|
| copy-json-fixes.patch.nocfbot | text/plain | 3.0 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Greg Sabino Mullane | 2026-03-09 13:06:56 | Re: Unexpected deadlock across two separate rows, using Postgres 17 and Django's select_for_update() |
| Previous Message | Shaheed Haque | 2026-03-09 09:55:08 | Re: Unexpected deadlock across two separate rows, using Postgres 17 and Django's select_for_update() |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Amul Sul | 2026-03-09 12:26:50 | Re: pg_waldump: support decoding of WAL inside tarfile |
| Previous Message | wenhui qiu | 2026-03-09 12:08:54 | Re: enhance wraparound warnings |