Skip to content

RESET PREPARED: clear the cache with default config, never reuse statement names - #1331

Open
IgorOhrimenko wants to merge 1 commit into
pgdogdev:mainfrom
IgorOhrimenko:reset-prepared-clears-cache
Open

RESET PREPARED: clear the cache with default config, never reuse statement names#1331
IgorOhrimenko wants to merge 1 commit into
pgdogdev:mainfrom
IgorOhrimenko:reset-prepared-clears-cache

Conversation

@IgorOhrimenko

Copy link
Copy Markdown
Contributor

Two related defects in the prepared statements cache admin path, split out of #1311 so they can be reviewed on their own.

RESET PREPARED does nothing with the default config

ResetPrepared::execute() passed prepared_statements_limit into close_unused(), and the default limit is unlimited (i64::MAX) — len() - capacity saturates to 0 and the command removes nothing. It now passes 0 explicitly: drop everything not in use, whatever the configured limit is.

close_unused(0) wiped in-use statements and reused global names

close_unused(0) called reset(): it dropped statements clients still hold and rolled the global name counter back to zero. After that, a server connection that still has an old __pgdog_N statement prepared can be handed a different query under the same name — the server-side cache check compares names only. The same path ran once a second from the maintenance task for anyone who sets prepared_statements_limit = 0.

close_unused(0) now removes only unused statements and never touches the counter; reset() is #[cfg(test)].

Testing

  • close_unused(0) keeps statements in use, removes released ones, and the next insert gets a fresh global name (fails on main: everything is wiped and the name is reused).
  • RESET PREPARED clears released statements under the default config (fails on main: no-op).
  • Parser test for RESET PREPAREDRESET QUERY_CACHE had one, this command didn't.

@codecov

codecov Bot commented Aug 10, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

RESET PREPARED passed the configured prepared_statements_limit into
close_unused(), and the default limit is unlimited — so out of the box
the command removed nothing. Pass 0 explicitly: drop everything not in
use, whatever the limit is.

That exposed what close_unused(0) actually did: reset() the whole
cache, dropping statements clients still hold and rolling the global
name counter back to zero. A server connection that still has an old
__pgdog_N prepared would then be handed a different query under the
same name — the local cache check only compares names. The same path
runs every second from maintenance when prepared_statements_limit is
set to 0. close_unused(0) now removes only unused statements and never
touches the counter; reset() is test-only.

RESET PREPARED also had no parser test (RESET QUERY_CACHE did).
@IgorOhrimenko
IgorOhrimenko force-pushed the reset-prepared-clears-cache branch from 851d1d0 to 67e3c84 Compare August 10, 2026 10:07
@IgorOhrimenko
IgorOhrimenko marked this pull request as ready for review August 10, 2026 12:35
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