*** a/src/bin/psql/command.c --- b/src/bin/psql/command.c *************** *** 2231,2236 **** do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet) --- 2231,2261 ---- get_line_style(&popt->topt)->name); } + /* set boolean output style */ + else if (strcmp(param, "boolstyle") == 0) + { + if (!value) + ; + else if (pg_strncasecmp("char", value, vallen) == 0) + popt->topt.bool_style = PRINT_BOOL_CHAR; + else if (pg_strncasecmp("word", value, vallen) == 0) + popt->topt.bool_style = PRINT_BOOL_WORD; + else + { + psql_error("\\pset: allowed bool styles are char, word\n"); + return false; + } + + if (!quiet) + { + if (popt->topt.bool_style == PRINT_BOOL_CHAR) + printf(_("Bool output style is char.\n")); + else if (popt->topt.bool_style == PRINT_BOOL_WORD) + printf(_("Bool output style is word.\n")); + } + + } + /* set border style/width */ else if (strcmp(param, "border") == 0) { *** a/src/bin/psql/describe.c --- b/src/bin/psql/describe.c *************** *** 22,27 **** --- 22,29 ---- #include "settings.h" #include "variables.h" + #include "catalog/pg_type.h" + static bool describeOneTableDetails(const char *schemaname, const char *relationname, *************** *** 1408,1414 **** describeOneTableDetails(const char *schemaname, printTableInitialized = true; for (i = 0; i < cols; i++) ! printTableAddHeader(&cont, headers[i], true, 'l'); /* Check if table is a view */ if (tableinfo.relkind == 'v' && verbose) --- 1410,1416 ---- printTableInitialized = true; for (i = 0; i < cols; i++) ! printTableAddHeader(&cont, headers[i], true, 'l', TEXTOID); /* Check if table is a view */ if (tableinfo.relkind == 'v' && verbose) *************** *** 2422,2433 **** describeRoles(const char *pattern, bool verbose) printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows); ! printTableAddHeader(&cont, gettext_noop("Role name"), true, align); ! printTableAddHeader(&cont, gettext_noop("Attributes"), true, align); ! printTableAddHeader(&cont, gettext_noop("Member of"), true, align); if (verbose && pset.sversion >= 80200) ! printTableAddHeader(&cont, gettext_noop("Description"), true, align); for (i = 0; i < nrows; i++) { --- 2424,2435 ---- printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows); ! printTableAddHeader(&cont, gettext_noop("Role name"), true, align, TEXTOID); ! printTableAddHeader(&cont, gettext_noop("Attributes"), true, align, TEXTOID); ! printTableAddHeader(&cont, gettext_noop("Member of"), true, align, TEXTOID); if (verbose && pset.sversion >= 80200) ! printTableAddHeader(&cont, gettext_noop("Description"), true, align, TEXTOID); for (i = 0; i < nrows; i++) { *** a/src/bin/psql/print.c --- b/src/bin/psql/print.c *************** *** 2149,2154 **** printTableInit(printTableContent *const content, const printTableOpt *opt, --- 2149,2158 ---- content->footer = content->footers; content->align = content->aligns; content->cellsadded = 0; + + content->ftypes = pg_local_calloc(ncolumns + 1, + sizeof(*content->ftype)); + content->ftype = content->ftypes; } /* *************** *** 2165,2171 **** printTableInit(printTableContent *const content, const printTableOpt *opt, */ void printTableAddHeader(printTableContent *const content, char *header, ! const bool translate, const char align) { #ifndef ENABLE_NLS (void) translate; /* unused parameter */ --- 2169,2175 ---- */ void printTableAddHeader(printTableContent *const content, char *header, ! const bool translate, const char align, const Oid ftype) { #ifndef ENABLE_NLS (void) translate; /* unused parameter */ *************** *** 2189,2194 **** printTableAddHeader(printTableContent *const content, char *header, --- 2193,2201 ---- *content->align = align; content->align++; + + *content->ftype = ftype; + content->ftype++; } /* *************** *** 2443,2448 **** printTable(const printTableContent *cont, FILE *fout, FILE *flog) --- 2450,2485 ---- } /* + * formating value - value must not be null + */ + static char * + format_value(printTableContent *cont, int col, const printQueryOpt *opt, + char *value, bool *mustfree) + { + char *result; + + *mustfree = false; + + /* format any numeric value */ + if (cont->aligns[col] == 'r' && opt->topt.numericLocale) + { + *mustfree = true; + result = format_numeric_locale(value); + } + + /* format boolean value */ + else if (cont->ftypes[col] == BOOLOID && opt->topt.bool_style == PRINT_BOOL_WORD) + { + result = (strcmp(value, "t") == 0) ? "true" : "false"; + } + else + result = value; + + return result; + } + + + /* * Use this to print query results * * It calls printTable with all the things set straight. *************** *** 2486,2492 **** printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f } printTableAddHeader(&cont, PQfname(result, i), ! opt->translate_header, align); } /* set cells */ --- 2523,2529 ---- } printTableAddHeader(&cont, PQfname(result, i), ! opt->translate_header, align, ftype); } /* set cells */ *************** *** 2495,2514 **** printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, FILE *f for (c = 0; c < cont.ncolumns; c++) { char *cell; - bool mustfree = false; bool translate; if (PQgetisnull(result, r, c)) cell = opt->nullPrint ? opt->nullPrint : ""; else ! { ! cell = PQgetvalue(result, r, c); ! if (cont.aligns[c] == 'r' && opt->topt.numericLocale) ! { ! cell = format_numeric_locale(cell); ! mustfree = true; ! } ! } translate = (opt->translate_columns && opt->translate_columns[c]); printTableAddCell(&cont, cell, translate, mustfree); --- 2532,2545 ---- for (c = 0; c < cont.ncolumns; c++) { char *cell; bool translate; + bool mustfree; if (PQgetisnull(result, r, c)) cell = opt->nullPrint ? opt->nullPrint : ""; else ! cell = format_value(&cont, c, opt, ! PQgetvalue(result, r, c), &mustfree); translate = (opt->translate_columns && opt->translate_columns[c]); printTableAddCell(&cont, cell, translate, mustfree); *** a/src/bin/psql/print.h --- b/src/bin/psql/print.h *************** *** 23,28 **** enum printFormat --- 23,34 ---- /* add your favourite output format here ... */ }; + enum boolStyle + { + PRINT_BOOL_CHAR, + PRINT_BOOL_WORD + }; + typedef struct printTextLineFormat { /* Line drawing characters to be used in various contexts */ *************** *** 88,93 **** typedef struct printTableOpt --- 94,100 ---- bool default_footer; /* allow "(xx rows)" default footer */ unsigned long prior_records; /* start offset for record counters */ const printTextFormat *line_style; /* line style (NULL for default) */ + enum boolStyle bool_style; /* style of boolean output */ struct separator fieldSep; /* field separator for unaligned text mode */ struct separator recordSep; /* record separator for unaligned text mode */ bool numericLocale; /* locale-aware numeric units separator and *************** *** 133,138 **** typedef struct printTableContent --- 140,147 ---- char *aligns; /* Array of alignment specifiers; 'l' or 'r', * one per column */ char *align; /* Pointer to the last added alignment */ + Oid *ftypes; /* Array of type oids */ + Oid *ftype; /* Pointer to the last added */ } printTableContent; typedef struct printQueryOpt *************** *** 162,168 **** extern void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows); extern void printTableAddHeader(printTableContent *const content, ! char *header, const bool translate, const char align); extern void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree); extern void printTableAddFooter(printTableContent *const content, --- 171,178 ---- const printTableOpt *opt, const char *title, const int ncolumns, const int nrows); extern void printTableAddHeader(printTableContent *const content, ! char *header, const bool translate, const char align, ! const Oid ftype); extern void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree); extern void printTableAddFooter(printTableContent *const content, *** a/src/bin/psql/startup.c --- b/src/bin/psql/startup.c *************** *** 130,135 **** main(int argc, char *argv[]) --- 130,136 ---- pset.popt.topt.start_table = true; pset.popt.topt.stop_table = true; pset.popt.topt.default_footer = true; + pset.popt.topt.bool_style = PRINT_BOOL_CHAR; /* We must get COLUMNS here before readline() sets it */ pset.popt.topt.env_columns = getenv("COLUMNS") ? atoi(getenv("COLUMNS")) : 0; *** a/src/bin/psql/tab-complete.c --- b/src/bin/psql/tab-complete.c *************** *** 3091,3097 **** psql_completion(char *text, int start, int end) static const char *const my_list[] = {"format", "border", "expanded", "null", "fieldsep", "tuples_only", "title", "tableattr", ! "linestyle", "pager", "recordsep", NULL}; COMPLETE_WITH_LIST_CS(my_list); } --- 3091,3097 ---- static const char *const my_list[] = {"format", "border", "expanded", "null", "fieldsep", "tuples_only", "title", "tableattr", ! "linestyle", "pager", "recordsep", "boolstyle", NULL}; COMPLETE_WITH_LIST_CS(my_list); } *************** *** 3112,3117 **** psql_completion(char *text, int start, int end) --- 3112,3124 ---- COMPLETE_WITH_LIST_CS(my_list); } + else if (strcmp(prev_wd, "boolstyle") == 0) + { + static const char *const my_list[] = + {"char", "word", NULL}; + + COMPLETE_WITH_LIST_CS(my_list); + } } else if (strcmp(prev_wd, "\\set") == 0) {