Skip to content

pgwire: report ParameterStatus for DISCARD ALL#37648

Draft
ggevay wants to merge 1 commit into
MaterializeInc:mainfrom
ggevay:gabor/sql-485-discard-all-parameter-status
Draft

pgwire: report ParameterStatus for DISCARD ALL#37648
ggevay wants to merge 1 commit into
MaterializeInc:mainfrom
ggevay:gabor/sql-485-discard-all-parameter-status

Conversation

@ggevay

@ggevay ggevay commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Fixes SQL-485

Motivation

DISCARD ALL resets all session variables but did not send ParameterStatus messages for the reportable (GUC_REPORT) parameters it changed, unlike RESET <var>. Connection poolers that track reported parameters silently desync from the server. For example, with pgbouncer and server_reset_query_always=1, every client's application_name silently became '' on Materialize while PostgreSQL preserves the pooler-tracked value. PostgreSQL reports every changed GUC_REPORT parameter after DISCARD ALL (verified against Postgres 18 on the raw wire).

Description

DISCARD ALL now sends a ParameterStatus message for every parameter in the notify set whose value changed as a result of the session reset, matching PostgreSQL's wire behavior.

This reuses the existing reporting mechanism instead of hand-emitting messages: SessionVars::reset_all and Session::reset now return the parameters whose value changed, ExecuteResponse::DiscardedAll carries them, and the pgwire endpoint handles them in the same match arm as TransactionCommitted/TransactionRolledBack, which already report changed parameters. The websocket SQL endpoint gets the same treatment, so DISCARD ALL over ws now includes the changed parameters in its result, consistent with how that endpoint reports SET and transaction ends.

One benign divergence from PostgreSQL: Materialize sends ParameterStatus before CommandComplete, PostgreSQL after. The protocol does not specify an order, and this matches Materialize's existing SET/RESET behavior.

The pgtest framework previously discarded all ParameterStatus messages. It now renders them when (and only when) a test's until block explicitly expects ParameterStatus, so existing tests are unaffected.

Verification

  • New regression test test/pgtest-mz/discard.pt asserts on the raw wire that SET application_name followed by DISCARD ALL produces ParameterStatus {"name":"application_name","value":""}, including a case with two changed parameters (TimeZone and application_name) reported in one batch.
  • Verified PostgreSQL 18's behavior with a raw-pgwire probe: DISCARD ALL (and RESET ALL) emit ParameterStatus for each changed GUC_REPORT parameter, restoring startup-packet values. Materialize already treats startup parameters as session defaults (test_startup_params_survive_reset), so the reported values match.
  • Existing coverage: full pgtest suite, test/sqllogictest/discard.slt, and the mz-sql/mz-pgwire unit tests all pass locally.

🤖 Generated with Claude Code

DISCARD ALL resets all session variables but did not send
ParameterStatus messages for the reportable parameters it changed,
unlike RESET. Connection poolers that track reported parameters, such
as pgbouncer with server_reset_query, silently desynced from the
server. PostgreSQL reports every changed GUC_REPORT parameter after
DISCARD ALL.

SessionVars::reset_all and Session::reset now return the parameters
whose value changed, ExecuteResponse::DiscardedAll carries them, and
the pgwire and HTTP endpoints report them the same way as transaction
ends already do.

Also teach the pgtest framework to render ParameterStatus messages
when a test explicitly expects them, and add a regression test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ggevay ggevay added the A-ADAPTER Topics related to the ADAPTER layer label Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-ADAPTER Topics related to the ADAPTER layer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant