Skip to content

[FIXED in 4.1.0] Cancelling a pipelined query that hasn't started can give the next query its result #48

Closed

Description

@okomarov

Tracks porsager#1252 against the fork.

Claim: a query that was already written to the connection, pipelined behind another, can be cancelled before it starts. ReadyForQuery then skips it, but PostgreSQL still sends that statement's answer, which is read as the next query's. The report includes a repro: a max: 1 reserved connection with three unsafe queries, where the middle one is cancelled while the first sleeps.

Status: fixed in 4.1.0 by ab0b431, which replaced the skipping loop with pipelined(), the same change porsager#1256 proposes. phase:cancel-pipelined (tests-startup/startup.js) reproduces it on a fake server and failed before that commit. Not claimed yet, because no test runs the report against real PostgreSQL.

To do:

  • Turn the report's reserve() repro (or Fix cancelling a query that has not started porsager/postgres#1256's test) into a real-PostgreSQL test that fails on 3.4.9, then add the README row and close this.
  • A CancelRequest is still sent when queries are pipelined behind the cancelled one; that is the race the README documents.
  • By reading, a cancelled pipelined prepared statement that hits a cached-plan error never settles: retry() hands it to submit(), which returns early for a cancelled query. Test it; open its own issue if it reproduces.

Activity

  1. moved this to Later in Roadmapon Oct 15, 2026
  2. added
    area: protocolProtocol messages and result handling
    upstreamAnswers porsager/postgres reports
    on Oct 16, 2026
  3. added this to the 4.5.0 milestone on Oct 16, 2026
  4. moved this from Later to In progress in Roadmapon Oct 16, 2026
  5. okomarov commented on Oct 16, 2026

    @okomarov
    Author

    From the #124 review, inferred and not reproduced: a retried query goes to the end of sent with active still true from its first turn. If it is cancelled while waiting there, cancel() takes the current-query branch and sends the CancelRequest at once, so it can hit whichever query the backend is running. Same misdirected-cancel race as the second point above.

  6. okomarov commented on Oct 17, 2026

    @okomarov
    Author

    Fixed in 4.1.0 (ab0b431). The reporter's reserve() repro is now a real-PostgreSQL test (c2e04d7) that fails on 3.4.9 as reported and passes here; README row in c5fa99b. The cached-plan follow-up became #123 (fixed, 2a2866e). The misdirected CancelRequest race noted above remains as documented in the README.

  7. okomarov commented on Oct 17, 2026

    @okomarov
    Author

    Shipped in 4.5.0.

  8. moved this from In progress to Shipped in Roadmapon Oct 17, 2026
  9. changed the title [-]Cancelling a pipelined query that hasn't started can give the next query its result[/-] [+][FIXED in 4.1.0] Cancelling a pipelined query that hasn't started can give the next query its result[/+] on Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: protocolProtocol messages and result handlingbugSomething isn't workingupstreamAnswers porsager/postgres reports

    Type

    No type

    Projects

    • Status
      Shipped

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions