1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-07 19:06:32 +03:00

Add \pset options for boolean value display

New \pset variables display_true and display_false allow the user to
change how true and false values are displayed.

Author: David G. Johnston <David.G.Johnston@gmail.com>
Reviewed-by: Álvaro Herrera <alvherre@kurilemu.de>
Discussion: https://postgr.es/m/CAKFQuwYts3vnfQ5AoKhEaKMTNMfJ443MW2kFswKwzn7fiofkrw@mail.gmail.com
Discussion: https://postgr.es/m/56308F56.8060908@joh.to
This commit is contained in:
Álvaro Herrera
2025-11-03 17:40:39 +01:00
parent cf8be02253
commit 645cb44c54
8 changed files with 123 additions and 5 deletions

View File

@@ -3099,6 +3099,26 @@ SELECT $1 \parse stmt1
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry id="app-psql-meta-command-pset-display-false">
<term><literal>display_false</literal></term>
<listitem>
<para>
Sets the string to be printed in place of a false value.
The default is to print <literal>f</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry id="app-psql-meta-command-pset-display-true">
<term><literal>display_true</literal></term>
<listitem>
<para>
Sets the string to be printed in place of a true value.
The default is to print <literal>t</literal>.
</para>
</listitem>
</varlistentry>
<varlistentry id="app-psql-meta-command-pset-expanded"> <varlistentry id="app-psql-meta-command-pset-expanded">
<term><literal>expanded</literal> (or <literal>x</literal>)</term> <term><literal>expanded</literal> (or <literal>x</literal>)</term>
<listitem> <listitem>

View File

