32#include "catalog/pg_type_d.h"
38#define NEED_COUNT_TABLE_LINES
156 {
"\342\224\234",
"\342\225\237"},
163 {
"\342\224\244",
"\342\225\242"},
174 {
"\342\225\236",
"\342\225\240"},
181 {
"\342\225\241",
"\342\225\243"},
194 {
"\342\224\274",
"\342\225\252"},
201 {
"\342\224\264",
"\342\225\247"},
208 {
"\342\224\254",
"\342\225\244"},
219 {
"\342\225\253",
"\342\225\254"},
226 {
"\342\225\250",
"\342\225\251"},
233 {
"\342\225\245",
"\342\225\246"},
246 {
"\342\224\224",
"\342\224\202",
"\342\224\214",
"\342\224\200",
"\342\224\220",
"\342\224\230"},
257 {
"\342\225\232",
"\342\225\221",
"\342\225\224",
"\342\225\220",
"\342\225\227",
"\342\225\235"},
282#ifdef NEED_COUNT_TABLE_LINES
397 if (
sep.separator_zero)
399 else if (
sep.separator)
428 return cont->footers;
442 const char *
const *ptr;
448 if (
cont->opt->start_table)
460 for (ptr =
cont->headers; *ptr; ptr++)
462 if (ptr !=
cont->headers)
474 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
485 if ((
i + 1) %
cont->ncolumns)
492 if (
cont->opt->stop_table)
500 for (f = footers; f; f = f->
next)
519 if (
cont->opt->recordSep.separator_zero)
533 const char *
const *ptr;
539 if (
cont->opt->start_table)
553 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
569 if ((
i + 1) %
cont->ncolumns)
575 if (
cont->opt->stop_table)
583 for (f =
cont->footers; f; f = f->
next)
593 if (
cont->opt->recordSep.separator_zero)
620 else if (border == 2)
623 for (
i = 0;
i < ncolumns;
i++)
628 if (
i < ncolumns - 1)
640 else if (border == 1)
676 const char *
const *ptr;
692 if (
cont->ncolumns > 0)
816 if (
cont->opt->columns > 0)
818 else if ((
fout == stdout && isatty(fileno(stdout))) ||
is_pager)
820 if (
cont->opt->env_columns > 0)
913 if (
cont->opt->start_table)
956 for (
i = 0;
i <
cont->ncolumns;
i++)
962 (!
format->wrap_right_border &&
i > 0))
1078 if (
cont->aligns[
j] ==
'r')
1121 if (
cont->aligns[
j] !=
'r')
1159 if (
cont->opt->stop_table)
1172 for (f = footers; f; f = f->
next)
1206 unsigned long record,
1312 unsigned long record =
cont->opt->prior_records + 1;
1313 const char *
const *
ptr;
1339 if (
cont->cells[0] ==
NULL &&
cont->opt->start_table &&
1340 cont->opt->stop_table)
1348 for (f = footers; f; f = f->
next)
1358 for (
i = 0;
i <
cont->ncolumns;
i++)
1385 &
width, &height, &fs);
1410 if (
cont->opt->columns > 0)
1412 else if ((
fout == stdout && isatty(fileno(stdout))) ||
is_pager)
1414 if (
cont->opt->env_columns > 0)
1482 if (
cont->nrows > 0)
1572 for (
int j = 0;
j <
cont->ncolumns;
j++)
1582 if (
cont->opt->start_table)
1590 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
1609 if (
i %
cont->ncolumns == 0)
1718 else if (
dline == 0)
1807 if (
cont->opt->stop_table)
1820 for (f =
cont->footers; f; f = f->
next)
1848 for (p =
str; *p; p++)
1876 sep ==
'\\' ||
sep ==
'.')
1885 const char *
const *ptr;
1899 if (
cont->opt->start_table && !
cont->opt->tuples_only)
1902 for (ptr =
cont->headers; *ptr; ptr++)
1904 if (ptr !=
cont->headers)
1912 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
1915 if ((
i + 1) %
cont->ncolumns)
1925 const char *
const *ptr;
1929 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
1936 cont->opt->csvFieldSep[0]);
1960 for (p = in; *p; p++)
2002 const char *
const *ptr;
2007 if (
cont->opt->start_table)
2026 for (ptr =
cont->headers; *ptr; ptr++)
2037 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2039 if (
i %
cont->ncolumns == 0)
2046 fprintf(
fout,
" <td align=\"%s\">",
cont->aligns[(
i) %
cont->ncolumns] ==
'r' ?
"right" :
"left");
2048 if ((*ptr)[
strspn(*ptr,
" \t")] ==
'\0')
2055 if ((
i + 1) %
cont->ncolumns == 0)
2059 if (
cont->opt->stop_table)
2071 for (f = footers; f; f = f->
next)
2090 unsigned long record =
cont->opt->prior_records + 1;
2092 const char *
const *ptr;
2097 if (
cont->opt->start_table)
2114 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2116 if (
i %
cont->ncolumns == 0)
2122 "\n <tr><td colspan=\"2\" align=\"center\">Record %lu</td></tr>\n",
2125 fputs(
"\n <tr><td colspan=\"2\"> </td></tr>\n",
fout);
2127 fputs(
" <tr valign=\"top\">\n"
2132 fprintf(
fout,
" <td align=\"%s\">",
cont->aligns[
i %
cont->ncolumns] ==
'r' ?
"right" :
"left");
2134 if ((*ptr)[
strspn(*ptr,
" \t")] ==
'\0')
2142 if (
cont->opt->stop_table)
2152 for (f =
cont->footers; f; f = f->
next)
2175 for (p = in; *p; p++)
2194 const char *
const *ptr;
2199 if (
cont->opt->start_table)
2214 for (
i = 0;
i <
cont->ncolumns;
i++)
2224 fputs(
",frame=\"none\",grid=\"none\"",
fout);
2230 fputs(
",frame=\"all\",grid=\"all\"",
fout);
2239 for (ptr =
cont->headers; *ptr; ptr++)
2241 if (ptr !=
cont->headers)
2251 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2253 if (
i %
cont->ncolumns == 0)
2259 if (
i %
cont->ncolumns != 0)
2264 if ((*ptr)[
strspn(*ptr,
" \t")] ==
'\0')
2266 if ((
i + 1) %
cont->ncolumns != 0)
2272 if ((
i + 1) %
cont->ncolumns == 0)
2278 if (
cont->opt->stop_table)
2288 for (f = footers; f; f = f->
next)
2303 unsigned long record =
cont->opt->prior_records + 1;
2305 const char *
const *ptr;
2310 if (
cont->opt->start_table)
2328 fputs(
",frame=\"none\",grid=\"none\"",
fout);
2334 fputs(
",frame=\"all\",grid=\"all\"",
fout);
2342 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2344 if (
i %
cont->ncolumns == 0)
2361 if ((*ptr)[
strspn(*ptr,
" \t")] ==
'\0')
2370 if (
cont->opt->stop_table)
2378 for (f =
cont->footers; f; f = f->
next)
2399 for (p = in; *p; p++)
2462 const char *
const *ptr;
2470 if (
cont->opt->start_table)
2485 for (
i = 0;
i <
cont->ncolumns;
i++)
2502 for (
i = 0, ptr =
cont->headers;
i <
cont->ncolumns;
i++, ptr++)
2516 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2520 if ((
i + 1) %
cont->ncolumns == 0)
2532 if (
cont->opt->stop_table)
2539 fputs(
"\\end{tabular}\n\n\\noindent ",
fout);
2546 for (f = footers; f; f = f->
next)
2572 const char *
const *ptr;
2580 if (
cont->opt->start_table)
2588 for (
i = 0;
i <
cont->ncolumns;
i++)
2594#define LONGTABLE_WHITESPACE " \t\n"
2639 for (
i = 0, ptr =
cont->headers;
i <
cont->ncolumns;
i++, ptr++)
2643 fputs(
"\\small\\textbf{\\textit{",
fout);
2648 fputs(
"\\midrule\n\\endfirsthead\n",
fout);
2653 for (
i = 0, ptr =
cont->headers;
i <
cont->ncolumns;
i++, ptr++)
2657 fputs(
"\\small\\textbf{\\textit{",
fout);
2689 fputs(
"\\bottomrule\n\\endfoot\n",
fout);
2690 fputs(
"\\bottomrule\n\\endlastfoot\n",
fout);
2696 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2699 if (
i != 0 &&
i %
cont->ncolumns != 0)
2704 if ((
i + 1) %
cont->ncolumns == 0)
2714 if (
cont->opt->stop_table)
2724 unsigned long record =
cont->opt->prior_records + 1;
2726 const char *
const *ptr;
2734 if (
cont->opt->start_table)
2756 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2759 if (
i %
cont->ncolumns == 0)
2768 fprintf(
fout,
"\\multicolumn{2}{|c|}{\\textit{Record %lu}} \\\\\n", record++);
2771 fprintf(
fout,
"\\multicolumn{2}{c}{\\textit{Record %lu}} \\\\\n", record++);
2783 if (
cont->opt->stop_table)
2788 fputs(
"\\end{tabular}\n\n\\noindent ",
fout);
2795 for (f =
cont->footers; f; f = f->
next)
2817 for (p = in; *p; p++)
2835 const char *
const *ptr;
2843 if (
cont->opt->start_table)
2860 for (
i = 0;
i <
cont->ncolumns;
i++)
2871 for (
i = 0, ptr =
cont->headers;
i <
cont->ncolumns;
i++, ptr++)
2884 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2888 if ((
i + 1) %
cont->ncolumns == 0)
2898 if (
cont->opt->stop_table)
2909 for (f = footers; f; f = f->
next)
2926 unsigned long record =
cont->opt->prior_records + 1;
2928 const char *
const *ptr;
2937 if (
cont->opt->start_table)
2962 for (
i = 0, ptr =
cont->cells; *ptr;
i++, ptr++)
2965 if (
i %
cont->ncolumns == 0)
3007 if (
cont->opt->stop_table)
3016 for (f =
cont->footers; f; f = f->
next)
3114 if (topt && topt->
pager && isatty(fileno(
stdin)) && isatty(fileno(stdout)))
3118 unsigned short int pager = topt->
pager;
3210 const char *title,
const int ncolumns,
const int nrows)
3215 content->
title = title;
3217 content->
nrows = nrows;
3225 fprintf(
stderr,
_(
"Cannot print table contents: number of cells %" PRIu64 " is equal to or exceeds maximum %zu.\n"),
3267 "column count of %d exceeded.\n"),
3280 *content->
align = align;
3309 fprintf(
stderr,
_(
"Cannot add cell to table content: total cell count of %" PRIu64 " exceeded.\n"),
3452 if (*
fout == stdout)
3479#ifdef NEED_COUNT_TABLE_LINES
3492 const char *
const *cell;
3499 for (
i = 0;
i <
cont->ncolumns;
i++)
3510 switch (
cont->opt->format)
3519 lines = vertical ?
cont->nrows : 1;
3530 lines =
Max(
cont->nrows - 1, 0);
3546 lines = vertical ?
cont->nrows : 1;
3555 for (
i = 0, cell =
cont->cells; *cell; cell++)
3583 if (++
i >=
cont->ncolumns)
3615 for (
i = 0;
i <
cont->ncolumns;
i++)
3678 switch (
cont->opt->format)
3681 if (
cont->opt->expanded == 1)
3694 if (
cont->opt->expanded == 1 ||
3701 if (
cont->opt->expanded == 1)
3707 if (
cont->opt->expanded == 1)
3713 if (
cont->opt->expanded == 1)
3719 if (
cont->opt->expanded == 1)
3725 if (
cont->opt->expanded == 1)
3731 if (
cont->opt->expanded == 1)
3778 for (
i = 0;
i <
cont.ncolumns;
i++)
3786 for (r = 0; r <
cont.nrows; r++)
3788 for (
c = 0;
c <
cont.ncolumns;
c++)
3820 for (footer = opt->
footers; *footer; footer++)
3915 popt->
name =
"unicode";
static void cleanup(void)
#define unconstify(underlying_type, expr)
#define ngettext(s, p, n)
#define Assert(condition)
#define fprintf(file, fmt, msg)
Oid PQftype(const PGresult *res, int field_num)
int PQmblen(const char *s, int encoding)
int PQdsplen(const char *s, int encoding)
void * pg_malloc(size_t size)
char * pg_strdup(const char *in)
#define pg_malloc_array(type, count)
#define pg_malloc0_object(type)
#define pg_malloc0_array(type, count)
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
static void asciidoc_escaped_print(const char *in, FILE *fout)
static void csv_print_field(const char *str, FILE *fout, char sep)
void printTableCleanup(printTableContent *const content)
void restore_sigpipe_trap(void)
static void print_asciidoc_text(const printTableContent *cont, FILE *fout)
static char default_footer[100]
static void print_aligned_vertical_line(const printTableOpt *topt, unsigned long record, unsigned int hwidth, unsigned int dwidth, int output_columns, printTextRule pos, FILE *fout)
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
static printTableFooter default_footer_cell
static void print_unaligned_vertical(const printTableContent *cont, FILE *fout)
static int additional_numeric_locale_len(const char *my_str)
const printTextFormat * get_line_style(const printTableOpt *opt)
static printTableFooter * footers_with_default(const printTableContent *cont)
#define LONGTABLE_WHITESPACE
FILE * PageOutput(int lines, const printTableOpt *topt)
void refresh_utf8format(const printTableOpt *opt)
static void print_latex_text(const printTableContent *cont, FILE *fout)
char column_type_alignment(Oid ftype)
static void IsPagerNeeded(const printTableContent *cont, const unsigned int *width_wrap, bool vertical, FILE **fout, bool *is_pager)
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
static void print_troff_ms_text(const printTableContent *cont, FILE *fout)
static void print_separator(struct separator sep, FILE *fout)
const printTextFormat pg_asciiformat
void printTableSetFooter(printTableContent *const content, const char *footer)
static void latex_escaped_print(const char *in, FILE *fout)
static char * thousands_sep
static void print_html_text(const printTableContent *cont, FILE *fout)
static void print_troff_ms_vertical(const printTableContent *cont, FILE *fout)
void ClosePager(FILE *pagerpipe)
static void print_csv_text(const printTableContent *cont, FILE *fout)
static void print_aligned_text(const printTableContent *cont, FILE *fout, bool is_pager)
static void print_csv_vertical(const printTableContent *cont, FILE *fout)
const printTextFormat pg_asciiformat_old
static FILE * PageOutputInternal(int lines, const printTableOpt *topt, const printTableContent *cont, const unsigned int *width_wrap, bool vertical)
static bool always_ignore_sigpipe
static void print_html_vertical(const printTableContent *cont, FILE *fout)
void disable_sigpipe_trap(void)
static void csv_escaped_print(const char *str, FILE *fout)
static char * format_numeric_locale(const char *my_str)
static char * decimal_point
static int strlen_max_width(unsigned char *str, int *target_width, int encoding)
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
static int integer_digits(const char *my_str)
static void print_asciidoc_vertical(const printTableContent *cont, FILE *fout)
static void print_unaligned_text(const printTableContent *cont, FILE *fout)
static void print_latex_vertical(const printTableContent *cont, FILE *fout)
void html_escaped_print(const char *in, FILE *fout)
void printTableAddFooter(printTableContent *const content, const char *footer)
static void troff_ms_escaped_print(const char *in, FILE *fout)
void set_sigpipe_trap_state(bool ignore)
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
static const unicodeStyleFormat unicode_style
printTextFormat pg_utf8format
static void print_latex_longtable_text(const printTableContent *cont, FILE *fout)
static void print_aligned_vertical(const printTableContent *cont, FILE *fout, bool is_pager)
static void _print_horizontal_line(const unsigned int ncolumns, const unsigned int *widths, unsigned short border, printTextRule pos, const printTextFormat *format, FILE *fout)
volatile sig_atomic_t cancel_pressed
void setDecimalLocale(void)
@ PRINT_XHEADER_EXACT_WIDTH
@ PRINT_LINE_WRAP_NEWLINE
void pg_wcssize(const unsigned char *pwcs, size_t len, int encoding, int *result_width, int *result_height, int *result_format_size)
void pg_wcsformat(const unsigned char *pwcs, size_t len, int encoding, struct lineptr *lines, int count)
unsigned char * mbvalidate(unsigned char *pwcs, int encoding)
Datum translate(PG_FUNCTION_ARGS)
const bool * translate_columns
const printTableOpt * opt
printTableFooter * footers
printTableFooter * footer
unicode_linestyle unicode_border_linestyle
int expanded_header_exact_width
printXheaderWidthType expanded_header_width_type
const printTextFormat * line_style
unsigned short int border
unicode_linestyle unicode_header_linestyle
unicode_linestyle unicode_column_linestyle
const char * midvrule_blank
const char * header_nl_left
printTextLineFormat lrule[4]
const char * midvrule_wrap
const char * header_nl_right