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 ------ master Details ------- https://git.postgresql.org/pg/commitdiff/c652cd3f94d57e69965f065c4ed45708a2b2a757 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(-)
