| From: | shihao zhong <zhong950419(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org> |
| Cc: | Andrew Dunstan <amdunstan(at)gmail(dot)com>, Joe Conway <mail(at)joeconway(dot)com>, jian he <jian(dot)universality(at)gmail(dot)com> |
| Subject: | [PG19] COPY (query) TO ... (FORMAT json) uses the table's column names |
| Date: | 2026-10-05 19:05:31 |
| Message-ID: | CAGRkXqQHjxgufHPz86+dxGaQZt37hikduUArYtfbn2_3mryZAw@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
I used Opus to analyze the new features in PG 19, and this is one of
the things it found. COPY (query) TO with FORMAT json can name the
JSON keys after the scanned table's columns, not the query's.
create temp table u1 (a int, b int);
create temp table u2 (b int, a int);
insert into u1 values (10, 1);
insert into u2 values (20, 2);
copy (select * from u1 union all select * from u2)
to stdout (format json);
{"a":10,"b":1}
{"b":20,"a":2}
The query's columns are (a, b), so the second row should be
{"a":20,"b":2}. row_to_json() over the same query gives that. Column
aliases are lost the same way, when the query returns all columns of
a table in order.
copy (select a as x, b as y from u1) to stdout (format json);
{"a":10,"b":1}
I expected {"x":10,"y":1}. The attached copy-json-query-columns.sql
runs both cases.
I think the reason is CopyToJsonOneRow() rebuilds the tuple with
the query's descriptor only when the slot's tdtypeid is RECORDOID.
Then the scan node that does not project returns a slot with the table's
row type, so the datum goes to composite_to_json().
0001 always forms the tuple with the query's descriptor on the query
path. That is one heap_form_tuple() per row in place of the tuple
copy the old path made. I have not measured it. Another fix is to
pass the descriptor to composite_to_json() and skip the extra tuple,
but that changes json.c and looks like too much for 19.
COPY TO json is new in 19, so I think this should be an open item.
Thanks,
Shihao
| Attachment | Content-Type | Size |
|---|---|---|
| v1-0002-Add-tests-for-JSON-keys-of-COPY-query-TO.patch | application/octet-stream | 2.3 KB |
| v1-0001-Fix-JSON-keys-of-COPY-query-TO-with-FORMAT-json.patch | application/octet-stream | 1.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Joao Detomini | 2026-10-05 19:21:10 | Re: Limiting WAL retained for archiving, like max_slot_wal_keep_size |
| Previous Message | Greg Burd | 2026-10-05 19:02:01 | Re: Per-thread leak in ECPG's memory.c |