Skip to content

fix(pgsql-ffto): stop ReadyForQuery finalizing pipelined extended queries (test_ffto_pgsql_pipeline-t) - #6021

Merged
renecannao merged 2 commits into
v3.0from
fix/ffto-pgsql-pipelined-stats-attribution
Aug 10, 2026
Merged

fix(pgsql-ffto): stop ReadyForQuery finalizing pipelined extended queries (test_ffto_pgsql_pipeline-t)#6021
renecannao merged 2 commits into
v3.0from
fix/ffto-pgsql-pipelined-stats-attribution

Conversation

@renecannao

@renecannao renecannao commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

CI-legacy-g9 failed on test_ffto_pgsql_pipeline-t while running #6020. The PR under test changes no runtime code at all, so this is a pre-existing bug in v3.0 that the run merely surfaced — hence a separate PR against v3.0 rather than a fix folded into #6020.

The signature

Scenario 1 pipelines three different statements before a single Sync. The observed digest stats:

digest rows_affected rows_sent
SELECT val FROM ffto_pg_pipe WHERE id = $1 0 (exp 0) 0 (exp 1) got nothing
INSERT INTO ffto_pg_pipe VALUES ($1,$2) 0 (exp 1) 1 (exp 0) got SELECT's result
UPDATE ffto_pg_pipe SET val = $2 WHERE id = $1 1 ✓ 0 ✓ got INSERT's — passes by coincidence

Every result landed one position late. The UPDATE assertion passed only because INSERT and UPDATE happen to share the same expectation (affected=1, sent=0). The totals confirm the shift rather than a lag: expected sent=1 / affected=2, observed sent=1 / affected=1 — the final CommandComplete was dropped entirely once the queue drained to IDLE.

Scenario 2 passed throughout because its ten executions share a single digest, which makes any shift invisible.

Root cause

PgSQLFFTO::process_server_message() finalized the current query unconditionally on 'Z' (ReadyForQuery):

} else if (type == 'Z') {
    finalize_current_query();
}

ReadyForQuery is the right finalizer for simple queries — their CommandComplete deliberately skips finalizing, which is what the m_current_finalize_on_sync check immediately above exists for. But an extended-protocol Execute is finalized by its own CommandComplete, and a pipelined batch has several queued at once. Finalizing one on ReadyForQuery reports it with zeroed counters and pops the pending deque, so every subsequent response in the batch is attributed to the wrong query and the last is lost.

The 'Z' branch is now restricted to finalize-on-sync queries.

Where the stray ReadyForQuery came from

Not hypothetical — the test manufactures one:

  • PgConnection::execute() only writes the Query message; it never reads the reply. Three back-to-back setup queries therefore leave three unread ReadyForQuery messages in the socket.
  • consumeInputUntilReady() stops at the first ReadyForQuery it sees. So the wait after the Parse batch actually consumed DROP TABLE's reply, not the one it was waiting for.
  • From that point the client ran a full exchange behind the server while continuing to pipeline, leaving an old ReadyForQuery in flight exactly when the Bind/Execute batch started.

Each setup query now consumes its own response, so the client is protocol-correct. Both halves are worth keeping: the test no longer desynchronizes, and FFTO no longer corrupts stats_pgsql_query_digest for any client that pipelines this way. The corruption mode matters — silent, plausible-looking wrong numbers, not a visible error.

Verification — please read before assuming this is proven

The failure does not reproduce locally. It is timing-dependent: whether the stray ReadyForQuery reaches the proxy before or after the batch's first Execute. On this machine the test passed 5/5 unfixed and 6/6 fixed; it failed on a 2-core GitHub runner. So the local passes are not evidence the fix works, and I have not produced a red-to-green reproduction. The fix rests on code analysis that matches the CI signature exactly — including the dropped final CommandComplete, which a simple "counters lagged" explanation cannot account for.

What is verified is the absence of regression. The full test_ffto_* set was run with and without the lib/PgSQLFFTO.cpp change, rebuilding and restarting the ProxySQL container each time:

without fix:  PASS 7/402 : FAIL 4/402
with fix:     PASS 7/402 : FAIL 4/402     (identical)

The 4 failures — test_ffto_mysql_mixed_protocol-t, test_ffto_mysql_transactions-t, test_ffto_pgsql-t, test_ffto_pgsql_concurrent-t — fail identically on unmodified v3.0 in this local environment and passed in CI on the same commit range, so they are environment-specific and unrelated. Two of them are MySQL FFTO tests, which a PgSQLFFTO change cannot reach at all.

