Skip to content

Conversation

@ZhouXing19
Copy link
Collaborator

@ZhouXing19 ZhouXing19 commented Jan 2, 2026

Fixes #158771

Previously, when using the extended protocol (Parse/Bind/Describe/Execute/Sync) to call a PL/pgSQL procedure containing COMMIT statements, CockroachDB would send extra RowDescription messages after the COMMIT, causing the JDBC driver to throw NoSuchElementException due to unexpected message sequences.

This change fixes the message flow to match JDBC driver expectations when procedures execute COMMIT statements internally. The fix ensures that the proper sequence of PostgreSQL wire protocol messages is sent, preventing the driver from entering an inconsistent state.

For reference, PG's code for describe portal message: https://github.com/postgres/postgres/blob/451c43974f8e199097d97624a4952ad0973cea61/src/backend/tcop/postgres.c#L2731

Release Notes (Bug Fix): Fixed compatibility issue with JDBC driver when calling PL/pgSQL procedures containing COMMIT statements via prepared statements. The driver would previously throw NoSuchElementException due to unexpected PostgreSQL wire protocol message sequences.

@cockroach-teamcity
Copy link
Member

This change is Reviewable

@ZhouXing19 ZhouXing19 marked this pull request as ready for review January 2, 2026 02:37
@ZhouXing19 ZhouXing19 requested review from a team as code owners January 2, 2026 02:37
@ZhouXing19 ZhouXing19 requested review from mw5h and rafiss and removed request for a team and mw5h January 2, 2026 02:37
@ZhouXing19 ZhouXing19 requested a review from a team January 2, 2026 18:14
Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice! I have some nits and a question to consider.

@yuzefovich reviewed 16 files and all commit messages, and made 6 comments.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @rafiss and @ZhouXing19).


