Hi! Please accept this patch (though it's not finished, just functional)!
It's \pset null for boolean values Printing tables of 't' and 'f' makes for painful-to-read output. This provides an easy win for psql users, giving them the option to do better. I would like all of our documentation examples eventually to be done with "\pset display_true true" and "\pset display_false false" configured. Getting it into v18 so docs being written now, like my NULL patch, can make use of it, would make my year. I was initially going to go with the following to mirror null even more closely. \pset { true | false } value And still like that option, though having the same word repeated as the expected value and name hurts it a bit. This next one was also considered but the word "print" already seemed a bit too entwined with \pset format related stuff. \pset { print_true | print_false } value David J.
From 4d306939c008ecf7e8ae0036a46218b059a069c7 Mon Sep 17 00:00:00 2001 From: "David G. Johnston" <david.g.johns...@gmail.com> Date: Thu, 20 Mar 2025 20:03:01 -0700 Subject: [PATCH] Add \pset options for boolean value display The server's space-expedient choice to use 't' and 'f' to represent boolean true and false respectively is technically understandable but visually atrocious. Teach psql to detect these two values and print whatever it deems is appropriate. For now, in the interest of backward compatability, that defaults to 't' and 'f'. However, now the user can impose their own standards by using the newly introduced display_true and display_false pset settings. --- src/bin/psql/command.c | 43 ++++++++++++++++++++++++++++++++++++ src/fe_utils/print.c | 6 +++++ src/include/fe_utils/print.h | 2 ++ 3 files changed, 51 insertions(+) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index bbe337780f..29f212e54f 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -2688,6 +2688,7 @@ exec_command_pset(PsqlScanState scan_state, bool active_branch) "border", "columns", "csv_fieldsep", "expanded", "fieldsep", "fieldsep_zero", "footer", "format", "linestyle", "null", "numericlocale", "pager", "pager_min_lines", + "display_true", "display_false", "recordsep", "recordsep_zero", "tableattr", "title", "tuples_only", "unicode_border_linestyle", @@ -5193,6 +5194,26 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) } } + /* true display */ + else if (strcmp(param, "display_true") == 0) + { + if (value) + { + free(popt->truePrint); + popt->truePrint = pg_strdup(value); + } + } + + /* false display */ + else if (strcmp(param, "display_false") == 0) + { + if (value) + { + free(popt->falsePrint); + popt->falsePrint = pg_strdup(value); + } + } + /* field separator for unaligned text */ else if (strcmp(param, "fieldsep") == 0) { @@ -5411,6 +5432,20 @@ printPsetInfo(const char *param, printQueryOpt *popt) popt->nullPrint ? popt->nullPrint : ""); } + /* show boolean true display */ + else if (strcmp(param, "display_true") == 0) + { + printf(_("Boolean true display is \"%s\".\n"), + popt->truePrint ? popt->truePrint : "t"); + } + + /* show boolean false display */ + else if (strcmp(param, "display_false") == 0) + { + printf(_("Boolean false display is \"%s\".\n"), + popt->falsePrint ? popt->falsePrint : "f"); + } + /* show locale-aware numeric output */ else if (strcmp(param, "numericlocale") == 0) { @@ -5656,6 +5691,14 @@ pset_value_string(const char *param, printQueryOpt *popt) return pset_quoted_string(popt->nullPrint ? popt->nullPrint : ""); + else if (strcmp(param, "display_true") == 0) + return pset_quoted_string(popt->truePrint + ? popt->truePrint + : "t"); + else if (strcmp(param, "display_false") == 0) + return pset_quoted_string(popt->falsePrint + ? popt->falsePrint + : "f"); else if (strcmp(param, "numericlocale") == 0) return pstrdup(pset_bool_string(popt->topt.numericLocale)); else if (strcmp(param, "pager") == 0) diff --git a/src/fe_utils/print.c b/src/fe_utils/print.c index 5e5e54e1b7..2156616c9d 100644 --- a/src/fe_utils/print.c +++ b/src/fe_utils/print.c @@ -3582,6 +3582,12 @@ printQuery(const PGresult *result, const printQueryOpt *opt, if (PQgetisnull(result, r, c)) cell = opt->nullPrint ? opt->nullPrint : ""; + else if (PQftype(result, c) == BOOLOID) + { + cell = (PQgetvalue(result, r, c)[0] == 't') + ? (opt->truePrint ? opt->truePrint : "t") + : (opt->falsePrint ? opt->falsePrint : "f"); + } else { cell = PQgetvalue(result, r, c); diff --git a/src/include/fe_utils/print.h b/src/include/fe_utils/print.h index c99c2ee1a3..2378e26acb 100644 --- a/src/include/fe_utils/print.h +++ b/src/include/fe_utils/print.h @@ -184,6 +184,8 @@ typedef struct printQueryOpt { printTableOpt topt; /* the options above */ char *nullPrint; /* how to print null entities */ + char *truePrint; /* how to print boolean true values */ + char *falsePrint; /* how to print boolean false values */ char *title; /* override title */ char **footers; /* override footer (default is "(xx rows)") */ bool translate_header; /* do gettext on column headers */ -- 2.34.1