Skip to content

fix(protocol): handle SQL PREPARE/EXECUTE over extended protocol - #1600

Open
dipeshbabu wants to merge 5 commits into
pgdogdev:mainfrom
dipeshbabu:fix/extended-sql-prepare
Open

dipeshbabu wants to merge 5 commits into
pgdogdev:mainfrom
dipeshbabu:fix/extended-sql-prepare

Conversation

@dipeshbabu

@dipeshbabu dipeshbabu commented Sep 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #1403.

SQL PREPARE sent through the extended protocol was replaced with a simple query, leaving clients waiting for ParseComplete. Preserve the original message sequence and track the inner statement when Execute completes.

SQL EXECUTE now reparses its rewritten SQL before binding, so cached outer statements use the current LIMIT/OFFSET and generated values. The internal Parse follows any required SQL PREPARE; its ParseComplete is consumed. The original Bind name remains available for decoding results. Client-local SQL preparation plans are not shared through the AST cache.

Keep the client's original unnamed Parse across executions so Postgrex can reuse it after Sync; request rewrites use a separate copy.

Regression coverage includes cross-shard and direct-shard pagination, mixed parameter positions, fresh generated IDs, separate client name registration, unnamed reuse, and error recovery. Added named/unnamed Ruby cases across full/extended/disabled modes and Postgrex protocol coverage. The pagination, generated-ID, and unnamed-statement failures were reproduced before their fixes. The new Ruby and Postgrex cases also passed in isolated local runs.

All 27 validation jobs passed before pushing this update.

@codecov

codecov Bot commented Sep 20, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.61017% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
pgdog/src/backend/prepared_statements.rs 97.10% 2 Missing ⚠️
pgdog/src/frontend/client/mod.rs 85.71% 2 Missing ⚠️
pgdog/src/net/protocol_message.rs 84.61% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@jkaczman
jkaczman self-requested a review September 20, 2026 21:31

@jkaczman jkaczman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Going off memory, I think LIMIT / OFFSET won't work with this. If it's a simple-ish fix to cover that, I think it'd be great to support that here as well. If it's difficult, I suppose we could file another issue, and leave a comment in the code explaining that it's broken. I'm also curious if anything else being re-written for Prepare/Execute is affected by this.

Ref to my previous issue implementing that and where I test that general code:

/// <https://github.com/pgdogdev/pgdog/issues/1383>
/// TODO: will need to support extended-protocol `Bind`s later for the re-write
#[tokio::test]
async fn test_simple_prepared_limit() {

Could you also write a basic test in our Ruby / Elixir suites to ensure there's no other issues? Ruby has suites covering full/extended/disabled prepared_statements, and Postgrex is pretty strict about ensuring protocol conformity through its state machine.

@dipeshbabu dipeshbabu changed the title fix(protocol): preserve extended SQL PREPARE replies fix(protocol): handle SQL PREPARE/EXECUTE over extended protocol Sep 21, 2026
@dipeshbabu

Copy link
Copy Markdown
Contributor Author

Fixed LIMIT/OFFSET and generated-ID rewrites, including repeated executions. The Postgrex test also caught unnamed-statement reuse; that's fixed too. Added Ruby/Postgrex coverage; all 27 validation jobs pass.

@jkaczman jkaczman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for fixing that, here's some more thoughts! There's also a couple other places I see the same kind of issues with.

Comment thread pgdog/src/frontend/router/parser/rewrite/statement/plan.rs Outdated
Comment thread pgdog/src/frontend/router/parser/rewrite/statement/offset.rs Outdated
Comment thread pgdog/src/frontend/client_request.rs Outdated
Comment thread pgdog/src/frontend/router/parser/rewrite/statement/plan.rs

@jkaczman jkaczman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Oh, and, could you please delete the TODO I mentioned in my earlier comment?

@jkaczman
jkaczman requested a review from levkk September 21, 2026 12:38
@dipeshbabu
dipeshbabu requested a review from jkaczman September 21, 2026 14:08

@jkaczman jkaczman left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I've read the changes over, I think it generally looks good other than some minor nits.

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.

PARSE and EXECUTE sent via Parse (extended protocol) isn't handled correctly

2 participants