PostgreSQL Source Code  git master
fe-print.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * fe-print.c
4  * functions for pretty-printing query results
5  *
6  * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
7  * Portions Copyright (c) 1994, Regents of the University of California
8  *
9  * These functions were formerly part of fe-exec.c, but they
10  * didn't really belong there.
11  *
12  * IDENTIFICATION
13  * src/interfaces/libpq/fe-print.c
14  *
15  *-------------------------------------------------------------------------
16  */
17 #include "postgres_fe.h"
18 
19 #include <signal.h>
20 
21 #ifdef WIN32
22 #include "win32.h"
23 #else
24 #include <unistd.h>
25 #include <sys/ioctl.h>
26 #endif
27 
28 #ifdef HAVE_TERMIOS_H
29 #include <termios.h>
30 #else
31 #ifndef WIN32
32 #include <sys/termios.h>
33 #endif
34 #endif
35 
36 #include "libpq-fe.h"
37 #include "libpq-int.h"
38 
39 
40 static bool do_field(const PQprintOpt *po, const PGresult *res,
41  const int i, const int j, const int fs_len,
42  char **fields,
43  const int nFields, const char **fieldNames,
44  unsigned char *fieldNotNum, int *fieldMax,
45  const int fieldMaxLen, FILE *fout);
46 static char *do_header(FILE *fout, const PQprintOpt *po, const int nFields,
47  int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum,
48  const int fs_len, const PGresult *res);
49 static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
50  unsigned char *fieldNotNum, int *fieldMax, char *border,
51  const int row_index);
52 static void fill(int length, int max, char filler, FILE *fp);
53 
54 /*
55  * PQprint()
56  *
57  * Format results of a query for printing.
58  *
59  * PQprintOpt is a typedef (structure) that contains
60  * various flags and options. consult libpq-fe.h for
61  * details
62  *
63  * This function should probably be removed sometime since psql
64  * doesn't use it anymore. It is unclear to what extent this is used
65  * by external clients, however.
66  */
67 void
68 PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
69 {
70  int nFields;
71 
72  nFields = PQnfields(res);
73 
74  if (nFields > 0)
75  { /* only print rows with at least 1 field. */
76  int i,
77  j;
78  int nTups;
79  int *fieldMax = NULL; /* in case we don't use them */
80  unsigned char *fieldNotNum = NULL;
81  char *border = NULL;
82  char **fields = NULL;
83  const char **fieldNames = NULL;
84  int fieldMaxLen = 0;
85  int numFieldName;
86  int fs_len = strlen(po->fieldSep);
87  int total_line_length = 0;
88  bool usePipe = false;
89  char *pagerenv;
90 
91 #if !defined(WIN32)
92  sigset_t osigset;
93  bool sigpipe_masked = false;
94  bool sigpipe_pending;
95 #endif
96 
97 #ifdef TIOCGWINSZ
98  struct winsize screen_size;
99 #else
100  struct winsize
101  {
102  int ws_row;
103  int ws_col;
104  } screen_size;
105 #endif
106 
107  nTups = PQntuples(res);
108  fieldNames = (const char **) calloc(nFields, sizeof(char *));
109  fieldNotNum = (unsigned char *) calloc(nFields, 1);
110  fieldMax = (int *) calloc(nFields, sizeof(int));
111  if (!fieldNames || !fieldNotNum || !fieldMax)
112  {
113  fprintf(stderr, libpq_gettext("out of memory\n"));
114  goto exit;
115  }
116  for (numFieldName = 0;
117  po->fieldName && po->fieldName[numFieldName];
118  numFieldName++)
119  ;
120  for (j = 0; j < nFields; j++)
121  {
122  int len;
123  const char *s = (j < numFieldName && po->fieldName[j][0]) ?
124  po->fieldName[j] : PQfname(res, j);
125 
126  fieldNames[j] = s;
127  len = s ? strlen(s) : 0;
128  fieldMax[j] = len;
129  len += fs_len;
130  if (len > fieldMaxLen)
131  fieldMaxLen = len;
132  total_line_length += len;
133  }
134 
135  total_line_length += nFields * strlen(po->fieldSep) + 1;
136 
137  if (fout == NULL)
138  fout = stdout;
139  if (po->pager && fout == stdout && isatty(fileno(stdin)) &&
140  isatty(fileno(stdout)))
141  {
142  /*
143  * If we think there'll be more than one screen of output, try to
144  * pipe to the pager program.
145  */
146 #ifdef TIOCGWINSZ
147  if (ioctl(fileno(stdout), TIOCGWINSZ, &screen_size) == -1 ||
148  screen_size.ws_col == 0 ||
149  screen_size.ws_row == 0)
150  {
151  screen_size.ws_row = 24;
152  screen_size.ws_col = 80;
153  }
154 #else
155  screen_size.ws_row = 24;
156  screen_size.ws_col = 80;
157 #endif
158 
159  /*
160  * Since this function is no longer used by psql, we don't examine
161  * PSQL_PAGER. It's possible that the hypothetical external users
162  * of the function would like that to happen, but in the name of
163  * backwards compatibility, we'll stick to just examining PAGER.
164  */
165  pagerenv = getenv("PAGER");
166  /* if PAGER is unset, empty or all-white-space, don't use pager */
167  if (pagerenv != NULL &&
168  strspn(pagerenv, " \t\r\n") != strlen(pagerenv) &&
169  !po->html3 &&
170  ((po->expanded &&
171  nTups * (nFields + 1) >= screen_size.ws_row) ||
172  (!po->expanded &&
173  nTups * (total_line_length / screen_size.ws_col + 1) *
174  (1 + (po->standard != 0)) >= screen_size.ws_row -
175  (po->header != 0) *
176  (total_line_length / screen_size.ws_col + 1) * 2
177  - (po->header != 0) * 2 /* row count and newline */
178  )))
179  {
180  fflush(NULL);
181  fout = popen(pagerenv, "w");
182  if (fout)
183  {
184  usePipe = true;
185 #ifndef WIN32
186  if (pq_block_sigpipe(&osigset, &sigpipe_pending) == 0)
187  sigpipe_masked = true;
188 #endif /* WIN32 */
189  }
190  else
191  fout = stdout;
192  }
193  }
194 
195  if (!po->expanded && (po->align || po->html3))
196  {
197  fields = (char **) calloc((size_t) nTups + 1,
198  nFields * sizeof(char *));
199  if (!fields)
200  {
201  fprintf(stderr, libpq_gettext("out of memory\n"));
202  goto exit;
203  }
204  }
205  else if (po->header && !po->html3)
206  {
207  if (po->expanded)
208  {
209  if (po->align)
210  fprintf(fout, libpq_gettext("%-*s%s Value\n"),
211  fieldMaxLen - fs_len, libpq_gettext("Field"), po->fieldSep);
212  else
213  fprintf(fout, libpq_gettext("%s%sValue\n"), libpq_gettext("Field"), po->fieldSep);
214  }
215  else
216  {
217  int len = 0;
218 
219  for (j = 0; j < nFields; j++)
220  {
221  const char *s = fieldNames[j];
222 
223  fputs(s, fout);
224  len += strlen(s) + fs_len;
225  if ((j + 1) < nFields)
226  fputs(po->fieldSep, fout);
227  }
228  fputc('\n', fout);
229  for (len -= fs_len; len--; fputc('-', fout));
230  fputc('\n', fout);
231  }
232  }
233  if (po->expanded && po->html3)
234  {
235  if (po->caption)
236  fprintf(fout, "<center><h2>%s</h2></center>\n", po->caption);
237  else
238  fprintf(fout,
239  "<center><h2>"
240  "Query retrieved %d rows * %d fields"
241  "</h2></center>\n",
242  nTups, nFields);
243  }
244  for (i = 0; i < nTups; i++)
245  {
246  if (po->expanded)
247  {
248  if (po->html3)
249  fprintf(fout,
250  "<table %s><caption align=\"top\">%d</caption>\n",
251  po->tableOpt ? po->tableOpt : "", i);
252  else
253  fprintf(fout, libpq_gettext("-- RECORD %d --\n"), i);
254  }
255  for (j = 0; j < nFields; j++)
256  {
257  if (!do_field(po, res, i, j, fs_len, fields, nFields,
258  fieldNames, fieldNotNum,
259  fieldMax, fieldMaxLen, fout))
260  goto exit;
261  }
262  if (po->html3 && po->expanded)
263  fputs("</table>\n", fout);
264  }
265  if (!po->expanded && (po->align || po->html3))
266  {
267  if (po->html3)
268  {
269  if (po->header)
270  {
271  if (po->caption)
272  fprintf(fout,
273  "<table %s><caption align=\"top\">%s</caption>\n",
274  po->tableOpt ? po->tableOpt : "",
275  po->caption);
276  else
277  fprintf(fout,
278  "<table %s><caption align=\"top\">"
279  "Retrieved %d rows * %d fields"
280  "</caption>\n",
281  po->tableOpt ? po->tableOpt : "", nTups, nFields);
282  }
283  else
284  fprintf(fout, "<table %s>", po->tableOpt ? po->tableOpt : "");
285  }
286  if (po->header)
287  border = do_header(fout, po, nFields, fieldMax, fieldNames,
288  fieldNotNum, fs_len, res);
289  for (i = 0; i < nTups; i++)
290  output_row(fout, po, nFields, fields,
291  fieldNotNum, fieldMax, border, i);
292  }
293  if (po->header && !po->html3)
294  fprintf(fout, "(%d row%s)\n\n", PQntuples(res),
295  (PQntuples(res) == 1) ? "" : "s");
296  if (po->html3 && !po->expanded)
297  fputs("</table>\n", fout);
298 
299 exit:
300  free(fieldMax);
301  free(fieldNotNum);
302  free(border);
303  if (fields)
304  {
305  /* if calloc succeeded, this shouldn't overflow size_t */
306  size_t numfields = ((size_t) nTups + 1) * (size_t) nFields;
307 
308  while (numfields-- > 0)
309  free(fields[numfields]);
310  free(fields);
311  }
312  free(fieldNames);
313  if (usePipe)
314  {
315 #ifdef WIN32
316  _pclose(fout);
317 #else
318  pclose(fout);
319 
320  /* we can't easily verify if EPIPE occurred, so say it did */
321  if (sigpipe_masked)
322  pq_reset_sigpipe(&osigset, sigpipe_pending, true);
323 #endif /* WIN32 */
324  }
325  }
326 }
327 
328 
329 static bool
330 do_field(const PQprintOpt *po, const PGresult *res,
331  const int i, const int j, const int fs_len,
332  char **fields,
333  const int nFields, char const **fieldNames,
334  unsigned char *fieldNotNum, int *fieldMax,
335  const int fieldMaxLen, FILE *fout)
336 {
337  const char *pval,
338  *p;
339  int plen;
340  bool skipit;
341 
342  plen = PQgetlength(res, i, j);
343  pval = PQgetvalue(res, i, j);
344 
345  if (plen < 1 || !pval || !*pval)
346  {
347  if (po->align || po->expanded)
348  skipit = true;
349  else
350  {
351  skipit = false;
352  goto efield;
353  }
354  }
355  else
356  skipit = false;
357 
358  if (!skipit)
359  {
360  if (po->align && !fieldNotNum[j])
361  {
362  /* Detect whether field contains non-numeric data */
363  char ch = '0';
364 
365  for (p = pval; *p; p += PQmblenBounded(p, res->client_encoding))
366  {
367  ch = *p;
368  if (!((ch >= '0' && ch <= '9') ||
369  ch == '.' ||
370  ch == 'E' ||
371  ch == 'e' ||
372  ch == ' ' ||
373  ch == '-'))
374  {
375  fieldNotNum[j] = 1;
376  break;
377  }
378  }
379 
380  /*
381  * Above loop will believe E in first column is numeric; also, we
382  * insist on a digit in the last column for a numeric. This test
383  * is still not bulletproof but it handles most cases.
384  */
385  if (*pval == 'E' || *pval == 'e' ||
386  !(ch >= '0' && ch <= '9'))
387  fieldNotNum[j] = 1;
388  }
389 
390  if (!po->expanded && (po->align || po->html3))
391  {
392  if (plen > fieldMax[j])
393  fieldMax[j] = plen;
394  if (!(fields[i * nFields + j] = (char *) malloc(plen + 1)))
395  {
396  fprintf(stderr, libpq_gettext("out of memory\n"));
397  return false;
398  }
399  strcpy(fields[i * nFields + j], pval);
400  }
401  else
402  {
403  if (po->expanded)
404  {
405  if (po->html3)
406  fprintf(fout,
407  "<tr><td align=\"left\"><b>%s</b></td>"
408  "<td align=\"%s\">%s</td></tr>\n",
409  fieldNames[j],
410  fieldNotNum[j] ? "left" : "right",
411  pval);
412  else
413  {
414  if (po->align)
415  fprintf(fout,
416  "%-*s%s %s\n",
417  fieldMaxLen - fs_len, fieldNames[j],
418  po->fieldSep,
419  pval);
420  else
421  fprintf(fout,
422  "%s%s%s\n",
423  fieldNames[j], po->fieldSep, pval);
424  }
425  }
426  else
427  {
428  if (!po->html3)
429  {
430  fputs(pval, fout);
431  efield:
432  if ((j + 1) < nFields)
433  fputs(po->fieldSep, fout);
434  else
435  fputc('\n', fout);
436  }
437  }
438  }
439  }
440  return true;
441 }
442 
443 
444 static char *
445 do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
446  const char **fieldNames, unsigned char *fieldNotNum,
447  const int fs_len, const PGresult *res)
448 {
449  int j; /* for loop index */
450  char *border = NULL;
451 
452  if (po->html3)
453  fputs("<tr>", fout);
454  else
455  {
456  int tot = 0;
457  int n = 0;
458  char *p = NULL;
459 
460  for (; n < nFields; n++)
461  tot += fieldMax[n] + fs_len + (po->standard ? 2 : 0);
462  if (po->standard)
463  tot += fs_len * 2 + 2;
464  border = malloc(tot + 1);
465  if (!border)
466  {
467  fprintf(stderr, libpq_gettext("out of memory\n"));
468  return NULL;
469  }
470  p = border;
471  if (po->standard)
472  {
473  char *fs = po->fieldSep;
474 
475  while (*fs++)
476  *p++ = '+';
477  }
478  for (j = 0; j < nFields; j++)
479  {
480  int len;
481 
482  for (len = fieldMax[j] + (po->standard ? 2 : 0); len--; *p++ = '-');
483  if (po->standard || (j + 1) < nFields)
484  {
485  char *fs = po->fieldSep;
486 
487  while (*fs++)
488  *p++ = '+';
489  }
490  }
491  *p = '\0';
492  if (po->standard)
493  fprintf(fout, "%s\n", border);
494  }
495  if (po->standard)
496  fputs(po->fieldSep, fout);
497  for (j = 0; j < nFields; j++)
498  {
499  const char *s = PQfname(res, j);
500 
501  if (po->html3)
502  {
503  fprintf(fout, "<th align=\"%s\">%s</th>",
504  fieldNotNum[j] ? "left" : "right", fieldNames[j]);
505  }
506  else
507  {
508  int n = strlen(s);
509 
510  if (n > fieldMax[j])
511  fieldMax[j] = n;
512  if (po->standard)
513  fprintf(fout,
514  fieldNotNum[j] ? " %-*s " : " %*s ",
515  fieldMax[j], s);
516  else
517  fprintf(fout, fieldNotNum[j] ? "%-*s" : "%*s", fieldMax[j], s);
518  if (po->standard || (j + 1) < nFields)
519  fputs(po->fieldSep, fout);
520  }
521  }
522  if (po->html3)
523  fputs("</tr>\n", fout);
524  else
525  fprintf(fout, "\n%s\n", border);
526  return border;
527 }
528 
529 
530 static void
531 output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
532  unsigned char *fieldNotNum, int *fieldMax, char *border,
533  const int row_index)
534 {
535  int field_index; /* for loop index */
536 
537  if (po->html3)
538  fputs("<tr>", fout);
539  else if (po->standard)
540  fputs(po->fieldSep, fout);
541  for (field_index = 0; field_index < nFields; field_index++)
542  {
543  char *p = fields[row_index * nFields + field_index];
544 
545  if (po->html3)
546  fprintf(fout, "<td align=\"%s\">%s</td>",
547  fieldNotNum[field_index] ? "left" : "right", p ? p : "");
548  else
549  {
550  fprintf(fout,
551  fieldNotNum[field_index] ?
552  (po->standard ? " %-*s " : "%-*s") :
553  (po->standard ? " %*s " : "%*s"),
554  fieldMax[field_index],
555  p ? p : "");
556  if (po->standard || field_index + 1 < nFields)
557  fputs(po->fieldSep, fout);
558  }
559  }
560  if (po->html3)
561  fputs("</tr>", fout);
562  else if (po->standard)
563  fprintf(fout, "\n%s", border);
564  fputc('\n', fout);
565 }
566 
567 
568 
569 /*
570  * really old printing routines
571  */
572 
573 void
575  FILE *fp, /* where to send the output */
576  int fillAlign, /* pad the fields with spaces */
577  const char *fieldSep, /* field separator */
578  int printHeader, /* display headers? */
579  int quiet
580 )
581 {
582 #define DEFAULT_FIELD_SEP " "
583 
584  int i,
585  j;
586  int nFields;
587  int nTuples;
588  int *fLength = NULL;
589 
590  if (fieldSep == NULL)
591  fieldSep = DEFAULT_FIELD_SEP;
592 
593  /* Get some useful info about the results */
594  nFields = PQnfields(res);
595  nTuples = PQntuples(res);
596 
597  if (fp == NULL)
598  fp = stdout;
599 
600  /* Figure the field lengths to align to */
601  /* will be somewhat time consuming for very large results */
602  if (fillAlign)
603  {
604  fLength = (int *) malloc(nFields * sizeof(int));
605  if (!fLength)
606  {
607  fprintf(stderr, libpq_gettext("out of memory\n"));
608  return;
609  }
610 
611  for (j = 0; j < nFields; j++)
612  {
613  fLength[j] = strlen(PQfname(res, j));
614  for (i = 0; i < nTuples; i++)
615  {
616  int flen = PQgetlength(res, i, j);
617 
618  if (flen > fLength[j])
619  fLength[j] = flen;
620  }
621  }
622  }
623 
624  if (printHeader)
625  {
626  /* first, print out the attribute names */
627  for (i = 0; i < nFields; i++)
628  {
629  fputs(PQfname(res, i), fp);
630  if (fillAlign)
631  fill(strlen(PQfname(res, i)), fLength[i], ' ', fp);
632  fputs(fieldSep, fp);
633  }
634  fprintf(fp, "\n");
635 
636  /* Underline the attribute names */
637  for (i = 0; i < nFields; i++)
638  {
639  if (fillAlign)
640  fill(0, fLength[i], '-', fp);
641  fputs(fieldSep, fp);
642  }
643  fprintf(fp, "\n");
644  }
645 
646  /* next, print out the instances */
647  for (i = 0; i < nTuples; i++)
648  {
649  for (j = 0; j < nFields; j++)
650  {
651  fprintf(fp, "%s", PQgetvalue(res, i, j));
652  if (fillAlign)
653  fill(strlen(PQgetvalue(res, i, j)), fLength[j], ' ', fp);
654  fputs(fieldSep, fp);
655  }
656  fprintf(fp, "\n");
657  }
658 
659  if (!quiet)
660  fprintf(fp, "\nQuery returned %d row%s.\n", PQntuples(res),
661  (PQntuples(res) == 1) ? "" : "s");
662 
663  fflush(fp);
664 
665  free(fLength);
666 }
667 
668 
669 
670 void
672  FILE *fout, /* output stream */
673  int PrintAttNames, /* print attribute names or not */
674  int TerseOutput, /* delimiter bars or not? */
675  int colWidth /* width of column, if 0, use variable width */
676 )
677 {
678  int nFields;
679  int nTups;
680  int i,
681  j;
682  char formatString[80];
683  char *tborder = NULL;
684 
685  nFields = PQnfields(res);
686  nTups = PQntuples(res);
687 
688  if (colWidth > 0)
689  sprintf(formatString, "%%s %%-%ds", colWidth);
690  else
691  sprintf(formatString, "%%s %%s");
692 
693  if (nFields > 0)
694  { /* only print rows with at least 1 field. */
695 
696  if (!TerseOutput)
697  {
698  int width;
699 
700  width = nFields * 14;
701  tborder = (char *) malloc(width + 1);
702  if (!tborder)
703  {
704  fprintf(stderr, libpq_gettext("out of memory\n"));
705  return;
706  }
707  for (i = 0; i < width; i++)
708  tborder[i] = '-';
709  tborder[width] = '\0';
710  fprintf(fout, "%s\n", tborder);
711  }
712 
713  for (i = 0; i < nFields; i++)
714  {
715  if (PrintAttNames)
716  {
717  fprintf(fout, formatString,
718  TerseOutput ? "" : "|",
719  PQfname(res, i));
720  }
721  }
722 
723  if (PrintAttNames)
724  {
725  if (TerseOutput)
726  fprintf(fout, "\n");
727  else
728  fprintf(fout, "|\n%s\n", tborder);
729  }
730 
731  for (i = 0; i < nTups; i++)
732  {
733  for (j = 0; j < nFields; j++)
734  {
735  const char *pval = PQgetvalue(res, i, j);
736 
737  fprintf(fout, formatString,
738  TerseOutput ? "" : "|",
739  pval ? pval : "");
740  }
741  if (TerseOutput)
742  fprintf(fout, "\n");
743  else
744  fprintf(fout, "|\n%s\n", tborder);
745  }
746  }
747 
748  free(tborder);
749 }
750 
751 
752 /* simply send out max-length number of filler characters to fp */
753 
754 static void
755 fill(int length, int max, char filler, FILE *fp)
756 {
757  int count;
758 
759  count = max - length;
760  while (count-- >= 0)
761  putc(filler, fp);
762 }
int PQgetlength(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3887
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
char * PQfname(const PGresult *res, int field_num)
Definition: fe-exec.c:3567
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
int PQnfields(const PGresult *res)
Definition: fe-exec.c:3489
int PQmblenBounded(const char *s, int encoding)
Definition: fe-misc.c:1234
void PQdisplayTuples(const PGresult *res, FILE *fp, int fillAlign, const char *fieldSep, int printHeader, int quiet)
Definition: fe-print.c:574
static void fill(int length, int max, char filler, FILE *fp)
Definition: fe-print.c:755
#define DEFAULT_FIELD_SEP
void PQprintTuples(const PGresult *res, FILE *fout, int PrintAttNames, int TerseOutput, int colWidth)
Definition: fe-print.c:671
void PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
Definition: fe-print.c:68
static char * do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax, const char **fieldNames, unsigned char *fieldNotNum, const int fs_len, const PGresult *res)
Definition: fe-print.c:445
static bool do_field(const PQprintOpt *po, const PGresult *res, const int i, const int j, const int fs_len, char **fields, const int nFields, const char **fieldNames, unsigned char *fieldNotNum, int *fieldMax, const int fieldMaxLen, FILE *fout)
Definition: fe-print.c:330
static void output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields, unsigned char *fieldNotNum, int *fieldMax, char *border, const int row_index)
Definition: fe-print.c:531
void pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
Definition: fe-secure.c:554
int pq_block_sigpipe(sigset_t *osigset, bool *sigpipe_pending)
Definition: fe-secure.c:504
#define calloc(a, b)
Definition: header.h:55
#define free(a)
Definition: header.h:65
#define malloc(a)
Definition: header.h:50
int j
Definition: isn.c:74
int i
Definition: isn.c:73
#define libpq_gettext(x)
Definition: libpq-int.h:905
static void const char fflush(stdout)
exit(1)
const void size_t len
#define sprintf
Definition: port.h:240
#define fprintf
Definition: port.h:242
pqbool align
Definition: libpq-fe.h:238
pqbool pager
Definition: libpq-fe.h:242
pqbool standard
Definition: libpq-fe.h:239
pqbool html3
Definition: libpq-fe.h:240
char * caption
Definition: libpq-fe.h:245
pqbool header
Definition: libpq-fe.h:237
pqbool expanded
Definition: libpq-fe.h:241
char * fieldSep
Definition: libpq-fe.h:243
char ** fieldName
Definition: libpq-fe.h:246
char * tableOpt
Definition: libpq-fe.h:244
int client_encoding
Definition: libpq-int.h:192