Making the race deterministic would need fault injection between the proxy's client-side and server-side reads, which is beyond what this fix warrants. CI on this branch is the next real signal.

Related

Surfaced by #6020 (PG protocol/compat test stack SP-1..SP-3), which is test/infra/docs only and does not touch lib/.

Summary by CodeRabbit

  • Bug Fixes
    • Improved extended-protocol query handling to prevent incorrect query completion, queue advancement, and statistics attribution.
    • Ensured setup operations remain synchronized before pipelined scenarios run, improving protocol reliability.
    • Improved handling of overlapping extended and simple queries to ensure both complete correctly and report accurate row counts.

…ries

CI-legacy-g9 failed on test_ffto_pgsql_pipeline-t with a signature that is
not a flake but a stats-attribution shift. Scenario 1 pipelines SELECT,
INSERT and UPDATE before a single Sync and observed:

  SELECT  rows_affected 0 (exp 0)   rows_sent 0 (exp 1)   <- got nothing
  INSERT  rows_affected 0 (exp 1)   rows_sent 1 (exp 0)   <- got SELECT's
  UPDATE  rows_affected 1 (exp 1)   rows_sent 0 (exp 0)   <- got INSERT's

Every result landed one position late, and the totals confirm it: expected
sent=1/affected=2, observed sent=1/affected=1, the last CommandComplete
dropped once the queue drained to IDLE. Scenario 2 passed only because its
ten executions share one digest, which hides any shift.

Root cause is the 'Z' branch of process_server_message(), which finalized
the current query unconditionally. ReadyForQuery is the correct finalizer
for SIMPLE queries -- their CommandComplete deliberately skips finalizing,
see the m_current_finalize_on_sync check -- but an extended-protocol Execute
is finalized by its own CommandComplete. Finalizing one on ReadyForQuery
reports it with zeroed counters and pops the pending deque, so every later
response in the batch is attributed to the wrong query. Restrict the 'Z'
branch to finalize-on-sync queries.

The stray ReadyForQuery comes from the test itself, so fix that too.
PgConnection::execute() only writes the Query message and never reads the
reply, so three back-to-back setup queries leave three unread ReadyForQuery
messages in the socket. consumeInputUntilReady() stops at the FIRST one it
sees, so the wait after the Parse batch actually consumed DROP TABLE's
reply; from there the client ran a full exchange behind the server while
still pipelining, leaving an old ReadyForQuery in flight when the
Bind/Execute batch began. Each setup query now consumes its own response.

Both halves are worth having: the test is now protocol-correct, and FFTO no
longer corrupts stats_pgsql_query_digest for any client that pipelines this
way -- silent, plausible-looking wrong numbers rather than a visible error.

