Fix \crosstabview to honor \pset display_true/display_false

First seen: 2026-06-03 07:16:13+00:00 · Messages: 1 · Participants: 1

Latest Update

2026-06-04 · claude-opus-4-6

Fix \crosstabview to Honor \pset display_true/display_false

Technical Problem

PostgreSQL 19 introduced a new psql feature (commit 645cb44c5) that allows users to customize how boolean values are displayed via \pset display_true and \pset display_false. This works correctly for normal query output but fails for \crosstabview, which is a psql meta-command that pivots query results into a cross-tabulation format.

The root cause is an architectural inconsistency in how crosstabview.c renders cell values. The crosstabview code path bypasses the normal print formatting pipeline that applies display transformations. While it already honors nullPrint (the custom NULL display string), it was not updated when the new boolean display settings were added in PG19.

Architectural Context

The psql Display Pipeline

In psql's normal query output path, results flow through printQuery() which applies various formatting transformations based on printQueryOpt settings:

The crosstabview Code Path

\crosstabview operates differently from normal output. It takes query results and reorganizes them into a pivot table before printing. The code in crosstabview.c manually constructs a new printTableContent structure, copying cell values from the original result set. During this manual construction, it only checked for NULL values (applying nullPrint) but did not apply boolean display transformations.

This is a classic problem with parallel code paths — when a new display feature is added to the main rendering pipeline, satellite code paths that handle their own rendering can be missed.

Proposed Solution

The patch introduces a helper function printQueryOptDisplayValue() that centralizes the logic for transforming raw cell values according to display settings. This function handles:

  1. NULL values → returns nullPrint string
  2. Boolean true values (raw value "t") → returns display_true setting
  3. Boolean false values (raw value "f") → returns display_false setting

By consolidating this logic into a single function, the patch:

Design Decisions and Tradeoffs

Scoped Fix for PG19

The author deliberately limits the fix to the boolean display issue since it's a PG19-only feature (and thus a PG19 bug). The numericLocale issue in crosstabview is acknowledged but deferred to v20, since it's a pre-existing behavior and not appropriate for the current release phase (bug-fix only).

Helper Function Approach

Rather than adding inline checks in crosstabview.c, the creation of printQueryOptDisplayValue() is a good abstraction that:

Boolean Detection Strategy

The patch likely detects boolean values by checking for the raw PostgreSQL wire format values "t" and "f" combined with column type information (OID for boolean type). This is important because a text column could legitimately contain the value "t" without being a boolean.

Scope of Impact

The fix affects three display contexts within crosstabview:

  1. Row header values — the leftmost column showing row keys
  2. Column header values — the top row showing column keys
  3. Cell values — the data cells in the pivot table body

All three are visible in the before/after example where row_key, col_key, and val all transition from raw t/f to YES/NO display.

Outstanding Issues

The numericLocale gap is more complex to fix because numeric locale formatting requires knowledge of the column's numeric type and involves locale-dependent formatting logic that may be more tightly coupled to the print infrastructure. This is appropriately deferred.