Skip to content

Add failing test: batch scan corrupted in cache_statement mode#2524

Merged
jackc merged 1 commit intojackc:masterfrom
dbussink:pipeline-result-format-reuse
Mar 22, 2026
Merged

Add failing test: batch scan corrupted in cache_statement mode#2524
jackc merged 1 commit intojackc:masterfrom
dbussink:pipeline-result-format-reuse

Conversation

@dbussink
Copy link
Copy Markdown
Contributor

sendBatchExtendedWithDescription passes eqb.ResultFormats to SendQueryStatement by reference. The next Build call reuses the backing array, corrupting the stored format codes for earlier queries. The server sends binary data (Bind was encoded correctly), but the local scan plan uses the corrupted text format code.

Exposed in v5.9.0 by c3a1750 (pgx batch uses SendQueryStatement), part of Skip Describe Portal for cached prepared statements reducing network round trips. The previous SendQueryPrepared path sent Describe Portal, so the server's RowDescription provided correct format codes regardless of the stored slice contents.

@jackc This happened when we updated to 5.9.0. As the test describes, I think it classifies as a bug? I haven't dug into how to fix it yet though, maybe that's immediately obvious to you?

Test fails reproducing the problem we have:

PGX_TEST_DATABASE="host=localhost port=5432 user=postgres sslmode=disable" go test -run TestSendBatchPreservesResultFormats
--- FAIL: TestSendBatchPreservesResultFormats (0.80s)
    --- FAIL: TestSendBatchPreservesResultFormats/cache_statement (0.51s)
        batch_test.go:1290:
                Error Trace:    /Users/dirkjan/code/jackc/pgx/batch_test.go:1290
                                                        /Users/dirkjan/code/jackc/pgx/pgxtest/pgxtest.go:78
                                                        /Users/dirkjan/code/jackc/pgx/pgxtest/pgxtest.go:99
                Error:          Received unexpected error:
                                can't scan into dest[0] (col: int4): strconv.ParseInt: parsing "\x00\x00\x00\x01": invalid syntax
                Test:           TestSendBatchPreservesResultFormats/cache_statement
FAIL
exit status 1
FAIL    github.com/jackc/pgx/v5 1.120s

It shows that it tries to parse the binary wire encoding for 1 as text since the second query in the pipeline uses text.

sendBatchExtendedWithDescription passes eqb.ResultFormats to
SendQueryStatement by reference. The next Build call reuses the backing
array (reset sets len=0, append overwrites), corrupting the stored format
codes for earlier queries. The server sends binary data (Bind was encoded
correctly), but the local scan plan uses the corrupted text format code.

Introduced in v5.9.0 by c3a1750 ("pgx batch uses SendQueryStatement"),
part of "Skip Describe Portal for cached prepared statements reducing
network round trips". The previous SendQueryPrepared path sent Describe
Portal, so the server's RowDescription provided correct format codes
regardless of the stored slice contents.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
@jackc
Copy link
Copy Markdown
Owner

jackc commented Mar 22, 2026

Good catch. Should have a fix in a few minutes.

@jackc jackc merged commit f7b90c2 into jackc:master Mar 22, 2026
0 of 14 checks passed
jackc added a commit that referenced this pull request Mar 22, 2026
Copy ResultFormats slice before passing to SendQueryStatement, which
stores it for later use. The extended query builder reuses the backing
array on the next loop iteration, corrupting format codes stored for
earlier queries in the batch.

Fixes the bug exposed by the test in #2524.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@jackc
Copy link
Copy Markdown
Owner

jackc commented Mar 22, 2026

Thanks for the great bug report. It was easy to fix with the failing test. Fix released in v5.9.1.

@dbussink
Copy link
Copy Markdown
Contributor Author

@jackc Thanks for the quick fix!

@dbussink dbussink deleted the pipeline-result-format-reuse branch March 22, 2026 14:51
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