pkg/sql/conn_executor_prepare.go line 679 at r1 (raw file):

			res.SetNoDataRowDescription()
		} else {
			skipRowDescription := false

Hm, feels like this part might not be needed - if I comment it out, the existing tests still work ...


pkg/sql/pgwire/testdata/pgtest/pgjdbc line 290 at r1 (raw file):

{"Type":"CommandComplete","CommandTag":"CALL"}
{"Type":"ReadyForQuery","TxStatus":"I"}

nit: should we verify the final state of the table?


pkg/sql/conn_executor.go line 1716 at r1 (raw file):

			resumeStmt statements.Statement[tree.Statement]

			// callRowDescSent tracks whether RowDescription has already been sent for a CALL statement

nit: wrap comments at 80 characters.


pkg/sql/conn_executor.go line 4398 at r1 (raw file):

		ast.StatementReturnType() == tree.Rows {
		// Only write RowDescription message if the procedure has output parameters.
		skipWriteRowDesc := false

nit: let's unify this variable name together with parameter names in the interface methods - how about skipRowDesc everywhere? (Currently we use skipWriteRowDesc in one spot and skipRowDescription in the other.)


pkg/sql/conn_executor.go line 4399 at r1 (raw file):

		// Only write RowDescription message if the procedure has output parameters.
		skipWriteRowDesc := false
		if _, isCallStmt := ast.(*tree.Call); isCallStmt {

nit: should we compare against tree.CallStmtTag for consistency?

Copy link
Collaborator Author

@ZhouXing19 ZhouXing19 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ZhouXing19 made 5 comments and resolved 3 discussions.
Reviewable status: :shipit: complete! 0 of 0 LGTMs obtained (waiting on @rafiss and @yuzefovich).


pkg/sql/conn_executor.go line 1716 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: wrap comments at 80 characters.

Done.


pkg/sql/conn_executor.go line 4398 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: let's unify this variable name together with parameter names in the interface methods - how about skipRowDesc everywhere? (Currently we use skipWriteRowDesc in one spot and skipRowDescription in the other.)

Unified to skipRowDescription.


pkg/sql/conn_executor.go line 4399 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: should we compare against tree.CallStmtTag for consistency?

Done.


pkg/sql/conn_executor_prepare.go line 679 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

Hm, feels like this part might not be needed - if I comment it out, the existing tests still work ...

Good catch -- we don't need to check if callRowDescSent since it only matters when for the actual stmt execution. Here we only need to check if the stmt returns any data or not. Removed.


pkg/sql/pgwire/testdata/pgtest/pgjdbc line 290 at r1 (raw file):

Previously, yuzefovich (Yahor Yuzefovich) wrote…

nit: should we verify the final state of the table?

Done.

@yuzefovich yuzefovich added backport-25.4.x Flags PRs that need to be backported to 25.4 backport-26.1.x Flags PRs that need to be backported to 26.1 labels Jan 5, 2026
Copy link
Member

@yuzefovich yuzefovich left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:lgtm: Feels like this should be backported, so I added a couple of labels.

@yuzefovich reviewed 7 files and all commit messages, made 2 comments, and resolved 2 discussions.
Reviewable status: :shipit: complete! 1 of 0 LGTMs obtained (waiting on @rafiss and @ZhouXing19).


pkg/sql/conn_executor_prepare.go line 668 at r2 (raw file):

			// Sending a nil formatCodes is equivalent to sending all text format
			// codes.
			res.SetPortalOutput(ctx, cursor.Rows.Types(), nil /* formatCodes */)

nit: let's restore the inlined comment.

@ZhouXing19
Copy link
Collaborator Author

TFTR!
bors r+

craig bot pushed a commit that referenced this pull request Jan 5, 2026
160377: pgwire: fix JDBC compatibility for SP with COMMIT r=ZhouXing19 a=ZhouXing19

Fixes #158771

Previously, when using the extended protocol (Parse/Bind/Describe/Execute/Sync) to call a PL/pgSQL procedure containing COMMIT statements, CockroachDB would send extra RowDescription messages after the COMMIT, causing the JDBC driver to throw NoSuchElementException due to unexpected message sequences.

This change fixes the message flow to match JDBC driver expectations when procedures execute COMMIT statements internally. The fix ensures that the proper sequence of PostgreSQL wire protocol messages is sent, preventing the driver from entering an inconsistent state.

For reference, PG's code for describe portal message: https://github.com/postgres/postgres/blob/451c43974f8e199097d97624a4952ad0973cea61/src/backend/tcop/postgres.c#L2731

Release Notes (Bug Fix): Fixed compatibility issue with JDBC driver when calling PL/pgSQL procedures containing COMMIT statements via prepared statements. The driver would previously throw NoSuchElementException due to unexpected PostgreSQL wire protocol message sequences.

Co-authored-by: ZhouXing19 <[email protected]>
#
# The issue occurs when using the extended protocol (Parse/Bind/Describe/Execute/Sync)
# to call a procedure that commits the transaction internally. The JDBC driver
# expects a specific sequence of messages but CockroachDB sends extra RowDescription
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this comment should be updated to clarify that this was the old behavior. This PR fixes it so the statement in the comment is no longer true.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@yuzefovich
Copy link
Member

bors r-

To update the comment based on Rafi's review

@craig
Copy link
Contributor

craig bot commented Jan 5, 2026

Canceled.

@ZhouXing19 ZhouXing19 force-pushed the nodata-proc branch 2 times, most recently from dc9ff53 to ab2bb0a Compare January 5, 2026 19:00
…ements

Previously, when using the extended protocol
(Parse/Bind/Describe/Execute/Sync) to call a PL/pgSQL procedure
containing COMMIT statements, CockroachDB would send extra
RowDescription messages after the COMMIT, causing the JDBC driver to
throw NoSuchElementException due to unexpected message sequences.

This change fixes the message flow to match JDBC driver expectations
when procedures execute COMMIT statements internally. The fix ensures
that the proper sequence of PostgreSQL wire protocol messages is sent,
preventing the driver from entering an inconsistent state.

Fixes cockroachdb#158771

Release Notes (Bug Fix): Fixed compatibility issue with JDBC driver when
calling PL/pgSQL procedures containing COMMIT statements via prepared
statements. The driver would previously throw NoSuchElementException due
to unexpected PostgreSQL wire protocol message sequences.
@ZhouXing19
Copy link
Collaborator Author

Done updating the comment in the test.
TFTRs!
bors r+

@craig
Copy link
Contributor

craig bot commented Jan 5, 2026

@craig craig bot merged commit 16efef8 into cockroachdb:master Jan 5, 2026
25 checks passed
@blathers-crl
Copy link

blathers-crl bot commented Jan 5, 2026

Based on the specified backports for this PR, I applied new labels to the following linked issue(s). Please adjust the labels as needed to match the branches actually affected by the issue(s), including adding any known older branches.


Issue #158771: branch-release-25.4, branch-release-26.1.


🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

@blathers-crl
Copy link

blathers-crl bot commented Jan 5, 2026

Encountered an error creating backports. Some common things that can go wrong:

  1. The backport branch might have already existed.
  2. There was a merge conflict.
  3. The backport branch contained merge commits.

You might need to create your backport manually using the backport tool.


💡 Consider backporting to the fork repo instead of the main repo. See instructions for more details.

error creating merge commit from f1d26c6 to blathers/backport-release-25.4-160377: POST https://api.github.com/repos/cockroachdb/cockroach/merges: 409 Merge conflict []

you may need to manually resolve merge conflicts with the backport tool.

Backport to branch 25.4.x failed. See errors above.


💡 Consider backporting to the fork repo instead of the main repo. See instructions for more details.

🦉 Hoot! I am a Blathers, a bot for CockroachDB. My owner is dev-inf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport-25.4.x Flags PRs that need to be backported to 25.4 backport-26.1.x Flags PRs that need to be backported to 26.1 backport-failed target-release-26.2.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

java.util.NoSuchElementException in JDBC driver when calling procedure that contains a commit statement

4 participants