BeginBinaryExport, BeginBinaryImport and BeginRawBinaryCopy (and BeginTextExport and BeginTextImport, which use the raw stream) throw InvalidOperationException when the server completes the command right away, e.g. for a COPY to or from a file on the server. They left the ReadyForQuery that follows the CommandComplete unread, so the next command on the connection read it as its own response and failed with "Received backend message ReadyForQuery while expecting ParseCompleteMessage", which broke the connection. Init now reads that ReadyForQuery before it throws.
How a real server gets there
A caller passes COPY t TO '<file>', COPY t FROM '<file>' or a PROGRAM variant to one of these APIs; that needs superuser or one of the roles pg_read_server_files, pg_write_server_files and pg_execute_server_program. Npgsql only checks the COPY prefix, so the server runs the command, sends no copy response, and ends it like any other statement with CommandComplete and ReadyForQuery. This is what the user in #1673 did (BeginTextImport with COPY … FROM 'C:\temp\test.csv'), which is why the exception exists.
On PostgreSQL 18.6, all six calls (binary export and import, raw export and import, text export and import) threw the intended exception. Then SELECT 42 failed as above and the connection was broken, also after Close and a reopen from the pool, which handed out the same physical connection. The imports did import. With this PR both following commands returned their values. The released 8.0.9, 9.0.5 and 10.0.3 behave like main.
Tests
CopyTests.Copy_api_with_command_that_completes_without_copying (mock, for the three classes): on main all three cases fail with the error above; with the fix they pass.
For the reviewer
- A core change in the COPY code (one more read in each of the three
Init methods), with no API change.
- It isn't meant for the hotfix branch.
Dependencies and merge order
It depends on no other PR.
Fixes #6694