VERIFICATION -- read this before assuming the fix is proven. The failure is
timing-dependent (whether the stray ReadyForQuery reaches the proxy before
or after the batch's first Execute) and does NOT reproduce locally: the test
passed 5/5 unfixed and 6/6 fixed on this machine, and it failed on a 2-core
GitHub runner. The fix therefore rests on code analysis matching the CI
signature exactly, not on a red-to-green reproduction. What IS verified is
the absence of regression: the full test_ffto_* set was run with and without
the lib change and both give an identical 7 pass / 4 fail. Those 4
(test_ffto_mysql_mixed_protocol-t, test_ffto_mysql_transactions-t,
test_ffto_pgsql-t, test_ffto_pgsql_concurrent-t) fail identically on
unmodified v3.0 in this local environment and pass in CI, so they are
environment-specific and unrelated -- two of them are MySQL FFTO tests that
this PgSQLFFTO change cannot reach at all.
@coderabbitai

coderabbitai Bot commented Aug 10, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: d570a85a-2ff9-45a9-8167-7e5644c442fd

📥 Commits

Reviewing files that changed from the base of the PR and between 5972d22 and 72099b6.

📒 Files selected for processing (3)
  • include/PgSQLFFTO.hpp
  • lib/PgSQLFFTO.cpp
  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
📜 Recent review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: run / trigger
🧰 Additional context used
📓 Path-based instructions (3)
include/**/*.hpp

📄 CodeRabbit inference engine (CLAUDE.md)

Header include guards use the #ifndef __CLASS_*_H convention.

Files:

  • include/PgSQLFFTO.hpp
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes such as MySQL_, PgSQL_, and ProxySQL_.
Member variables must use snake_case.
Constants and macros must use UPPER_SNAKE_CASE.
Use C++17, and gate conditional code with #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, and #ifdef PROXYSQLCLICKHOUSE; PROXYSQLGENAI must not guard core code outside plugins/genai/.
Consider performance implications when changing hot paths or other performance-critical code.
Use RAII for resource management and jemalloc for allocation.
Use pthread mutexes for synchronization and std::atomic<> for counters.

Files:

  • include/PgSQLFFTO.hpp
  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
  • lib/PgSQLFFTO.cpp
test/tap/tests/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

test/tap/tests/**/*.cpp: Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp.
To add a new TAP test, add the <testname>-t.cpp file and register it in test/tap/tests/Makefile/groups.json; no special Makefile target is needed because make <testname>-t is generated by pattern rule.

Files:

  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
🧠 Learnings (1)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
🔇 Additional comments (3)
include/PgSQLFFTO.hpp (1)

80-87: LGTM!

lib/PgSQLFFTO.cpp (1)

163-194: LGTM!

Also applies to: 264-313

test/tap/tests/test_ffto_pgsql_pipeline-t.cpp (1)

17-18: LGTM!

Also applies to: 43-49, 155-174, 247-297


📝 Walkthrough

Walkthrough

The change adds response tracking to FFTO query state. Response terminators now mark queries as observed, and ReadyForQuery finalizes only eligible queries. TAP coverage adds an overlapping extended and simple query scenario.

Changes

PostgreSQL protocol flow

Layer / File(s) Summary
Response tracking and finalization
include/PgSQLFFTO.hpp, lib/PgSQLFFTO.cpp
FFTO resets m_response_seen during query lifecycle transitions. Response terminators set the flag. ReadyForQuery finalizes the query only after a response is observed.
Pipeline regression validation
test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
The test consumes setup responses and adds an overlapping extended Execute/Sync and simple Query scenario. It verifies separate digest counts and row metrics.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related issues

Possibly related PRs

  • sysown/proxysql#5524 — Modifies the same FFTO pipeline test and PostgreSQL response-finalization behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant PgSQLFFTO
  participant PostgreSQL
  Client->>PgSQLFFTO: Send Execute/Sync and overlapping Query
  PgSQLFFTO->>PostgreSQL: Forward pipelined requests
  PostgreSQL->>PgSQLFFTO: Return response terminators
  PgSQLFFTO->>PgSQLFFTO: Track response ownership
  PostgreSQL->>PgSQLFFTO: Send ReadyForQuery
  PgSQLFFTO->>Client: Drain responses with separate metrics
Loading

Poem

A rabbit tracks each query’s trail,
Response flags keep queues on rail.
Sync and simple queries run,
Their counts stay split when work is done.
Hop, hop, the pipeline clears!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the PostgreSQL FFTO fix and the prevented ReadyForQuery finalization of pipelined extended queries.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/ffto-pgsql-pipelined-stats-attribution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Comment thread lib/PgSQLFFTO.cpp Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@lib/PgSQLFFTO.cpp`:
- Around line 286-288: Track pending Sync response boundaries so
finalize_current_query cannot activate a query queued after Sync before that
Sync emits ReadyForQuery. Update the query activation/finalization flow around
m_current_finalize_on_sync and finalize_current_query while preserving existing
Execute completion behavior. Add a regression test covering Execute, Sync, and a
simple Query pipelined before replies are consumed.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 431524d9-2eb5-44c1-a898-b361e95af3a3

📥 Commits

Reviewing files that changed from the base of the PR and between 06f3894 and 5972d22.

📒 Files selected for processing (2)
  • lib/PgSQLFFTO.cpp
  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap)
  • GitHub Check: CI-builds / builds (debian12,-dbg)
  • GitHub Check: CI-builds / builds (ubuntu22,-tap-mysqlx)
  • GitHub Check: CI-builds / builds (ubuntu24,-tap-genai-gcov)
  • GitHub Check: run / trigger
  • GitHub Check: build
🧰 Additional context used
📓 Path-based instructions (2)
test/tap/tests/**/*.cpp

📄 CodeRabbit inference engine (CLAUDE.md)

test/tap/tests/**/*.cpp: Test files in test/tap/tests/ must follow the naming pattern test_*.cpp or *-t.cpp.
To add a new TAP test, add the <testname>-t.cpp file and register it in test/tap/tests/Makefile/groups.json; no special Makefile target is needed because make <testname>-t is generated by pattern rule.

Files:

  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
**/*.{cpp,h,hpp}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{cpp,h,hpp}: Class names must use PascalCase with protocol prefixes such as MySQL_, PgSQL_, and ProxySQL_.
Member variables must use snake_case.
Constants and macros must use UPPER_SNAKE_CASE.
Use C++17, and gate conditional code with #ifdef PROXYSQL31, #ifdef PROXYSQL40, #ifdef PROXYSQLFFTO, #ifdef PROXYSQLTSDB, and #ifdef PROXYSQLCLICKHOUSE; PROXYSQLGENAI must not guard core code outside plugins/genai/.
Consider performance implications when changing hot paths or other performance-critical code.
Use RAII for resource management and jemalloc for allocation.
Use pthread mutexes for synchronization and std::atomic<> for counters.

Files:

  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
  • lib/PgSQLFFTO.cpp
🧠 Learnings (1)
📚 Learning: 2026-01-20T09:34:19.124Z
Learnt from: yuji-hatakeyama
Repo: sysown/proxysql PR: 5307
File: test/tap/tests/reg_test_5306-show_warnings_with_comment-t.cpp:39-48
Timestamp: 2026-01-20T09:34:19.124Z
Learning: In ProxySQL's TAP test suite, resource leaks (e.g., not calling mysql_close() on early return paths) are commonly tolerated because test processes are short-lived and OS frees resources on exit. This pattern applies to all C++ test files under test/tap/tests. When reviewing, recognize this as a project-wide test convention and focus on test correctness and isolation rather than insisting on fixing such leaks in these test files.

Applied to files:

  • test/tap/tests/test_ffto_pgsql_pipeline-t.cpp
🔇 Additional comments (1)
test/tap/tests/test_ffto_pgsql_pipeline-t.cpp (1)

152-171: LGTM!

Comment thread lib/PgSQLFFTO.cpp Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5972d221c1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread lib/PgSQLFFTO.cpp Outdated
Comment on lines +286 to +288
if (m_current_finalize_on_sync) {
finalize_current_query();
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Finalize extended EmptyQueryResponse messages

When a valid extended Parse/Bind/Execute contains a nonempty string that parses as empty, such as whitespace or a comment, PostgreSQL returns EmptyQueryResponse (I) followed by ReadyForQuery, rather than CommandComplete. track_query() still records this execution with finalize_on_sync=false, so this guard now ignores its only handled terminator and leaves it current; the next query's CommandComplete is then attributed to the empty query and subsequent digest statistics remain shifted. Handle I as an extended execution completion before suppressing ReadyForQuery finalization.

Useful? React with 👍 / 👎.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 0% with 28 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.47%. Comparing base (b4c7514) to head (72099b6).
⚠️ Report is 76 commits behind head on v3.0.

Files with missing lines Patch % Lines
test/tap/tests/test_ffto_pgsql_pipeline-t.cpp 0.00% 18 Missing ⚠️
lib/PgSQLFFTO.cpp 0.00% 10 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             v3.0    #6021      +/-   ##
==========================================
- Coverage   53.06%   49.47%   -3.59%     
==========================================
  Files         478      478              
  Lines      143736   142825     -911     
  Branches    36348    36353       +5     
==========================================
- Hits        76267    70663    -5604     
- Misses      50559    54091    +3532     
- Partials    16910    18071    +1161     
Flag Coverage Δ
integration-tests 49.24% <0.00%> (-0.03%) ⬇️
unit-tests ?

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…he query kind

Addresses three review findings, all of which show the previous guard used the
wrong discriminator. Gating the 'Z' branch on m_current_finalize_on_sync fixed
the reported pipeline case but left neighbouring orderings broken.

CodeRabbit (Major): Execute + Sync + simple Query pipelined in one client
write. The Execute's CommandComplete finalizes it and activates the queued
simple query; the ReadyForQuery that follows belongs to the *Sync*, i.e. the
exchange that just ended, but the simple query is now current and has
finalize_on_sync=true, so it was finalized with zero counters and its own
CommandComplete discarded. Unlike the original report this ordering is
deterministic, not a race -- it follows purely from what the client sends.

codex (P1): an extended Execute whose text is empty once comments/whitespace
are stripped is answered by EmptyQueryResponse ('I'), never CommandComplete.
With 'Z' suppressed for extended queries it was never finalized at all, so it
stayed current and swallowed the next query's CommandComplete.

gitar-bot: same shape for PortalSuspended ('s') on a row-limited Execute.
Latent today -- Execute's max-rows field is parsed but never acted on
(issue #5900) -- but it stalls the queue the day that is fixed.

The unifying fix: track whether the current query has received its OWN
response terminator (m_response_seen, set by 'C', 'I' and 's') and gate 'Z'
on that instead of on the query kind. This is correct for every ordering. A
simple query that got its CommandComplete finalizes on ReadyForQuery exactly
as before. An extended Execute finalizes on its own terminator and cannot
still be current when ReadyForQuery arrives. A query still awaiting its first
response -- whether because a stale ReadyForQuery is in flight or because it
was activated mid-batch -- is left alone for the response that is genuinely
its own. 'I' and 's' also finalize extended executions directly, so neither
can stall the queue.

Adds Scenario 3 to test_ffto_pgsql_pipeline-t covering the CodeRabbit case
(extended Execute + Sync + simple Query, then assert each digest kept its own
row counts). Plan count 13 -> 19. Because that ordering is deterministic this
is a genuine regression test: on unfixed code the simple query's digest
records rows_sent=0 instead of 1.
@renecannao

Copy link
Copy Markdown
Contributor Author

Correction to the verification claims in the PR description

While acting on the review feedback I discovered the local runs I reported were vacuous, and the description is wrong as written. Correcting it here rather than quietly editing it.

test_ffto_pgsql_pipeline-t connects with pg_lite_client, which on v3.0 supports cleartext auth only (SCRAM/MD5 support is added by #6020, not present here). The default pgsql-authentication_method is 3 (SCRAM), so running this test in isolation aborts in setup with Unsupported authentication method: 10 and skips all remaining assertions — which TAP counts as a PASS. My "5/5 unfixed, 6/6 fixed" runs were that skip-all, not real executions. It only runs for real inside a full group because earlier pgsql tests lower the auth floor and do not restore it, so the test silently depends on group ordering.

Attempting a genuine local run then hit a second problem: ensure-infras.bash fails for docker-pgsql16-single with unknown shorthand flag: 'p' in -pgdb1-1 (a docker exec with an empty container-name variable), so pgsql_users is never populated and no PG test can authenticate on this box at all. Both are local/infra issues, unrelated to this fix, but they invalidate the local evidence I cited.

What still stands: the regression comparison was like-for-like — the full test_ffto_* set gave an identical 7 pass / 4 fail with and without the lib/ change — so the change introduces no regression among the tests that did run. And the root-cause analysis is unaffected, since it rests on the CI failure signature and the code, not on local runs.

What no longer stands: any claim that the fix was exercised locally. It has not been.

The Scenario 3 added in 72099b6 is a deterministic regression test for the CodeRabbit case (it does not depend on the race), so CI is where both it and the original fix get their first real exercise.

@gitar-bot

gitar-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 1 resolved / 1 findings

Restricts ReadyForQuery finalization in PgSQLFFTO to sync-bound queries, resolving the incorrect query completion finding and preventing statistics attribution errors in pipelined extended queries.

✅ 1 resolved
Edge Case: Extended query without CommandComplete no longer finalized on 'Z'

📄 lib/PgSQLFFTO.cpp:264-278
With 'Z' now finalizing only finalize-on-sync (simple) queries, an extended-protocol Execute that terminates without a CommandComplete — e.g. a row-limited Execute answered by PortalSuspended ('s') — is never finalized: neither the 'C' branch (never arrives) nor the 'Z' branch (skipped since finalize_on_sync is false) fires. The stalled current query then blocks the pending queue for subsequent statements. This is a niche path (cursor/row-limited Execute) and process_client_message reads but ignores the max-rows field, so it may not be exercised today; if PortalSuspended is possible, consider handling type 's'/'I' to advance the queue. Verify against your expected client protocol usage before acting.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

Copy link
Copy Markdown

@renecannao

Copy link
Copy Markdown
Contributor Author

The CI-unit-tests-asan-coverage failure here is not caused by this PR — it is an intermittent build race, now fixed separately in #6024.

The job failed in its build step, not in the tests (they were skipped):

/usr/bin/ld: error: /opt/proxysql/test/tap/tap/libcurl.so: file too short
make[2]: *** [Makefile:794: genai_fts_string_unit-t] Error 1

unit_tests was the only target in test/tap/Makefile without the tap test_deps prerequisites its three siblings declare, so it ran concurrently with tap — whose recipe copies libcurl into the very directory the unit tests link from. A linker following the symlink chain while cp was still writing the ~700 KB payload read a truncated ELF.

Nothing in this PR touches libcurl or genai, and the same workflow passed on this branch's previous commit (5972d221c). Re-running the job should be enough to clear it here; #6024 stops it recurring.

@renecannao
renecannao merged commit b263edc into v3.0 Aug 10, 2026
80 of 83 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.

1 participant