Skip to content

copy_dumps corrupts array elements through COPY#67

Merged
roed314 merged 1 commit into
roed314:masterfrom
roed-math:fix/array-copy
Jul 20, 2026
Merged

copy_dumps corrupts array elements through COPY#67
roed314 merged 1 commit into
roed314:masterfrom
roed-math:fix/array-copy

Conversation

@roed-math

Copy link
Copy Markdown

Array elements were quoted only when they contained braces, so ["a,b"] became {a,b} (two elements), [""] became {} (the empty array), [" a"] lost its space, and ["NULL"] became an SQL NULL — silent data corruption through copy_to/copy_from/reload and LMFDB's uploader. A None element was written as the field-level marker \N, which COPY unescapes to the letter N.

Elements are now quoted whenever PostgreSQL's array parser needs it (empty, NULL case-insensitively, or containing braces, commas, quotes, backslashes or whitespace), with array-level escaping applied inside COPY's field-level escaping in the order COPY undoes them, and None becomes the array literal NULL. Verified beyond the unit tests by driving 27 nasty values — embedded tabs, newlines, quotes, backslashes, unicode, [None, 1], 2-D arrays — through an actual COPY FROM and back: all round-trip exactly. Output changes only for values that could not round-trip before.


Split out of #60 (one PR per issue). This branch carries only this issue's fix and its tests; the rest of the known-bug inventory stays xfailed, so the full suite is green here and the strict markers guarantee no cross-issue leakage.

Array elements were quoted only when they contained braces, so ["a,b"] became {a,b} (two elements), [""] became {} (the empty array), [" a"] lost its space, and ["NULL"] became an SQL NULL — silent data corruption through copy_to/copy_from/reload and LMFDB's uploader. A None element was written as the field-level marker \N, which COPY unescapes to the letter N.

Elements are now quoted whenever PostgreSQL's array parser needs it (empty, NULL case-insensitively, or containing braces, commas, quotes, backslashes or whitespace), with array-level escaping applied inside COPY's field-level escaping in the order COPY undoes them, and None becomes the array literal NULL. Verified beyond the unit tests by driving 27 nasty values — embedded tabs, newlines, quotes, backslashes, unicode, [None, 1], 2-D arrays — through an actual COPY FROM and back: all round-trip exactly. Output changes only for values that could not round-trip before.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@roed314
roed314 merged commit 2d35704 into roed314:master Jul 20, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants