Adjust pg_stat_get_lock() prorows to match lock types

First seen: 2026-05-04 02:23:47+00:00 · Messages: 1 · Participants: 1

Latest Update

2026-05-06 · opus 4.7

Analysis: Adjusting pg_stat_get_lock() prorows to Match Actual Lock Type Count

Core Problem

This thread addresses a minor but legitimate planner-estimation inaccuracy in the system catalog function pg_stat_get_lock() (exposed via the pg_stat_lock view). The function is a set-returning function (SRF) that emits one row per lock type tracked by the statistics subsystem. Because it is an SRF written in C, the planner has no way to derive a row-count estimate from relation statistics; it relies entirely on the prorows field declared in pg_proc.dat.

The declared prorows = 10 is stale relative to the function's actual behavior, which returns 12 rows — one per defined lock type. The discrepancy is small in absolute terms, but for a function whose cardinality is deterministic and fixed at compile time, there is no reason for the estimate to be wrong at all.

Why This Matters Architecturally

  1. Deterministic cardinality should be exact. Unlike SRFs whose output depends on runtime input (e.g. generate_series(a,b) or unnest(arr)), pg_stat_get_lock() returns a compile-time-fixed number of rows equal to the number of lock-type enum entries. There is no statistical guesswork involved — the correct prorows value is knowable.

  2. Downstream plan quality. While a 10-vs-12 delta is unlikely to flip a plan shape on its own, pg_stat_lock is often joined against other catalogs or filtered in monitoring queries. When an SRF feeds a nested loop or hash join, an underestimate of 20% in the outer side can cascade — particularly once the view is wrapped in more complex monitoring SQL. Keeping catalog-function prorows in sync with reality is a standard hygiene item and has been adjusted for similar functions historically (e.g. pg_stat_get_backend_*, pg_get_keywords, etc.).

  3. Consistency invariant. The number of lock types is defined by an enum/array in the lock-stats infrastructure. Any patch that adds a lock type must bump prorows in lockstep, and the current mismatch suggests that invariant was silently violated at some point — either the set of lock types grew from 10 to 12 without the catalog metadata being updated, or prorows was an initial guess that was never tightened.

Proposed Change

The patch is minimal and mechanical:

Note that prorows only affects the planner; the executor still emits whatever the function actually produces. So the patch is semantically a pure optimizer hint adjustment with no runtime behavior change and no catalog-version bump requirement beyond the usual CATALOG_VERSION_NO bump for any pg_proc.dat edit.

Design Considerations / Tradeoffs

Participant Assessment

Only one message from the original poster (Evan Li) exists at the time of this analysis. This is a first-patch-style contribution — small, self-contained, with a reproducer via EXPLAIN ANALYZE and a clearly presented before/after. No committer has yet weighed in. The change is small enough that it is likely to be picked up by a committer with minimal review, possibly with a request to either drop the comment changes or justify them explicitly.

Likely Review Outcomes

  1. Patch accepted as-is with the prorows bump; comment tweaks kept if genuinely improving clarity, dropped otherwise.
  2. Reviewer may request adding a StaticAssertStmt or a comment adjacent to the lock-type definition reminding maintainers to keep prorows synchronized.
  3. Catalog version bump handled by the committer at commit time (customary — submitters are usually told not to include it).