@@ -2709,7 +2709,8 @@ exec_command_pset(PsqlScanState scan_state, bool active_branch)
int i; int i;
static const char *const my_list[] = { static const char *const my_list[] = {
"border", "columns", "csv_fieldsep", "expanded", "fieldsep", "border", "columns", "csv_fieldsep",
"display_false", "display_true", "expanded", "fieldsep",
"fieldsep_zero", "footer", "format", "linestyle", "null", "fieldsep_zero", "footer", "format", "linestyle", "null",
"numericlocale", "pager", "pager_min_lines", "numericlocale", "pager", "pager_min_lines",
"recordsep", "recordsep_zero", "recordsep", "recordsep_zero",
@@ -5300,6 +5301,26 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
} }
} }
/* 'false' display */
else if (strcmp(param, "display_false") == 0)
{
if (value)
{
free(popt->falsePrint);
popt->falsePrint = pg_strdup(value);
}
}
/* 'true' display */
else if (strcmp(param, "display_true") == 0)
{
if (value)
{
free(popt->truePrint);
popt->truePrint = pg_strdup(value);
}
}
/* field separator for unaligned text */ /* field separator for unaligned text */
else if (strcmp(param, "fieldsep") == 0) else if (strcmp(param, "fieldsep") == 0)
{ {
@@ -5474,6 +5495,20 @@ printPsetInfo(const char *param, printQueryOpt *popt)
popt->topt.csvFieldSep); popt->topt.csvFieldSep);
} }
/* show boolean 'false' display */
else if (strcmp(param, "display_false") == 0)
{
printf(_("Boolean false display is \"%s\".\n"),
popt->falsePrint ? popt->falsePrint : "f");
}
/* show boolean 'true' display */
else if (strcmp(param, "display_true") == 0)
{
printf(_("Boolean true display is \"%s\".\n"),
popt->truePrint ? popt->truePrint : "t");
}
/* show field separator for unaligned text */ /* show field separator for unaligned text */
else if (strcmp(param, "fieldsep") == 0) else if (strcmp(param, "fieldsep") == 0)
{ {
@@ -5743,6 +5778,10 @@ pset_value_string(const char *param, printQueryOpt *popt)
return psprintf("%d", popt->topt.columns); return psprintf("%d", popt->topt.columns);
else if (strcmp(param, "csv_fieldsep") == 0) else if (strcmp(param, "csv_fieldsep") == 0)
return pset_quoted_string(popt->topt.csvFieldSep); return pset_quoted_string(popt->topt.csvFieldSep);
else if (strcmp(param, "display_false") == 0)
return pset_quoted_string(popt->falsePrint ? popt->falsePrint : "f");
else if (strcmp(param, "display_true") == 0)
return pset_quoted_string(popt->truePrint ? popt->truePrint : "t");
else if (strcmp(param, "expanded") == 0) else if (strcmp(param, "expanded") == 0)
return pstrdup(popt->topt.expanded == 2 return pstrdup(popt->topt.expanded == 2
? "auto" ? "auto"

View File

@@ -290,9 +290,9 @@ slashUsage(unsigned short int pager)
HELPN(" \\H toggle HTML output mode (currently %s)\n", HELPN(" \\H toggle HTML output mode (currently %s)\n",
ON(pset.popt.topt.format == PRINT_HTML)); ON(pset.popt.topt.format == PRINT_HTML));
HELP0(" \\pset [NAME [VALUE]] set table output option\n" HELP0(" \\pset [NAME [VALUE]] set table output option\n"
" (border|columns|csv_fieldsep|expanded|fieldsep|\n" " (border|columns|csv_fieldsep|display_false|display_true|\n"
" fieldsep_zero|footer|format|linestyle|null|\n" " expanded|fieldsep|fieldsep_zero|footer|format|linestyle|\n"
" numericlocale|pager|pager_min_lines|recordsep|\n" " null|numericlocale|pager|pager_min_lines|recordsep|\n"
" recordsep_zero|tableattr|title|tuples_only|\n" " recordsep_zero|tableattr|title|tuples_only|\n"
" unicode_border_linestyle|unicode_column_linestyle|\n" " unicode_border_linestyle|unicode_column_linestyle|\n"
" unicode_header_linestyle|xheader_width)\n"); " unicode_header_linestyle|xheader_width)\n");
@@ -480,6 +480,10 @@ helpVariables(unsigned short int pager)
" border style (number)\n"); " border style (number)\n");
HELP0(" columns\n" HELP0(" columns\n"
" target width for the wrapped format\n"); " target width for the wrapped format\n");
HELP0(" display_false\n"
" set the string to be printed in place of a boolean 'false'\n");
HELP0(" display_true\n"
" set the string to be printed in place of a boolean 'true'\n");
HELP0(" expanded (or x)\n" HELP0(" expanded (or x)\n"
" expanded output [on, off, auto]\n"); " expanded output [on, off, auto]\n");
HELPN(" fieldsep\n" HELPN(" fieldsep\n"

View File

@@ -5478,7 +5478,8 @@ match_previous_words(int pattern_id,
else if (TailMatchesCS("\\password")) else if (TailMatchesCS("\\password"))
COMPLETE_WITH_QUERY(Query_for_list_of_roles); COMPLETE_WITH_QUERY(Query_for_list_of_roles);
else if (TailMatchesCS("\\pset")) else if (TailMatchesCS("\\pset"))
COMPLETE_WITH_CS("border", "columns", "csv_fieldsep", "expanded", COMPLETE_WITH_CS("border", "columns", "csv_fieldsep",
"display_false", "display_true", "expanded",
"fieldsep", "fieldsep_zero", "footer", "format", "fieldsep", "fieldsep_zero", "footer", "format",
"linestyle", "null", "numericlocale", "linestyle", "null", "numericlocale",
"pager", "pager_min_lines", "pager", "pager_min_lines",

View File

@@ -3775,6 +3775,10 @@ printQuery(const PGresult *result, const printQueryOpt *opt,
if (PQgetisnull(result, r, c)) if (PQgetisnull(result, r, c))
cell = opt->nullPrint ? opt->nullPrint : ""; 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 else
{ {
cell = PQgetvalue(result, r, c); cell = PQgetvalue(result, r, c);

View File

@@ -184,6 +184,8 @@ typedef struct printQueryOpt
{ {
printTableOpt topt; /* the options above */ printTableOpt topt; /* the options above */
char *nullPrint; /* how to print null entities */ 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 *title; /* override title */
char **footers; /* override footer (default is "(xx rows)") */ char **footers; /* override footer (default is "(xx rows)") */
bool translate_header; /* do gettext on column headers */ bool translate_header; /* do gettext on column headers */

View File

@@ -445,6 +445,8 @@ environment value
border 1 border 1
columns 0 columns 0
csv_fieldsep ',' csv_fieldsep ','
display_false 'f'
display_true 't'
expanded off expanded off
fieldsep '|' fieldsep '|'
fieldsep_zero off fieldsep_zero off
@@ -464,6 +466,36 @@ unicode_border_linestyle single
unicode_column_linestyle single unicode_column_linestyle single
unicode_header_linestyle single unicode_header_linestyle single
xheader_width full xheader_width full
-- test the simple display substitution settings
prepare q as select null as n, true as t, false as f;
\pset null '(null)'
\pset display_true 'true'
\pset display_false 'false'
execute q;
n | t | f
--------+------+-------
(null) | true | false
(1 row)
\pset null
\pset display_true
\pset display_false
execute q;
n | t | f
--------+------+-------
(null) | true | false
(1 row)
\pset null ''
\pset display_true 't'
\pset display_false 'f'
execute q;
n | t | f
---+---+---
| t | f
(1 row)
deallocate q;
-- test multi-line headers, wrapping, and newline indicators -- test multi-line headers, wrapping, and newline indicators
-- in aligned, unaligned, and wrapped formats -- in aligned, unaligned, and wrapped formats
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab

View File

@@ -219,6 +219,22 @@ select 'drop table gexec_test', 'select ''2000-01-01''::date as party_over'
-- show all pset options -- show all pset options
\pset \pset
-- test the simple display substitution settings
prepare q as select null as n, true as t, false as f;
\pset null '(null)'
\pset display_true 'true'
\pset display_false 'false'
execute q;
\pset null
\pset display_true
\pset display_false
execute q;
\pset null ''
\pset display_true 't'
\pset display_false 'f'
execute q;
deallocate q;
-- test multi-line headers, wrapping, and newline indicators -- test multi-line headers, wrapping, and newline indicators
-- in aligned, unaligned, and wrapped formats -- in aligned, unaligned, and wrapped formats
prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab prepare q as select array_to_string(array_agg(repeat('x',2*n)),E'\n') as "ab