COPY TO FORMAT JSON: use the query's column names as keys

CopyToJsonOneRow() stamped the row datum with the query's descriptor
only when the slot's descriptor was of type RECORD.  A scan that does
not project returns the table's row type, so the keys came from the
table, not the query, losing column aliases and mislabelling rows
from UNION ALL branches with different column orders.

Fix by always using the query's descriptor.  For non-virtual slots,
heap_copy_tuple_as_datum() can just be passed that descriptor, so
there is no extra cost.  This is safe because a scan skips projection
only when tlist_matches_tupdesc() holds, so the layouts match.

Bug introduced in 7dadd38cda9.

Reported-by: Shihao Zhong <[email protected]>
Reviewed-by: Shihao Zhong <[email protected]>
Reviewed-by: João Marcelo Detomini <[email protected]>
Discussion: 
https://postgr.es/m/cagrkxqqhjxgufhpz86+dxgaqzt37hikduuarytfbn2_3mry...@mail.gmail.com
Backpatch-through: 19

Branch
------
REL_19_STABLE

Details
-------
https://git.postgresql.org/pg/commitdiff/05b522024838e19f7b9f0fe54d72b29bc588b230

Modified Files
--------------
src/backend/commands/copyto.c      | 40 ++++++++++++++++++++++++++------------
src/test/regress/expected/copy.out | 13 +++++++++++++
src/test/regress/sql/copy.sql      | 10 ++++++++++
3 files changed, 51 insertions(+), 12 deletions(-)

Reply via email to