Fix \crosstabview to honor \pset display_true/display_false

Started by Chao Li16 days ago3 messageshackers
Jump to latest
#1Chao Li
li.evan.chao@gmail.com

Hi,

While testing “[645cb44c5] Add \pset options for boolean value display”, I noticed that it seems to miss support for \crosstabview.

Here is a repro:
```
evantest=# \pset display_true YES
Boolean true display is "YES".
evantest=# \pset display_false NO
Boolean false display is "NO".
evantest=#
evantest=# select true as direct_true, false as direct_false;
direct_true | direct_false
-------------+--------------
YES | NO
(1 row)

evantest=#
evantest=# select false as row_key, true as col_key, true as val
evantest-# union all
evantest-# select true, false, false
evantest-# \crosstabview row_key col_key val
row_key | t | f
---------+---+---
f | t |
t | | f
(2 rows)
```

In normal query output, true/false are shown as YES/NO, but \crosstabview still shows them as t/f.

I noticed this problem by searching for nullPrint and finding it in crosstabview.c. Since nullPrint is already honored there, display_true/display_false should be honored as well.

While working on the fix, I further noticed that numericlocale is also not honored by \crosstabview:
```
evantest=# \pset numericlocale on
evantest=#
evantest=# SELECT 12345::numeric AS direct_value;
direct_value
--------------
12,345
(1 row)

evantest=#
evantest=# SELECT 1 AS row_key, 1 AS col_key, 12345::numeric AS val
evantest-# \crosstabview row_key col_key val
row_key | 1
---------+-------
1 | 12345
(1 row)
```

Since we are supposed to fix only v19 bugs at this stage, this patch only makes \crosstabview honor display_true/display_false, as that is a new PG19 feature. I will add the numericlocale work to my TODO and revisit it for v20.

In this patch, I add a helper function, printQueryOptDisplayValue(), to handle both nullPrint and display_true/display_false in a single place. In the future, we may also be able to handle numericlocale in this function.

See the attached patch for details. With the fix, \crosstabview displays boolean values according to the \pset settings:
```
evantest=# select false as row_key, true as col_key, true as val
evantest-# union all
evantest-# select true, false, false
evantest-# \crosstabview row_key col_key val
row_key | YES | NO
---------+-----+----
NO | YES |
YES | | NO
(2 rows)
```

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v1-0001-Make-crosstabview-honor-boolean-display-settings.patchapplication/octet-stream; name=v1-0001-Make-crosstabview-honor-boolean-display-settings.patch; x-unix-mode=0644Download+83-31
#2David G. Johnston
david.g.johnston@gmail.com
In reply to: Chao Li (#1)
Re: Fix \crosstabview to honor \pset display_true/display_false

On Wed, Jun 3, 2026 at 12:16 AM Chao Li <li.evan.chao@gmail.com> wrote:

While testing “[645cb44c5] Add \pset options for boolean value display”, I
noticed that it seems to miss support for \crosstabview.

In this patch, I add a helper function, printQueryOptDisplayValue(), to
handle both nullPrint and display_true/display_false in a single place. In
the future, we may also be able to handle numericlocale in this function.

Thanks Chao!

Adding a function indeed seems like the best choice - the only question is
whether expanding print.h at this point is acceptable. If not, making it
private to crosstab.c will accomplish the same immediate need.

The name is a bit odd to me but I'm also not that familiar with naming
conventions in the C code. But this is another reason to make it private
in v19 and figure out the public interface in v20.

cont.cells[idx] =
printQueryOptDisplayValue(!PQgetisnull(result, rn, field_for_data) ?
PQgetvalue(result, rn, field_for_data) :
NULL,
data_ftype, &popt, "");

I'd either remove the not operator and flip the order of the output ternary
positions, or move the entire "compute the unadjusted value" to a local
variable (assignment from ternary or just an if block) and then pass it to
printQueryOptDisplayValue directly. Having a ternary expression as the
first argument is what the other changes got rid of and makes this much
easier to read (hence the need for the function).

David J.

#3Chao Li
li.evan.chao@gmail.com
In reply to: David G. Johnston (#2)
Re: Fix \crosstabview to honor \pset display_true/display_false

On Jun 19, 2026, at 06:47, David G. Johnston <david.g.johnston@gmail.com> wrote:

On Wed, Jun 3, 2026 at 12:16 AM Chao Li <li.evan.chao@gmail.com> wrote:
While testing “[645cb44c5] Add \pset options for boolean value display”, I noticed that it seems to miss support for \crosstabview.

In this patch, I add a helper function, printQueryOptDisplayValue(), to handle both nullPrint and display_true/display_false in a single place. In the future, we may also be able to handle numericlocale in this function.

Thanks Chao!

Adding a function indeed seems like the best choice - the only question is whether expanding print.h at this point is acceptable. If not, making it private to crosstab.c will accomplish the same immediate need.

The name is a bit odd to me but I'm also not that familiar with naming conventions in the C code. But this is another reason to make it private in v19 and figure out the public interface in v20.

Sounds fair. I removed the helper declaration from print.h and added local temporary declaration in the .c files with a TODO comment for v20.

cont.cells[idx] =
printQueryOptDisplayValue(!PQgetisnull(result, rn, field_for_data) ?
PQgetvalue(result, rn, field_for_data) :
NULL,
data_ftype, &popt, "");

I'd either remove the not operator and flip the order of the output ternary positions, or move the entire "compute the unadjusted value" to a local variable (assignment from ternary or just an if block) and then pass it to printQueryOptDisplayValue directly. Having a ternary expression as the first argument is what the other changes got rid of and makes this much easier to read (hence the need for the function).

Agreed.

PFA v2: addressed David’s comments.

Best regards,
--
Chao Li (Evan)
HighGo Software Co., Ltd.
https://www.highgo.com/

Attachments:

v2-0001-Make-crosstabview-honor-boolean-display-settings.patchapplication/octet-stream; name=v2-0001-Make-crosstabview-honor-boolean-display-settings.patch; x-unix-mode=0644Download+96-32