PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
describe.c File Reference
#include "postgres_fe.h"
#include <ctype.h>
#include "catalog/pg_default_acl.h"
#include "fe_utils/string_utils.h"
#include "common.h"
#include "describe.h"
#include "fe_utils/mbprint.h"
#include "fe_utils/print.h"
#include "settings.h"
#include "variables.h"
Include dependency graph for describe.c:

Go to the source code of this file.

Functions

static bool describeOneTableDetails (const char *schemaname, const char *relationname, const char *oid, bool verbose)
 
static void add_tablespace_footer (printTableContent *const cont, char relkind, Oid tablespace, const bool newline)
 
static void add_role_attribute (PQExpBuffer buf, const char *const str)
 
static bool listTSParsersVerbose (const char *pattern)
 
static bool describeOneTSParser (const char *oid, const char *nspname, const char *prsname)
 
static bool listTSConfigsVerbose (const char *pattern)
 
static bool describeOneTSConfig (const char *oid, const char *nspname, const char *cfgname, const char *pnspname, const char *prsname)
 
static void printACLColumn (PQExpBuffer buf, const char *colname)
 
static bool listOneExtensionContents (const char *extname, const char *oid)
 
bool describeAggregates (const char *pattern, bool verbose, bool showSystem)
 
bool describeAccessMethods (const char *pattern, bool verbose)
 
bool describeTablespaces (const char *pattern, bool verbose)
 
bool describeFunctions (const char *functypes, const char *pattern, bool verbose, bool showSystem)
 
bool describeTypes (const char *pattern, bool verbose, bool showSystem)
 
bool describeOperators (const char *pattern, bool verbose, bool showSystem)
 
bool listAllDbs (const char *pattern, bool verbose)
 
bool permissionsList (const char *pattern)
 
bool listDefaultACLs (const char *pattern)
 
bool objectDescription (const char *pattern, bool showSystem)
 
bool describeTableDetails (const char *pattern, bool verbose, bool showSystem)
 
bool describeRoles (const char *pattern, bool verbose, bool showSystem)
 
bool listDbRoleSettings (const char *pattern, const char *pattern2)
 
bool listTables (const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
 
bool listLanguages (const char *pattern, bool verbose, bool showSystem)
 
bool listDomains (const char *pattern, bool verbose, bool showSystem)
 
bool listConversions (const char *pattern, bool verbose, bool showSystem)
 
bool listEventTriggers (const char *pattern, bool verbose)
 
bool listCasts (const char *pattern, bool verbose)
 
bool listCollations (const char *pattern, bool verbose, bool showSystem)
 
bool listSchemas (const char *pattern, bool verbose, bool showSystem)
 
bool listTSParsers (const char *pattern, bool verbose)
 
bool listTSDictionaries (const char *pattern, bool verbose)
 
bool listTSTemplates (const char *pattern, bool verbose)
 
bool listTSConfigs (const char *pattern, bool verbose)
 
bool listForeignDataWrappers (const char *pattern, bool verbose)
 
bool listForeignServers (const char *pattern, bool verbose)
 
bool listUserMappings (const char *pattern, bool verbose)
 
bool listForeignTables (const char *pattern, bool verbose)
 
bool listExtensions (const char *pattern)
 
bool listExtensionContents (const char *pattern)
 
bool listPublications (const char *pattern)
 
bool describePublications (const char *pattern)
 
bool describeSubscriptions (const char *pattern, bool verbose)
 

Function Documentation

static void add_role_attribute ( PQExpBuffer  buf,
const char *const  str 
)
static

Definition at line 3055 of file describe.c.

References appendPQExpBufferStr(), and PQExpBufferData::len.

Referenced by describeRoles().

3056 {
3057  if (buf->len > 0)
3058  appendPQExpBufferStr(buf, ", ");
3059 
3060  appendPQExpBufferStr(buf, str);
3061 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
static void add_tablespace_footer ( printTableContent *const  cont,
char  relkind,
Oid  tablespace,
const bool  newline 
)
static

Definition at line 2838 of file describe.c.

References _, appendPQExpBuffer(), buf, PQExpBufferData::data, printTableFooter::data, printTableContent::footer, initPQExpBuffer(), NULL, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), printTableAddFooter(), printTableSetFooter(), PSQLexec(), and termPQExpBuffer().

Referenced by describeOneTableDetails().

2840 {
2841  /* relkinds for which we support tablespaces */
2842  if (relkind == 'r' || relkind == 'm' || relkind == 'i' || relkind == 'P')
2843  {
2844  /*
2845  * We ignore the database default tablespace so that users not using
2846  * tablespaces don't need to know about them. This case also covers
2847  * pre-8.0 servers, for which tablespace will always be 0.
2848  */
2849  if (tablespace != 0)
2850  {
2851  PGresult *result = NULL;
2853 
2854  initPQExpBuffer(&buf);
2855  printfPQExpBuffer(&buf,
2856  "SELECT spcname FROM pg_catalog.pg_tablespace\n"
2857  "WHERE oid = '%u';", tablespace);
2858  result = PSQLexec(buf.data);
2859  if (!result)
2860  return;
2861  /* Should always be the case, but.... */
2862  if (PQntuples(result) > 0)
2863  {
2864  if (newline)
2865  {
2866  /* Add the tablespace as a new footer */
2867  printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
2868  PQgetvalue(result, 0, 0));
2869  printTableAddFooter(cont, buf.data);
2870  }
2871  else
2872  {
2873  /* Append the tablespace to the latest footer */
2874  printfPQExpBuffer(&buf, "%s", cont->footer->data);
2875 
2876  /*-------
2877  translator: before this string there's an index description like
2878  '"foo_pkey" PRIMARY KEY, btree (a)' */
2879  appendPQExpBuffer(&buf, _(", tablespace \"%s\""),
2880  PQgetvalue(result, 0, 0));
2881  printTableSetFooter(cont, buf.data);
2882  }
2883  }
2884  PQclear(result);
2885  termPQExpBuffer(&buf);
2886  }
2887  }
2888 }
void printTableSetFooter(printTableContent *const content, const char *footer)
Definition: print.c:3081
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static chr newline(void)
Definition: regc_lex.c:1137
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
char * tablespace
Definition: pgbench.c:146
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
printTableFooter * footer
Definition: print.h:157
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:226
char * data
Definition: print.h:135
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeAccessMethods ( const char *  pattern,
bool  verbose 
)

Definition at line 136 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

137 {
139  PGresult *res;
140  printQueryOpt myopt = pset.popt;
141  static const bool translate_columns[] = {false, true, false, false};
142 
143  if (pset.sversion < 90600)
144  {
145  char sverbuf[32];
146 
147  psql_error("The server (version %s) does not support access methods.\n",
149  sverbuf, sizeof(sverbuf)));
150  return true;
151  }
152 
153  initPQExpBuffer(&buf);
154 
155  printfPQExpBuffer(&buf,
156  "SELECT amname AS \"%s\",\n"
157  " CASE amtype"
158  " WHEN 'i' THEN '%s'"
159  " END AS \"%s\"",
160  gettext_noop("Name"),
161  gettext_noop("Index"),
162  gettext_noop("Type"));
163 
164  if (verbose)
165  {
166  appendPQExpBuffer(&buf,
167  ",\n amhandler AS \"%s\",\n"
168  " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
169  gettext_noop("Handler"),
170  gettext_noop("Description"));
171  }
172 
174  "\nFROM pg_catalog.pg_am\n");
175 
176  processSQLNamePattern(pset.db, &buf, pattern, false, false,
177  NULL, "amname", NULL,
178  NULL);
179 
180  appendPQExpBufferStr(&buf, "ORDER BY 1;");
181 
182  res = PSQLexec(buf.data);
183  termPQExpBuffer(&buf);
184  if (!res)
185  return false;
186 
187  myopt.nullPrint = NULL;
188  myopt.title = _("List of access methods");
189  myopt.translate_header = true;
190  myopt.translate_columns = translate_columns;
191  myopt.n_translate_columns = lengthof(translate_columns);
192 
193  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
194 
195  PQclear(res);
196  return true;
197 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeAggregates ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 59 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

60 {
62  PGresult *res;
63  printQueryOpt myopt = pset.popt;
64 
65  initPQExpBuffer(&buf);
66 
67  printfPQExpBuffer(&buf,
68  "SELECT n.nspname as \"%s\",\n"
69  " p.proname AS \"%s\",\n"
70  " pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n",
71  gettext_noop("Schema"),
72  gettext_noop("Name"),
73  gettext_noop("Result data type"));
74 
75  if (pset.sversion >= 80400)
76  appendPQExpBuffer(&buf,
77  " CASE WHEN p.pronargs = 0\n"
78  " THEN CAST('*' AS pg_catalog.text)\n"
79  " ELSE pg_catalog.pg_get_function_arguments(p.oid)\n"
80  " END AS \"%s\",\n",
81  gettext_noop("Argument data types"));
82  else if (pset.sversion >= 80200)
83  appendPQExpBuffer(&buf,
84  " CASE WHEN p.pronargs = 0\n"
85  " THEN CAST('*' AS pg_catalog.text)\n"
86  " ELSE\n"
87  " pg_catalog.array_to_string(ARRAY(\n"
88  " SELECT\n"
89  " pg_catalog.format_type(p.proargtypes[s.i], NULL)\n"
90  " FROM\n"
91  " pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
92  " ), ', ')\n"
93  " END AS \"%s\",\n",
94  gettext_noop("Argument data types"));
95  else
96  appendPQExpBuffer(&buf,
97  " pg_catalog.format_type(p.proargtypes[0], NULL) AS \"%s\",\n",
98  gettext_noop("Argument data types"));
99 
100  appendPQExpBuffer(&buf,
101  " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
102  "FROM pg_catalog.pg_proc p\n"
103  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
104  "WHERE p.proisagg\n",
105  gettext_noop("Description"));
106 
107  if (!showSystem && !pattern)
108  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
109  " AND n.nspname <> 'information_schema'\n");
110 
111  processSQLNamePattern(pset.db, &buf, pattern, true, false,
112  "n.nspname", "p.proname", NULL,
113  "pg_catalog.pg_function_is_visible(p.oid)");
114 
115  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
116 
117  res = PSQLexec(buf.data);
118  termPQExpBuffer(&buf);
119  if (!res)
120  return false;
121 
122  myopt.nullPrint = NULL;
123  myopt.title = _("List of aggregate functions");
124  myopt.translate_header = true;
125 
126  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
127 
128  PQclear(res);
129  return true;
130 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeFunctions ( const char *  functypes,
const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 297 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

298 {
299  bool showAggregate = strchr(functypes, 'a') != NULL;
300  bool showNormal = strchr(functypes, 'n') != NULL;
301  bool showTrigger = strchr(functypes, 't') != NULL;
302  bool showWindow = strchr(functypes, 'w') != NULL;
303  bool have_where;
305  PGresult *res;
306  printQueryOpt myopt = pset.popt;
307  static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, false, false, false, false};
308 
309  /* No "Parallel" column before 9.6 */
310  static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, false, false, false, false};
311 
312  if (strlen(functypes) != strspn(functypes, "antwS+"))
313  {
314  psql_error("\\df only takes [antwS+] as options\n");
315  return true;
316  }
317 
318  if (showWindow && pset.sversion < 80400)
319  {
320  char sverbuf[32];
321 
322  psql_error("\\df does not take a \"w\" option with server version %s\n",
324  sverbuf, sizeof(sverbuf)));
325  return true;
326  }
327 
328  if (!showAggregate && !showNormal && !showTrigger && !showWindow)
329  {
330  showAggregate = showNormal = showTrigger = true;
331  if (pset.sversion >= 80400)
332  showWindow = true;
333  }
334 
335  initPQExpBuffer(&buf);
336 
337  printfPQExpBuffer(&buf,
338  "SELECT n.nspname as \"%s\",\n"
339  " p.proname as \"%s\",\n",
340  gettext_noop("Schema"),
341  gettext_noop("Name"));
342 
343  if (pset.sversion >= 80400)
344  appendPQExpBuffer(&buf,
345  " pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n"
346  " pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n"
347  " CASE\n"
348  " WHEN p.proisagg THEN '%s'\n"
349  " WHEN p.proiswindow THEN '%s'\n"
350  " WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s'\n"
351  " ELSE '%s'\n"
352  " END as \"%s\"",
353  gettext_noop("Result data type"),
354  gettext_noop("Argument data types"),
355  /* translator: "agg" is short for "aggregate" */
356  gettext_noop("agg"),
357  gettext_noop("window"),
358  gettext_noop("trigger"),
359  gettext_noop("normal"),
360  gettext_noop("Type"));
361  else if (pset.sversion >= 80100)
362  appendPQExpBuffer(&buf,
363  " CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
364  " pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
365  " CASE WHEN proallargtypes IS NOT NULL THEN\n"
366  " pg_catalog.array_to_string(ARRAY(\n"
367  " SELECT\n"
368  " CASE\n"
369  " WHEN p.proargmodes[s.i] = 'i' THEN ''\n"
370  " WHEN p.proargmodes[s.i] = 'o' THEN 'OUT '\n"
371  " WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT '\n"
372  " WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC '\n"
373  " END ||\n"
374  " CASE\n"
375  " WHEN COALESCE(p.proargnames[s.i], '') = '' THEN ''\n"
376  " ELSE p.proargnames[s.i] || ' ' \n"
377  " END ||\n"
378  " pg_catalog.format_type(p.proallargtypes[s.i], NULL)\n"
379  " FROM\n"
380  " pg_catalog.generate_series(1, pg_catalog.array_upper(p.proallargtypes, 1)) AS s(i)\n"
381  " ), ', ')\n"
382  " ELSE\n"
383  " pg_catalog.array_to_string(ARRAY(\n"
384  " SELECT\n"
385  " CASE\n"
386  " WHEN COALESCE(p.proargnames[s.i+1], '') = '' THEN ''\n"
387  " ELSE p.proargnames[s.i+1] || ' '\n"
388  " END ||\n"
389  " pg_catalog.format_type(p.proargtypes[s.i], NULL)\n"
390  " FROM\n"
391  " pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
392  " ), ', ')\n"
393  " END AS \"%s\",\n"
394  " CASE\n"
395  " WHEN p.proisagg THEN '%s'\n"
396  " WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s'\n"
397  " ELSE '%s'\n"
398  " END AS \"%s\"",
399  gettext_noop("Result data type"),
400  gettext_noop("Argument data types"),
401  /* translator: "agg" is short for "aggregate" */
402  gettext_noop("agg"),
403  gettext_noop("trigger"),
404  gettext_noop("normal"),
405  gettext_noop("Type"));
406  else
407  appendPQExpBuffer(&buf,
408  " CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END ||\n"
409  " pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
410  " pg_catalog.oidvectortypes(p.proargtypes) as \"%s\",\n"
411  " CASE\n"
412  " WHEN p.proisagg THEN '%s'\n"
413  " WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s'\n"
414  " ELSE '%s'\n"
415  " END AS \"%s\"",
416  gettext_noop("Result data type"),
417  gettext_noop("Argument data types"),
418  /* translator: "agg" is short for "aggregate" */
419  gettext_noop("agg"),
420  gettext_noop("trigger"),
421  gettext_noop("normal"),
422  gettext_noop("Type"));
423 
424  if (verbose)
425  {
426  appendPQExpBuffer(&buf,
427  ",\n CASE\n"
428  " WHEN p.provolatile = 'i' THEN '%s'\n"
429  " WHEN p.provolatile = 's' THEN '%s'\n"
430  " WHEN p.provolatile = 'v' THEN '%s'\n"
431  " END as \"%s\"",
432  gettext_noop("immutable"),
433  gettext_noop("stable"),
434  gettext_noop("volatile"),
435  gettext_noop("Volatility"));
436  if (pset.sversion >= 90600)
437  appendPQExpBuffer(&buf,
438  ",\n CASE\n"
439  " WHEN p.proparallel = 'r' THEN '%s'\n"
440  " WHEN p.proparallel = 's' THEN '%s'\n"
441  " WHEN p.proparallel = 'u' THEN '%s'\n"
442  " END as \"%s\"",
443  gettext_noop("restricted"),
444  gettext_noop("safe"),
445  gettext_noop("unsafe"),
446  gettext_noop("Parallel"));
447  appendPQExpBuffer(&buf,
448  ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\""
449  ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"",
450  gettext_noop("Owner"),
451  gettext_noop("definer"),
452  gettext_noop("invoker"),
453  gettext_noop("Security"));
454  appendPQExpBufferStr(&buf, ",\n ");
455  printACLColumn(&buf, "p.proacl");
456  appendPQExpBuffer(&buf,
457  ",\n l.lanname as \"%s\""
458  ",\n p.prosrc as \"%s\""
459  ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
460  gettext_noop("Language"),
461  gettext_noop("Source code"),
462  gettext_noop("Description"));
463  }
464 
466  "\nFROM pg_catalog.pg_proc p"
467  "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n");
468 
469  if (verbose)
471  " LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
472 
473  have_where = false;
474 
475  /* filter by function type, if requested */
476  if (showNormal && showAggregate && showTrigger && showWindow)
477  /* Do nothing */ ;
478  else if (showNormal)
479  {
480  if (!showAggregate)
481  {
482  if (have_where)
483  appendPQExpBufferStr(&buf, " AND ");
484  else
485  {
486  appendPQExpBufferStr(&buf, "WHERE ");
487  have_where = true;
488  }
489  appendPQExpBufferStr(&buf, "NOT p.proisagg\n");
490  }
491  if (!showTrigger)
492  {
493  if (have_where)
494  appendPQExpBufferStr(&buf, " AND ");
495  else
496  {
497  appendPQExpBufferStr(&buf, "WHERE ");
498  have_where = true;
499  }
500  appendPQExpBufferStr(&buf, "p.prorettype <> 'pg_catalog.trigger'::pg_catalog.regtype\n");
501  }
502  if (!showWindow && pset.sversion >= 80400)
503  {
504  if (have_where)
505  appendPQExpBufferStr(&buf, " AND ");
506  else
507  {
508  appendPQExpBufferStr(&buf, "WHERE ");
509  have_where = true;
510  }
511  appendPQExpBufferStr(&buf, "NOT p.proiswindow\n");
512  }
513  }
514  else
515  {
516  bool needs_or = false;
517 
518  appendPQExpBufferStr(&buf, "WHERE (\n ");
519  have_where = true;
520  /* Note: at least one of these must be true ... */
521  if (showAggregate)
522  {
523  appendPQExpBufferStr(&buf, "p.proisagg\n");
524  needs_or = true;
525  }
526  if (showTrigger)
527  {
528  if (needs_or)
529  appendPQExpBufferStr(&buf, " OR ");
531  "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n");
532  needs_or = true;
533  }
534  if (showWindow)
535  {
536  if (needs_or)
537  appendPQExpBufferStr(&buf, " OR ");
538  appendPQExpBufferStr(&buf, "p.proiswindow\n");
539  needs_or = true;
540  }
541  appendPQExpBufferStr(&buf, " )\n");
542  }
543 
544  processSQLNamePattern(pset.db, &buf, pattern, have_where, false,
545  "n.nspname", "p.proname", NULL,
546  "pg_catalog.pg_function_is_visible(p.oid)");
547 
548  if (!showSystem && !pattern)
549  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
550  " AND n.nspname <> 'information_schema'\n");
551 
552  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
553 
554  res = PSQLexec(buf.data);
555  termPQExpBuffer(&buf);
556  if (!res)
557  return false;
558 
559  myopt.nullPrint = NULL;
560  myopt.title = _("List of functions");
561  myopt.translate_header = true;
562  if (pset.sversion >= 90600)
563  {
564  myopt.translate_columns = translate_columns;
565  myopt.n_translate_columns = lengthof(translate_columns);
566  }
567  else
568  {
569  myopt.translate_columns = translate_columns_pre_96;
570  myopt.n_translate_columns = lengthof(translate_columns_pre_96);
571  }
572 
573  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
574 
575  PQclear(res);
576  return true;
577 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
static bool describeOneTableDetails ( const char *  schemaname,
const char *  relationname,
const char *  oid,
bool  verbose 
)
static

Definition at line 1349 of file describe.c.

References _, add_tablespace_footer(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), atooid, buf, PQExpBufferData::data, printTableOpt::default_footer, _psqlSettings::encoding, printTableOpt::expanded, fmtId(), free, gettext_noop, i, initPQExpBuffer(), _psqlSettings::logfile, NULL, pg_malloc(), pg_strdup(), pg_wcswidth(), _psqlSettings::popt, PQclear(), PQgetisnull(), PQgetvalue(), PQnfields(), PQntuples(), printfPQExpBuffer(), printTable(), printTableAddCell(), printTableAddFooter(), printTableAddHeader(), printTableCleanup(), printTableInit(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, resetPQExpBuffer(), _psqlSettings::sversion, tablespace, termPQExpBuffer(), tmpbuf, and printQueryOpt::topt.

Referenced by describeTableDetails().

1353 {
1355  PGresult *res = NULL;
1356  printTableOpt myopt = pset.popt.topt;
1357  printTableContent cont;
1358  bool printTableInitialized = false;
1359  int i;
1360  char *view_def = NULL;
1361  char *headers[11];
1362  char **seq_values = NULL;
1363  char **ptr;
1364  PQExpBufferData title;
1366  int cols;
1367  int numrows = 0;
1368  struct
1369  {
1370  int16 checks;
1371  char relkind;
1372  bool hasindex;
1373  bool hasrules;
1374  bool hastriggers;
1375  bool rowsecurity;
1376  bool forcerowsecurity;
1377  bool hasoids;
1378  Oid tablespace;
1379  char *reloptions;
1380  char *reloftype;
1381  char relpersistence;
1382  char relreplident;
1383  } tableinfo;
1384  bool show_column_details = false;
1385  bool retval;
1386 
1387  retval = false;
1388 
1389  myopt.default_footer = false;
1390  /* This output looks confusing in expanded mode. */
1391  myopt.expanded = false;
1392 
1393  initPQExpBuffer(&buf);
1394  initPQExpBuffer(&title);
1395  initPQExpBuffer(&tmpbuf);
1396 
1397  /* Get general table info */
1398  if (pset.sversion >= 90500)
1399  {
1400  printfPQExpBuffer(&buf,
1401  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1402  "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
1403  "c.relhasoids, %s, c.reltablespace, "
1404  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1405  "c.relpersistence, c.relreplident\n"
1406  "FROM pg_catalog.pg_class c\n "
1407  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1408  "WHERE c.oid = '%s';",
1409  (verbose ?
1410  "pg_catalog.array_to_string(c.reloptions || "
1411  "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1412  : "''"),
1413  oid);
1414  }
1415  else if (pset.sversion >= 90400)
1416  {
1417  printfPQExpBuffer(&buf,
1418  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1419  "c.relhastriggers, false, false, c.relhasoids, "
1420  "%s, c.reltablespace, "
1421  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1422  "c.relpersistence, c.relreplident\n"
1423  "FROM pg_catalog.pg_class c\n "
1424  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1425  "WHERE c.oid = '%s';",
1426  (verbose ?
1427  "pg_catalog.array_to_string(c.reloptions || "
1428  "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1429  : "''"),
1430  oid);
1431  }
1432  else if (pset.sversion >= 90100)
1433  {
1434  printfPQExpBuffer(&buf,
1435  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1436  "c.relhastriggers, false, false, c.relhasoids, "
1437  "%s, c.reltablespace, "
1438  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
1439  "c.relpersistence\n"
1440  "FROM pg_catalog.pg_class c\n "
1441  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1442  "WHERE c.oid = '%s';",
1443  (verbose ?
1444  "pg_catalog.array_to_string(c.reloptions || "
1445  "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1446  : "''"),
1447  oid);
1448  }
1449  else if (pset.sversion >= 90000)
1450  {
1451  printfPQExpBuffer(&buf,
1452  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1453  "c.relhastriggers, false, false, c.relhasoids, "
1454  "%s, c.reltablespace, "
1455  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END\n"
1456  "FROM pg_catalog.pg_class c\n "
1457  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1458  "WHERE c.oid = '%s';",
1459  (verbose ?
1460  "pg_catalog.array_to_string(c.reloptions || "
1461  "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1462  : "''"),
1463  oid);
1464  }
1465  else if (pset.sversion >= 80400)
1466  {
1467  printfPQExpBuffer(&buf,
1468  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
1469  "c.relhastriggers, false, false, c.relhasoids, "
1470  "%s, c.reltablespace\n"
1471  "FROM pg_catalog.pg_class c\n "
1472  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
1473  "WHERE c.oid = '%s';",
1474  (verbose ?
1475  "pg_catalog.array_to_string(c.reloptions || "
1476  "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
1477  : "''"),
1478  oid);
1479  }
1480  else if (pset.sversion >= 80200)
1481  {
1482  printfPQExpBuffer(&buf,
1483  "SELECT relchecks, relkind, relhasindex, relhasrules, "
1484  "reltriggers <> 0, false, false, relhasoids, "
1485  "%s, reltablespace\n"
1486  "FROM pg_catalog.pg_class WHERE oid = '%s';",
1487  (verbose ?
1488  "pg_catalog.array_to_string(reloptions, E', ')" : "''"),
1489  oid);
1490  }
1491  else if (pset.sversion >= 80000)
1492  {
1493  printfPQExpBuffer(&buf,
1494  "SELECT relchecks, relkind, relhasindex, relhasrules, "
1495  "reltriggers <> 0, false, false, relhasoids, "
1496  "'', reltablespace\n"
1497  "FROM pg_catalog.pg_class WHERE oid = '%s';",
1498  oid);
1499  }
1500  else
1501  {
1502  printfPQExpBuffer(&buf,
1503  "SELECT relchecks, relkind, relhasindex, relhasrules, "
1504  "reltriggers <> 0, false, false, relhasoids, "
1505  "'', ''\n"
1506  "FROM pg_catalog.pg_class WHERE oid = '%s';",
1507  oid);
1508  }
1509 
1510  res = PSQLexec(buf.data);
1511  if (!res)
1512  goto error_return;
1513 
1514  /* Did we get anything? */
1515  if (PQntuples(res) == 0)
1516  {
1517  if (!pset.quiet)
1518  psql_error("Did not find any relation with OID %s.\n", oid);
1519  goto error_return;
1520  }
1521 
1522  tableinfo.checks = atoi(PQgetvalue(res, 0, 0));
1523  tableinfo.relkind = *(PQgetvalue(res, 0, 1));
1524  tableinfo.hasindex = strcmp(PQgetvalue(res, 0, 2), "t") == 0;
1525  tableinfo.hasrules = strcmp(PQgetvalue(res, 0, 3), "t") == 0;
1526  tableinfo.hastriggers = strcmp(PQgetvalue(res, 0, 4), "t") == 0;
1527  tableinfo.rowsecurity = strcmp(PQgetvalue(res, 0, 5), "t") == 0;
1528  tableinfo.forcerowsecurity = strcmp(PQgetvalue(res, 0, 6), "t") == 0;
1529  tableinfo.hasoids = strcmp(PQgetvalue(res, 0, 7), "t") == 0;
1530  tableinfo.reloptions = (pset.sversion >= 80200) ?
1531  pg_strdup(PQgetvalue(res, 0, 8)) : NULL;
1532  tableinfo.tablespace = (pset.sversion >= 80000) ?
1533  atooid(PQgetvalue(res, 0, 9)) : 0;
1534  tableinfo.reloftype = (pset.sversion >= 90000 &&
1535  strcmp(PQgetvalue(res, 0, 10), "") != 0) ?
1536  pg_strdup(PQgetvalue(res, 0, 10)) : NULL;
1537  tableinfo.relpersistence = (pset.sversion >= 90100) ?
1538  *(PQgetvalue(res, 0, 11)) : 0;
1539  tableinfo.relreplident = (pset.sversion >= 90400) ?
1540  *(PQgetvalue(res, 0, 12)) : 'd';
1541  PQclear(res);
1542  res = NULL;
1543 
1544  /*
1545  * If it's a sequence, fetch its values and store into an array that will
1546  * be used later.
1547  */
1548  if (tableinfo.relkind == 'S')
1549  {
1550  printfPQExpBuffer(&buf, "SELECT * FROM %s", fmtId(schemaname));
1551  /* must be separate because fmtId isn't reentrant */
1552  appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
1553 
1554  res = PSQLexec(buf.data);
1555  if (!res)
1556  goto error_return;
1557 
1558  seq_values = pg_malloc((PQnfields(res) + 1) * sizeof(*seq_values));
1559 
1560  for (i = 0; i < PQnfields(res); i++)
1561  seq_values[i] = pg_strdup(PQgetvalue(res, 0, i));
1562  seq_values[i] = NULL;
1563 
1564  PQclear(res);
1565  res = NULL;
1566  }
1567 
1568  /*
1569  * Get column info
1570  *
1571  * You need to modify value of "firstvcol" which will be defined below if
1572  * you are adding column(s) preceding to verbose-only columns.
1573  */
1574  printfPQExpBuffer(&buf, "SELECT a.attname,");
1575  appendPQExpBufferStr(&buf, "\n pg_catalog.format_type(a.atttypid, a.atttypmod),"
1576  "\n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128)"
1577  "\n FROM pg_catalog.pg_attrdef d"
1578  "\n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef),"
1579  "\n a.attnotnull, a.attnum,");
1580  if (pset.sversion >= 90100)
1581  appendPQExpBufferStr(&buf, "\n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t\n"
1582  " WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation");
1583  else
1584  appendPQExpBufferStr(&buf, "\n NULL AS attcollation");
1585  if (tableinfo.relkind == 'i')
1586  appendPQExpBufferStr(&buf, ",\n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef");
1587  else
1588  appendPQExpBufferStr(&buf, ",\n NULL AS indexdef");
1589  if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
1590  appendPQExpBufferStr(&buf, ",\n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "
1591  " '(' || array_to_string(ARRAY(SELECT quote_ident(option_name) || ' ' || quote_literal(option_value) FROM "
1592  " pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions");
1593  else
1594  appendPQExpBufferStr(&buf, ",\n NULL AS attfdwoptions");
1595  if (verbose)
1596  {
1597  appendPQExpBufferStr(&buf, ",\n a.attstorage");
1598  appendPQExpBufferStr(&buf, ",\n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget");
1599 
1600  /*
1601  * In 9.0+, we have column comments for: relations, views, composite
1602  * types, and foreign tables (c.f. CommentObject() in comment.c).
1603  */
1604  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
1605  tableinfo.relkind == 'm' || tableinfo.relkind == 'f' ||
1606  tableinfo.relkind == 'c' || tableinfo.relkind == 'P')
1607  appendPQExpBufferStr(&buf, ", pg_catalog.col_description(a.attrelid, a.attnum)");
1608  }
1609 
1610  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_attribute a");
1611  appendPQExpBuffer(&buf, "\nWHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped", oid);
1612  appendPQExpBufferStr(&buf, "\nORDER BY a.attnum;");
1613 
1614  res = PSQLexec(buf.data);
1615  if (!res)
1616  goto error_return;
1617  numrows = PQntuples(res);
1618 
1619  /* Make title */
1620  switch (tableinfo.relkind)
1621  {
1622  case 'r':
1623  if (tableinfo.relpersistence == 'u')
1624  printfPQExpBuffer(&title, _("Unlogged table \"%s.%s\""),
1625  schemaname, relationname);
1626  else
1627  printfPQExpBuffer(&title, _("Table \"%s.%s\""),
1628  schemaname, relationname);
1629  break;
1630  case 'v':
1631  printfPQExpBuffer(&title, _("View \"%s.%s\""),
1632  schemaname, relationname);
1633  break;
1634  case 'm':
1635  if (tableinfo.relpersistence == 'u')
1636  printfPQExpBuffer(&title, _("Unlogged materialized view \"%s.%s\""),
1637  schemaname, relationname);
1638  else
1639  printfPQExpBuffer(&title, _("Materialized view \"%s.%s\""),
1640  schemaname, relationname);
1641  break;
1642  case 'S':
1643  printfPQExpBuffer(&title, _("Sequence \"%s.%s\""),
1644  schemaname, relationname);
1645  break;
1646  case 'i':
1647  if (tableinfo.relpersistence == 'u')
1648  printfPQExpBuffer(&title, _("Unlogged index \"%s.%s\""),
1649  schemaname, relationname);
1650  else
1651  printfPQExpBuffer(&title, _("Index \"%s.%s\""),
1652  schemaname, relationname);
1653  break;
1654  case 's':
1655  /* not used as of 8.2, but keep it for backwards compatibility */
1656  printfPQExpBuffer(&title, _("Special relation \"%s.%s\""),
1657  schemaname, relationname);
1658  break;
1659  case 't':
1660  printfPQExpBuffer(&title, _("TOAST table \"%s.%s\""),
1661  schemaname, relationname);
1662  break;
1663  case 'c':
1664  printfPQExpBuffer(&title, _("Composite type \"%s.%s\""),
1665  schemaname, relationname);
1666  break;
1667  case 'f':
1668  printfPQExpBuffer(&title, _("Foreign table \"%s.%s\""),
1669  schemaname, relationname);
1670  break;
1671  case 'P':
1672  if (tableinfo.relpersistence == 'u')
1673  printfPQExpBuffer(&title, _("Unlogged table \"%s.%s\""),
1674  schemaname, relationname);
1675  else
1676  printfPQExpBuffer(&title, _("Table \"%s.%s\""),
1677  schemaname, relationname);
1678  break;
1679  default:
1680  /* untranslated unknown relkind */
1681  printfPQExpBuffer(&title, "?%c? \"%s.%s\"",
1682  tableinfo.relkind, schemaname, relationname);
1683  break;
1684  }
1685 
1686  /* Set the number of columns, and their names */
1687  headers[0] = gettext_noop("Column");
1688  headers[1] = gettext_noop("Type");
1689  cols = 2;
1690 
1691  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
1692  tableinfo.relkind == 'm' || tableinfo.relkind == 'f' ||
1693  tableinfo.relkind == 'c' || tableinfo.relkind == 'P')
1694  {
1695  headers[cols++] = gettext_noop("Collation");
1696  headers[cols++] = gettext_noop("Nullable");
1697  headers[cols++] = gettext_noop("Default");
1698  show_column_details = true;
1699  }
1700 
1701  if (tableinfo.relkind == 'S')
1702  headers[cols++] = gettext_noop("Value");
1703 
1704  if (tableinfo.relkind == 'i')
1705  headers[cols++] = gettext_noop("Definition");
1706 
1707  if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
1708  headers[cols++] = gettext_noop("FDW Options");
1709 
1710  if (verbose)
1711  {
1712  headers[cols++] = gettext_noop("Storage");
1713  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'm' ||
1714  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
1715  headers[cols++] = gettext_noop("Stats target");
1716  /* Column comments, if the relkind supports this feature. */
1717  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
1718  tableinfo.relkind == 'm' || tableinfo.relkind == 'c' ||
1719  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
1720  headers[cols++] = gettext_noop("Description");
1721  }
1722 
1723  printTableInit(&cont, &myopt, title.data, cols, numrows);
1724  printTableInitialized = true;
1725 
1726  for (i = 0; i < cols; i++)
1727  printTableAddHeader(&cont, headers[i], true, 'l');
1728 
1729  /* Check if table is a view or materialized view */
1730  if ((tableinfo.relkind == 'v' || tableinfo.relkind == 'm') && verbose)
1731  {
1732  PGresult *result;
1733 
1734  printfPQExpBuffer(&buf,
1735  "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);",
1736  oid);
1737  result = PSQLexec(buf.data);
1738  if (!result)
1739  goto error_return;
1740 
1741  if (PQntuples(result) > 0)
1742  view_def = pg_strdup(PQgetvalue(result, 0, 0));
1743 
1744  PQclear(result);
1745  }
1746 
1747  /* Generate table cells to be printed */
1748  for (i = 0; i < numrows; i++)
1749  {
1750  /* Column */
1751  printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
1752 
1753  /* Type */
1754  printTableAddCell(&cont, PQgetvalue(res, i, 1), false, false);
1755 
1756  /* Collation, Nullable, Default */
1757  if (show_column_details)
1758  {
1759  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
1760 
1761  printTableAddCell(&cont, strcmp(PQgetvalue(res, i, 3), "t") == 0 ? "not null" : "", false, false);
1762 
1763  /* (note: above we cut off the 'default' string at 128) */
1764  printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
1765  }
1766 
1767  /* Value: for sequences only */
1768  if (tableinfo.relkind == 'S')
1769  printTableAddCell(&cont, seq_values[i], false, false);
1770 
1771  /* Expression for index column */
1772  if (tableinfo.relkind == 'i')
1773  printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
1774 
1775  /* FDW options for foreign table column, only for 9.2 or later */
1776  if (tableinfo.relkind == 'f' && pset.sversion >= 90200)
1777  printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
1778 
1779  /* Storage and Description */
1780  if (verbose)
1781  {
1782  int firstvcol = 8;
1783  char *storage = PQgetvalue(res, i, firstvcol);
1784 
1785  /* these strings are literal in our syntax, so not translated. */
1786  printTableAddCell(&cont, (storage[0] == 'p' ? "plain" :
1787  (storage[0] == 'm' ? "main" :
1788  (storage[0] == 'x' ? "extended" :
1789  (storage[0] == 'e' ? "external" :
1790  "???")))),
1791  false, false);
1792 
1793  /* Statistics target, if the relkind supports this feature */
1794  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'm' ||
1795  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
1796  {
1797  printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 1),
1798  false, false);
1799  }
1800 
1801  /* Column comments, if the relkind supports this feature. */
1802  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'v' ||
1803  tableinfo.relkind == 'm' || tableinfo.relkind == 'c' ||
1804  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
1805  printTableAddCell(&cont, PQgetvalue(res, i, firstvcol + 2),
1806  false, false);
1807  }
1808  }
1809 
1810  /* Make footers */
1811  if (pset.sversion >= 100000)
1812  {
1813  /* Get the partition information */
1814  PGresult *result;
1815  char *parent_name;
1816  char *partdef;
1817 
1818  printfPQExpBuffer(&buf,
1819  "SELECT inhparent::pg_catalog.regclass, pg_get_expr(c.relpartbound, inhrelid)"
1820  " FROM pg_catalog.pg_class c"
1821  " JOIN pg_catalog.pg_inherits"
1822  " ON c.oid = inhrelid"
1823  " WHERE c.oid = '%s' AND c.relispartition;", oid);
1824  result = PSQLexec(buf.data);
1825  if (!result)
1826  goto error_return;
1827 
1828  if (PQntuples(result) > 0)
1829  {
1830  parent_name = PQgetvalue(result, 0, 0);
1831  partdef = PQgetvalue(result, 0, 1);
1832  printfPQExpBuffer(&tmpbuf, _("Partition of: %s %s"), parent_name,
1833  partdef);
1834  printTableAddFooter(&cont, tmpbuf.data);
1835  PQclear(result);
1836  }
1837  }
1838 
1839  if (tableinfo.relkind == 'P')
1840  {
1841  /* Get the partition key information */
1842  PGresult *result;
1843  char *partkeydef;
1844 
1845  printfPQExpBuffer(&buf,
1846  "SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid);",
1847  oid);
1848  result = PSQLexec(buf.data);
1849  if (!result || PQntuples(result) != 1)
1850  goto error_return;
1851 
1852  partkeydef = PQgetvalue(result, 0, 0);
1853  printfPQExpBuffer(&tmpbuf, _("Partition key: %s"), partkeydef);
1854  printTableAddFooter(&cont, tmpbuf.data);
1855  PQclear(result);
1856  }
1857 
1858  if (tableinfo.relkind == 'i')
1859  {
1860  /* Footer information about an index */
1861  PGresult *result;
1862 
1863  printfPQExpBuffer(&buf,
1864  "SELECT i.indisunique, i.indisprimary, i.indisclustered, ");
1865  if (pset.sversion >= 80200)
1866  appendPQExpBufferStr(&buf, "i.indisvalid,\n");
1867  else
1868  appendPQExpBufferStr(&buf, "true AS indisvalid,\n");
1869  if (pset.sversion >= 90000)
1870  appendPQExpBufferStr(&buf,
1871  " (NOT i.indimmediate) AND "
1872  "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
1873  "WHERE conrelid = i.indrelid AND "
1874  "conindid = i.indexrelid AND "
1875  "contype IN ('p','u','x') AND "
1876  "condeferrable) AS condeferrable,\n"
1877  " (NOT i.indimmediate) AND "
1878  "EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
1879  "WHERE conrelid = i.indrelid AND "
1880  "conindid = i.indexrelid AND "
1881  "contype IN ('p','u','x') AND "
1882  "condeferred) AS condeferred,\n");
1883  else
1884  appendPQExpBufferStr(&buf,
1885  " false AS condeferrable, false AS condeferred,\n");
1886 
1887  if (pset.sversion >= 90400)
1888  appendPQExpBuffer(&buf, "i.indisreplident,\n");
1889  else
1890  appendPQExpBuffer(&buf, "false AS indisreplident,\n");
1891 
1892  appendPQExpBuffer(&buf, " a.amname, c2.relname, "
1893  "pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
1894  "FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
1895  "WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
1896  "AND i.indrelid = c2.oid;",
1897  oid);
1898 
1899  result = PSQLexec(buf.data);
1900  if (!result)
1901  goto error_return;
1902  else if (PQntuples(result) != 1)
1903  {
1904  PQclear(result);
1905  goto error_return;
1906  }
1907  else
1908  {
1909  char *indisunique = PQgetvalue(result, 0, 0);
1910  char *indisprimary = PQgetvalue(result, 0, 1);
1911  char *indisclustered = PQgetvalue(result, 0, 2);
1912  char *indisvalid = PQgetvalue(result, 0, 3);
1913  char *deferrable = PQgetvalue(result, 0, 4);
1914  char *deferred = PQgetvalue(result, 0, 5);
1915  char *indisreplident = PQgetvalue(result, 0, 6);
1916  char *indamname = PQgetvalue(result, 0, 7);
1917  char *indtable = PQgetvalue(result, 0, 8);
1918  char *indpred = PQgetvalue(result, 0, 9);
1919 
1920  if (strcmp(indisprimary, "t") == 0)
1921  printfPQExpBuffer(&tmpbuf, _("primary key, "));
1922  else if (strcmp(indisunique, "t") == 0)
1923  printfPQExpBuffer(&tmpbuf, _("unique, "));
1924  else
1925  resetPQExpBuffer(&tmpbuf);
1926  appendPQExpBuffer(&tmpbuf, "%s, ", indamname);
1927 
1928  /* we assume here that index and table are in same schema */
1929  appendPQExpBuffer(&tmpbuf, _("for table \"%s.%s\""),
1930  schemaname, indtable);
1931 
1932  if (strlen(indpred))
1933  appendPQExpBuffer(&tmpbuf, _(", predicate (%s)"), indpred);
1934 
1935  if (strcmp(indisclustered, "t") == 0)
1936  appendPQExpBufferStr(&tmpbuf, _(", clustered"));
1937 
1938  if (strcmp(indisvalid, "t") != 0)
1939  appendPQExpBufferStr(&tmpbuf, _(", invalid"));
1940 
1941  if (strcmp(deferrable, "t") == 0)
1942  appendPQExpBufferStr(&tmpbuf, _(", deferrable"));
1943 
1944  if (strcmp(deferred, "t") == 0)
1945  appendPQExpBufferStr(&tmpbuf, _(", initially deferred"));
1946 
1947  if (strcmp(indisreplident, "t") == 0)
1948  appendPQExpBuffer(&tmpbuf, _(", replica identity"));
1949 
1950  printTableAddFooter(&cont, tmpbuf.data);
1951  add_tablespace_footer(&cont, tableinfo.relkind,
1952  tableinfo.tablespace, true);
1953  }
1954 
1955  PQclear(result);
1956  }
1957  else if (tableinfo.relkind == 'S')
1958  {
1959  /* Footer information about a sequence */
1960  PGresult *result = NULL;
1961 
1962  /* Get the column that owns this sequence */
1963  printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||"
1964  "\n pg_catalog.quote_ident(relname) || '.' ||"
1965  "\n pg_catalog.quote_ident(attname)"
1966  "\nFROM pg_catalog.pg_class c"
1967  "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid"
1968  "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace"
1969  "\nINNER JOIN pg_catalog.pg_attribute a ON ("
1970  "\n a.attrelid=c.oid AND"
1971  "\n a.attnum=d.refobjsubid)"
1972  "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass"
1973  "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass"
1974  "\n AND d.objid=%s"
1975  "\n AND d.deptype='a'",
1976  oid);
1977 
1978  result = PSQLexec(buf.data);
1979  if (!result)
1980  goto error_return;
1981  else if (PQntuples(result) == 1)
1982  {
1983  printfPQExpBuffer(&buf, _("Owned by: %s"),
1984  PQgetvalue(result, 0, 0));
1985  printTableAddFooter(&cont, buf.data);
1986  }
1987 
1988  /*
1989  * If we get no rows back, don't show anything (obviously). We should
1990  * never get more than one row back, but if we do, just ignore it and
1991  * don't print anything.
1992  */
1993  PQclear(result);
1994  }
1995  else if (tableinfo.relkind == 'r' || tableinfo.relkind == 'm' ||
1996  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
1997  {
1998  /* Footer information about a table */
1999  PGresult *result = NULL;
2000  int tuples = 0;
2001 
2002  /* print indexes */
2003  if (tableinfo.hasindex)
2004  {
2005  printfPQExpBuffer(&buf,
2006  "SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, ");
2007  if (pset.sversion >= 80200)
2008  appendPQExpBufferStr(&buf, "i.indisvalid, ");
2009  else
2010  appendPQExpBufferStr(&buf, "true as indisvalid, ");
2011  appendPQExpBufferStr(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n ");
2012  if (pset.sversion >= 90000)
2013  appendPQExpBufferStr(&buf,
2014  "pg_catalog.pg_get_constraintdef(con.oid, true), "
2015  "contype, condeferrable, condeferred");
2016  else
2017  appendPQExpBufferStr(&buf,
2018  "null AS constraintdef, null AS contype, "
2019  "false AS condeferrable, false AS condeferred");
2020  if (pset.sversion >= 90400)
2021  appendPQExpBufferStr(&buf, ", i.indisreplident");
2022  else
2023  appendPQExpBufferStr(&buf, ", false AS indisreplident");
2024  if (pset.sversion >= 80000)
2025  appendPQExpBufferStr(&buf, ", c2.reltablespace");
2026  appendPQExpBufferStr(&buf,
2027  "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n");
2028  if (pset.sversion >= 90000)
2029  appendPQExpBufferStr(&buf,
2030  " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x'))\n");
2031  appendPQExpBuffer(&buf,
2032  "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
2033  "ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname;",
2034  oid);
2035  result = PSQLexec(buf.data);
2036  if (!result)
2037  goto error_return;
2038  else
2039  tuples = PQntuples(result);
2040 
2041  if (tuples > 0)
2042  {
2043  printTableAddFooter(&cont, _("Indexes:"));
2044  for (i = 0; i < tuples; i++)
2045  {
2046  /* untranslated index name */
2047  printfPQExpBuffer(&buf, " \"%s\"",
2048  PQgetvalue(result, i, 0));
2049 
2050  /* If exclusion constraint, print the constraintdef */
2051  if (strcmp(PQgetvalue(result, i, 7), "x") == 0)
2052  {
2053  appendPQExpBuffer(&buf, " %s",
2054  PQgetvalue(result, i, 6));
2055  }
2056  else
2057  {
2058  const char *indexdef;
2059  const char *usingpos;
2060 
2061  /* Label as primary key or unique (but not both) */
2062  if (strcmp(PQgetvalue(result, i, 1), "t") == 0)
2063  appendPQExpBufferStr(&buf, " PRIMARY KEY,");
2064  else if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
2065  {
2066  if (strcmp(PQgetvalue(result, i, 7), "u") == 0)
2067  appendPQExpBufferStr(&buf, " UNIQUE CONSTRAINT,");
2068  else
2069  appendPQExpBufferStr(&buf, " UNIQUE,");
2070  }
2071 
2072  /* Everything after "USING" is echoed verbatim */
2073  indexdef = PQgetvalue(result, i, 5);
2074  usingpos = strstr(indexdef, " USING ");
2075  if (usingpos)
2076  indexdef = usingpos + 7;
2077  appendPQExpBuffer(&buf, " %s", indexdef);
2078 
2079  /* Need these for deferrable PK/UNIQUE indexes */
2080  if (strcmp(PQgetvalue(result, i, 8), "t") == 0)
2081  appendPQExpBufferStr(&buf, " DEFERRABLE");
2082 
2083  if (strcmp(PQgetvalue(result, i, 9), "t") == 0)
2084  appendPQExpBufferStr(&buf, " INITIALLY DEFERRED");
2085  }
2086 
2087  /* Add these for all cases */
2088  if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
2089  appendPQExpBufferStr(&buf, " CLUSTER");
2090 
2091  if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
2092  appendPQExpBufferStr(&buf, " INVALID");
2093 
2094  if (strcmp(PQgetvalue(result, i, 10), "t") == 0)
2095  appendPQExpBuffer(&buf, " REPLICA IDENTITY");
2096 
2097  printTableAddFooter(&cont, buf.data);
2098 
2099  /* Print tablespace of the index on the same line */
2100  if (pset.sversion >= 80000)
2101  add_tablespace_footer(&cont, 'i',
2102  atooid(PQgetvalue(result, i, 11)),
2103  false);
2104  }
2105  }
2106  PQclear(result);
2107  }
2108 
2109  /* print table (and column) check constraints */
2110  if (tableinfo.checks)
2111  {
2112  printfPQExpBuffer(&buf,
2113  "SELECT r.conname, "
2114  "pg_catalog.pg_get_constraintdef(r.oid, true)\n"
2115  "FROM pg_catalog.pg_constraint r\n"
2116  "WHERE r.conrelid = '%s' AND r.contype = 'c'\n"
2117  "ORDER BY 1;",
2118  oid);
2119  result = PSQLexec(buf.data);
2120  if (!result)
2121  goto error_return;
2122  else
2123  tuples = PQntuples(result);
2124 
2125  if (tuples > 0)
2126  {
2127  printTableAddFooter(&cont, _("Check constraints:"));
2128  for (i = 0; i < tuples; i++)
2129  {
2130  /* untranslated constraint name and def */
2131  printfPQExpBuffer(&buf, " \"%s\" %s",
2132  PQgetvalue(result, i, 0),
2133  PQgetvalue(result, i, 1));
2134 
2135  printTableAddFooter(&cont, buf.data);
2136  }
2137  }
2138  PQclear(result);
2139  }
2140 
2141  /* print foreign-key constraints (there are none if no triggers) */
2142  if (tableinfo.hastriggers)
2143  {
2144  printfPQExpBuffer(&buf,
2145  "SELECT conname,\n"
2146  " pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n"
2147  "FROM pg_catalog.pg_constraint r\n"
2148  "WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1;",
2149  oid);
2150  result = PSQLexec(buf.data);
2151  if (!result)
2152  goto error_return;
2153  else
2154  tuples = PQntuples(result);
2155 
2156  if (tuples > 0)
2157  {
2158  printTableAddFooter(&cont, _("Foreign-key constraints:"));
2159  for (i = 0; i < tuples; i++)
2160  {
2161  /* untranslated constraint name and def */
2162  printfPQExpBuffer(&buf, " \"%s\" %s",
2163  PQgetvalue(result, i, 0),
2164  PQgetvalue(result, i, 1));
2165 
2166  printTableAddFooter(&cont, buf.data);
2167  }
2168  }
2169  PQclear(result);
2170  }
2171 
2172  /* print incoming foreign-key references (none if no triggers) */
2173  if (tableinfo.hastriggers)
2174  {
2175  printfPQExpBuffer(&buf,
2176  "SELECT conname, conrelid::pg_catalog.regclass,\n"
2177  " pg_catalog.pg_get_constraintdef(c.oid, true) as condef\n"
2178  "FROM pg_catalog.pg_constraint c\n"
2179  "WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1;",
2180  oid);
2181  result = PSQLexec(buf.data);
2182  if (!result)
2183  goto error_return;
2184  else
2185  tuples = PQntuples(result);
2186 
2187  if (tuples > 0)
2188  {
2189  printTableAddFooter(&cont, _("Referenced by:"));
2190  for (i = 0; i < tuples; i++)
2191  {
2192  printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
2193  PQgetvalue(result, i, 1),
2194  PQgetvalue(result, i, 0),
2195  PQgetvalue(result, i, 2));
2196 
2197  printTableAddFooter(&cont, buf.data);
2198  }
2199  }
2200  PQclear(result);
2201  }
2202 
2203  /* print any row-level policies */
2204  if (pset.sversion >= 90500)
2205  {
2206  if (pset.sversion >= 100000)
2207  printfPQExpBuffer(&buf,
2208  "SELECT pol.polname, pol.polpermissive,\n"
2209  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
2210  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
2211  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
2212  "CASE pol.polcmd \n"
2213  "WHEN 'r' THEN 'SELECT'\n"
2214  "WHEN 'a' THEN 'INSERT'\n"
2215  "WHEN 'w' THEN 'UPDATE'\n"
2216  "WHEN 'd' THEN 'DELETE'\n"
2217  "END AS cmd\n"
2218  "FROM pg_catalog.pg_policy pol\n"
2219  "WHERE pol.polrelid = '%s' ORDER BY 1;",
2220  oid);
2221  else
2222  printfPQExpBuffer(&buf,
2223  "SELECT pol.polname, 't' as polpermissive,\n"
2224  "CASE WHEN pol.polroles = '{0}' THEN NULL ELSE array_to_string(array(select rolname from pg_roles where oid = any (pol.polroles) order by 1),',') END,\n"
2225  "pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n"
2226  "pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n"
2227  "CASE pol.polcmd \n"
2228  "WHEN 'r' THEN 'SELECT'\n"
2229  "WHEN 'a' THEN 'INSERT'\n"
2230  "WHEN 'w' THEN 'UPDATE'\n"
2231  "WHEN 'd' THEN 'DELETE'\n"
2232  "END AS cmd\n"
2233  "FROM pg_catalog.pg_policy pol\n"
2234  "WHERE pol.polrelid = '%s' ORDER BY 1;",
2235  oid);
2236 
2237  result = PSQLexec(buf.data);
2238  if (!result)
2239  goto error_return;
2240  else
2241  tuples = PQntuples(result);
2242 
2243  /*
2244  * Handle cases where RLS is enabled and there are policies, or
2245  * there aren't policies, or RLS isn't enabled but there are
2246  * policies
2247  */
2248  if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples > 0)
2249  printTableAddFooter(&cont, _("Policies:"));
2250 
2251  if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples > 0)
2252  printTableAddFooter(&cont, _("Policies (forced row security enabled):"));
2253 
2254  if (tableinfo.rowsecurity && !tableinfo.forcerowsecurity && tuples == 0)
2255  printTableAddFooter(&cont, _("Policies (row security enabled): (none)"));
2256 
2257  if (tableinfo.rowsecurity && tableinfo.forcerowsecurity && tuples == 0)
2258  printTableAddFooter(&cont, _("Policies (forced row security enabled): (none)"));
2259 
2260  if (!tableinfo.rowsecurity && tuples > 0)
2261  printTableAddFooter(&cont, _("Policies (row security disabled):"));
2262 
2263  /* Might be an empty set - that's ok */
2264  for (i = 0; i < tuples; i++)
2265  {
2266  printfPQExpBuffer(&buf, " POLICY \"%s\"",
2267  PQgetvalue(result, i, 0));
2268 
2269  if (*(PQgetvalue(result, i, 1)) == 'f')
2270  appendPQExpBuffer(&buf, " AS RESTRICTIVE");
2271 
2272  if (!PQgetisnull(result, i, 5))
2273  appendPQExpBuffer(&buf, " FOR %s",
2274  PQgetvalue(result, i, 5));
2275 
2276  if (!PQgetisnull(result, i, 2))
2277  {
2278  appendPQExpBuffer(&buf, "\n TO %s",
2279  PQgetvalue(result, i, 2));
2280  }
2281 
2282  if (!PQgetisnull(result, i, 3))
2283  appendPQExpBuffer(&buf, "\n USING (%s)",
2284  PQgetvalue(result, i, 3));
2285 
2286  if (!PQgetisnull(result, i, 4))
2287  appendPQExpBuffer(&buf, "\n WITH CHECK (%s)",
2288  PQgetvalue(result, i, 4));
2289 
2290  printTableAddFooter(&cont, buf.data);
2291 
2292  }
2293  PQclear(result);
2294  }
2295 
2296  /* print rules */
2297  if (tableinfo.hasrules && tableinfo.relkind != 'm')
2298  {
2299  if (pset.sversion >= 80300)
2300  {
2301  printfPQExpBuffer(&buf,
2302  "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
2303  "ev_enabled\n"
2304  "FROM pg_catalog.pg_rewrite r\n"
2305  "WHERE r.ev_class = '%s' ORDER BY 1;",
2306  oid);
2307  }
2308  else
2309  {
2310  printfPQExpBuffer(&buf,
2311  "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
2312  "'O'::char AS ev_enabled\n"
2313  "FROM pg_catalog.pg_rewrite r\n"
2314  "WHERE r.ev_class = '%s' ORDER BY 1;",
2315  oid);
2316  }
2317  result = PSQLexec(buf.data);
2318  if (!result)
2319  goto error_return;
2320  else
2321  tuples = PQntuples(result);
2322 
2323  if (tuples > 0)
2324  {
2325  bool have_heading;
2326  int category;
2327 
2328  for (category = 0; category < 4; category++)
2329  {
2330  have_heading = false;
2331 
2332  for (i = 0; i < tuples; i++)
2333  {
2334  const char *ruledef;
2335  bool list_rule = false;
2336 
2337  switch (category)
2338  {
2339  case 0:
2340  if (*PQgetvalue(result, i, 2) == 'O')
2341  list_rule = true;
2342  break;
2343  case 1:
2344  if (*PQgetvalue(result, i, 2) == 'D')
2345  list_rule = true;
2346  break;
2347  case 2:
2348  if (*PQgetvalue(result, i, 2) == 'A')
2349  list_rule = true;
2350  break;
2351  case 3:
2352  if (*PQgetvalue(result, i, 2) == 'R')
2353  list_rule = true;
2354  break;
2355  }
2356  if (!list_rule)
2357  continue;
2358 
2359  if (!have_heading)
2360  {
2361  switch (category)
2362  {
2363  case 0:
2364  printfPQExpBuffer(&buf, _("Rules:"));
2365  break;
2366  case 1:
2367  printfPQExpBuffer(&buf, _("Disabled rules:"));
2368  break;
2369  case 2:
2370  printfPQExpBuffer(&buf, _("Rules firing always:"));
2371  break;
2372  case 3:
2373  printfPQExpBuffer(&buf, _("Rules firing on replica only:"));
2374  break;
2375  }
2376  printTableAddFooter(&cont, buf.data);
2377  have_heading = true;
2378  }
2379 
2380  /* Everything after "CREATE RULE" is echoed verbatim */
2381  ruledef = PQgetvalue(result, i, 1);
2382  ruledef += 12;
2383  printfPQExpBuffer(&buf, " %s", ruledef);
2384  printTableAddFooter(&cont, buf.data);
2385  }
2386  }
2387  }
2388  PQclear(result);
2389  }
2390 
2391  /* print any publications */
2392  if (pset.sversion >= 100000)
2393  {
2394  printfPQExpBuffer(&buf,
2395  "SELECT pub.pubname\n"
2396  " FROM pg_catalog.pg_publication pub\n"
2397  " LEFT JOIN pg_publication_rel pr\n"
2398  " ON (pr.prpubid = pub.oid)\n"
2399  "WHERE pr.prrelid = '%s' OR pub.puballtables\n"
2400  "ORDER BY 1;",
2401  oid);
2402 
2403  result = PSQLexec(buf.data);
2404  if (!result)
2405  goto error_return;
2406  else
2407  tuples = PQntuples(result);
2408 
2409  if (tuples > 0)
2410  printTableAddFooter(&cont, _("Publications:"));
2411 
2412  /* Might be an empty set - that's ok */
2413  for (i = 0; i < tuples; i++)
2414  {
2415  printfPQExpBuffer(&buf, " \"%s\"",
2416  PQgetvalue(result, i, 0));
2417 
2418  printTableAddFooter(&cont, buf.data);
2419  }
2420  PQclear(result);
2421  }
2422  }
2423 
2424  if (view_def)
2425  {
2426  PGresult *result = NULL;
2427 
2428  /* Footer information about a view */
2429  printTableAddFooter(&cont, _("View definition:"));
2430  printTableAddFooter(&cont, view_def);
2431 
2432  /* print rules */
2433  if (tableinfo.hasrules)
2434  {
2435  printfPQExpBuffer(&buf,
2436  "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true))\n"
2437  "FROM pg_catalog.pg_rewrite r\n"
2438  "WHERE r.ev_class = '%s' AND r.rulename != '_RETURN' ORDER BY 1;",
2439  oid);
2440  result = PSQLexec(buf.data);
2441  if (!result)
2442  goto error_return;
2443 
2444  if (PQntuples(result) > 0)
2445  {
2446  printTableAddFooter(&cont, _("Rules:"));
2447  for (i = 0; i < PQntuples(result); i++)
2448  {
2449  const char *ruledef;
2450 
2451  /* Everything after "CREATE RULE" is echoed verbatim */
2452  ruledef = PQgetvalue(result, i, 1);
2453  ruledef += 12;
2454 
2455  printfPQExpBuffer(&buf, " %s", ruledef);
2456  printTableAddFooter(&cont, buf.data);
2457  }
2458  }
2459  PQclear(result);
2460  }
2461  }
2462 
2463  /*
2464  * Print triggers next, if any (but only user-defined triggers). This
2465  * could apply to either a table or a view.
2466  */
2467  if (tableinfo.hastriggers)
2468  {
2469  PGresult *result;
2470  int tuples;
2471 
2472  printfPQExpBuffer(&buf,
2473  "SELECT t.tgname, "
2474  "pg_catalog.pg_get_triggerdef(t.oid%s), "
2475  "t.tgenabled, %s\n"
2476  "FROM pg_catalog.pg_trigger t\n"
2477  "WHERE t.tgrelid = '%s' AND ",
2478  (pset.sversion >= 90000 ? ", true" : ""),
2479  (pset.sversion >= 90000 ? "t.tgisinternal" :
2480  pset.sversion >= 80300 ?
2481  "t.tgconstraint <> 0 AS tgisinternal" :
2482  "false AS tgisinternal"), oid);
2483  if (pset.sversion >= 90000)
2484  /* display/warn about disabled internal triggers */
2485  appendPQExpBuffer(&buf, "(NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D'))");
2486  else if (pset.sversion >= 80300)
2487  appendPQExpBufferStr(&buf, "(t.tgconstraint = 0 OR (t.tgconstraint <> 0 AND t.tgenabled = 'D'))");
2488  else
2489  appendPQExpBufferStr(&buf,
2490  "(NOT tgisconstraint "
2491  " OR NOT EXISTS"
2492  " (SELECT 1 FROM pg_catalog.pg_depend d "
2493  " JOIN pg_catalog.pg_constraint c ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) "
2494  " WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))");
2495  appendPQExpBufferStr(&buf, "\nORDER BY 1;");
2496 
2497  result = PSQLexec(buf.data);
2498  if (!result)
2499  goto error_return;
2500  else
2501  tuples = PQntuples(result);
2502 
2503  if (tuples > 0)
2504  {
2505  bool have_heading;
2506  int category;
2507 
2508  /*
2509  * split the output into 4 different categories. Enabled triggers,
2510  * disabled triggers and the two special ALWAYS and REPLICA
2511  * configurations.
2512  */
2513  for (category = 0; category <= 4; category++)
2514  {
2515  have_heading = false;
2516  for (i = 0; i < tuples; i++)
2517  {
2518  bool list_trigger;
2519  const char *tgdef;
2520  const char *usingpos;
2521  const char *tgenabled;
2522  const char *tgisinternal;
2523 
2524  /*
2525  * Check if this trigger falls into the current category
2526  */
2527  tgenabled = PQgetvalue(result, i, 2);
2528  tgisinternal = PQgetvalue(result, i, 3);
2529  list_trigger = false;
2530  switch (category)
2531  {
2532  case 0:
2533  if (*tgenabled == 'O' || *tgenabled == 't')
2534  list_trigger = true;
2535  break;
2536  case 1:
2537  if ((*tgenabled == 'D' || *tgenabled == 'f') &&
2538  *tgisinternal == 'f')
2539  list_trigger = true;
2540  break;
2541  case 2:
2542  if ((*tgenabled == 'D' || *tgenabled == 'f') &&
2543  *tgisinternal == 't')
2544  list_trigger = true;
2545  break;
2546  case 3:
2547  if (*tgenabled == 'A')
2548  list_trigger = true;
2549  break;
2550  case 4:
2551  if (*tgenabled == 'R')
2552  list_trigger = true;
2553  break;
2554  }
2555  if (list_trigger == false)
2556  continue;
2557 
2558  /* Print the category heading once */
2559  if (have_heading == false)
2560  {
2561  switch (category)
2562  {
2563  case 0:
2564  printfPQExpBuffer(&buf, _("Triggers:"));
2565  break;
2566  case 1:
2567  if (pset.sversion >= 80300)
2568  printfPQExpBuffer(&buf, _("Disabled user triggers:"));
2569  else
2570  printfPQExpBuffer(&buf, _("Disabled triggers:"));
2571  break;
2572  case 2:
2573  printfPQExpBuffer(&buf, _("Disabled internal triggers:"));
2574  break;
2575  case 3:
2576  printfPQExpBuffer(&buf, _("Triggers firing always:"));
2577  break;
2578  case 4:
2579  printfPQExpBuffer(&buf, _("Triggers firing on replica only:"));
2580  break;
2581 
2582  }
2583  printTableAddFooter(&cont, buf.data);
2584  have_heading = true;
2585  }
2586 
2587  /* Everything after "TRIGGER" is echoed verbatim */
2588  tgdef = PQgetvalue(result, i, 1);
2589  usingpos = strstr(tgdef, " TRIGGER ");
2590  if (usingpos)
2591  tgdef = usingpos + 9;
2592 
2593  printfPQExpBuffer(&buf, " %s", tgdef);
2594  printTableAddFooter(&cont, buf.data);
2595  }
2596  }
2597  }
2598  PQclear(result);
2599  }
2600 
2601  /*
2602  * Finish printing the footer information about a table.
2603  */
2604  if (tableinfo.relkind == 'r' || tableinfo.relkind == 'm' ||
2605  tableinfo.relkind == 'f' || tableinfo.relkind == 'P')
2606  {
2607  PGresult *result;
2608  int tuples;
2609 
2610  /* print foreign server name */
2611  if (tableinfo.relkind == 'f')
2612  {
2613  char *ftoptions;
2614 
2615  /* Footer information about foreign table */
2616  printfPQExpBuffer(&buf,
2617  "SELECT s.srvname,\n"
2618  " array_to_string(ARRAY(SELECT "
2619  " quote_ident(option_name) || ' ' || "
2620  " quote_literal(option_value) FROM "
2621  " pg_options_to_table(ftoptions)), ', ') "
2622  "FROM pg_catalog.pg_foreign_table f,\n"
2623  " pg_catalog.pg_foreign_server s\n"
2624  "WHERE f.ftrelid = %s AND s.oid = f.ftserver;",
2625  oid);
2626  result = PSQLexec(buf.data);
2627  if (!result)
2628  goto error_return;
2629  else if (PQntuples(result) != 1)
2630  {
2631  PQclear(result);
2632  goto error_return;
2633  }
2634 
2635  /* Print server name */
2636  printfPQExpBuffer(&buf, "Server: %s",
2637  PQgetvalue(result, 0, 0));
2638  printTableAddFooter(&cont, buf.data);
2639 
2640  /* Print per-table FDW options, if any */
2641  ftoptions = PQgetvalue(result, 0, 1);
2642  if (ftoptions && ftoptions[0] != '\0')
2643  {
2644  printfPQExpBuffer(&buf, "FDW Options: (%s)", ftoptions);
2645  printTableAddFooter(&cont, buf.data);
2646  }
2647  PQclear(result);
2648  }
2649 
2650  /* print inherited tables (exclude, if parent is a partitioned table) */
2651  printfPQExpBuffer(&buf,
2652  "SELECT c.oid::pg_catalog.regclass"
2653  " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
2654  " WHERE c.oid=i.inhparent AND i.inhrelid = '%s'"
2655  " AND c.relkind != 'P' ORDER BY inhseqno;", oid);
2656 
2657  result = PSQLexec(buf.data);
2658  if (!result)
2659  goto error_return;
2660  else
2661  {
2662  const char *s = _("Inherits");
2663  int sw = pg_wcswidth(s, strlen(s), pset.encoding);
2664 
2665  tuples = PQntuples(result);
2666 
2667  for (i = 0; i < tuples; i++)
2668  {
2669  if (i == 0)
2670  printfPQExpBuffer(&buf, "%s: %s",
2671  s, PQgetvalue(result, i, 0));
2672  else
2673  printfPQExpBuffer(&buf, "%*s %s",
2674  sw, "", PQgetvalue(result, i, 0));
2675  if (i < tuples - 1)
2676  appendPQExpBufferChar(&buf, ',');
2677 
2678  printTableAddFooter(&cont, buf.data);
2679  }
2680 
2681  PQclear(result);
2682  }
2683 
2684  /* print child tables (with additional info if partitions) */
2685  if (pset.sversion >= 100000)
2686  printfPQExpBuffer(&buf,
2687  "SELECT c.oid::pg_catalog.regclass, pg_get_expr(c.relpartbound, c.oid)"
2688  " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
2689  " WHERE c.oid=i.inhrelid AND"
2690  " i.inhparent = '%s' AND"
2691  " EXISTS (SELECT 1 FROM pg_class c WHERE c.oid = '%s')"
2692  " ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid, oid);
2693  else if (pset.sversion >= 80300)
2694  printfPQExpBuffer(&buf,
2695  "SELECT c.oid::pg_catalog.regclass"
2696  " FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i"
2697  " WHERE c.oid=i.inhrelid AND"
2698  " i.inhparent = '%s' AND"
2699  " EXISTS (SELECT 1 FROM pg_class c WHERE c.oid = '%s')"
2700  " ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;", oid, oid);
2701  else
2702  printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i WHERE c.oid=i.inhrelid AND i.inhparent = '%s' ORDER BY c.relname;", oid);
2703 
2704  result = PSQLexec(buf.data);
2705  if (!result)
2706  goto error_return;
2707  else
2708  tuples = PQntuples(result);
2709 
2710  if (!verbose)
2711  {
2712  /* print the number of child tables, if any */
2713  if (tuples > 0)
2714  {
2715  if (tableinfo.relkind != 'P')
2716  printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
2717  else
2718  printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples);
2719  printTableAddFooter(&cont, buf.data);
2720  }
2721  }
2722  else
2723  {
2724  /* display the list of child tables */
2725  const char *ct = tableinfo.relkind != 'P' ? _("Child tables") : _("Partitions");
2726  int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding);
2727 
2728  for (i = 0; i < tuples; i++)
2729  {
2730  if (tableinfo.relkind != 'P')
2731  {
2732  if (i == 0)
2733  printfPQExpBuffer(&buf, "%s: %s",
2734  ct, PQgetvalue(result, i, 0));
2735  else
2736  printfPQExpBuffer(&buf, "%*s %s",
2737  ctw, "", PQgetvalue(result, i, 0));
2738  }
2739  else
2740  {
2741  if (i == 0)
2742  printfPQExpBuffer(&buf, "%s: %s %s",
2743  ct, PQgetvalue(result, i, 0), PQgetvalue(result, i, 1));
2744  else
2745  printfPQExpBuffer(&buf, "%*s %s %s",
2746  ctw, "", PQgetvalue(result, i, 0), PQgetvalue(result, i, 1));
2747  }
2748  if (i < tuples - 1)
2749  appendPQExpBufferChar(&buf, ',');
2750 
2751  printTableAddFooter(&cont, buf.data);
2752  }
2753  }
2754  PQclear(result);
2755 
2756  /* Table type */
2757  if (tableinfo.reloftype)
2758  {
2759  printfPQExpBuffer(&buf, _("Typed table of type: %s"), tableinfo.reloftype);
2760  printTableAddFooter(&cont, buf.data);
2761  }
2762 
2763  if (verbose && (tableinfo.relkind == 'r' || tableinfo.relkind == 'm') &&
2764 
2765  /*
2766  * No need to display default values; we already display a REPLICA
2767  * IDENTITY marker on indexes.
2768  */
2769  tableinfo.relreplident != 'i' &&
2770  ((strcmp(schemaname, "pg_catalog") != 0 && tableinfo.relreplident != 'd') ||
2771  (strcmp(schemaname, "pg_catalog") == 0 && tableinfo.relreplident != 'n')))
2772  {
2773  const char *s = _("Replica Identity");
2774 
2775  printfPQExpBuffer(&buf, "%s: %s",
2776  s,
2777  tableinfo.relreplident == 'f' ? "FULL" :
2778  tableinfo.relreplident == 'n' ? "NOTHING" :
2779  "???");
2780 
2781  printTableAddFooter(&cont, buf.data);
2782  }
2783 
2784  /* OIDs, if verbose and not a materialized view */
2785  if (verbose && tableinfo.relkind != 'm' && tableinfo.hasoids)
2786  printTableAddFooter(&cont, _("Has OIDs: yes"));
2787 
2788  /* Tablespace info */
2789  add_tablespace_footer(&cont, tableinfo.relkind, tableinfo.tablespace,
2790  true);
2791  }
2792 
2793  /* reloptions, if verbose */
2794  if (verbose &&
2795  tableinfo.reloptions && tableinfo.reloptions[0] != '\0')
2796  {
2797  const char *t = _("Options");
2798 
2799  printfPQExpBuffer(&buf, "%s: %s", t, tableinfo.reloptions);
2800  printTableAddFooter(&cont, buf.data);
2801  }
2802 
2803  printTable(&cont, pset.queryFout, false, pset.logfile);
2804 
2805  retval = true;
2806 
2807 error_return:
2808 
2809  /* clean up */
2810  if (printTableInitialized)
2811  printTableCleanup(&cont);
2812  termPQExpBuffer(&buf);
2813  termPQExpBuffer(&title);
2814  termPQExpBuffer(&tmpbuf);
2815 
2816  if (seq_values)
2817  {
2818  for (ptr = seq_values; *ptr; ptr++)
2819  free(*ptr);
2820  free(seq_values);
2821  }
2822 
2823  if (view_def)
2824  free(view_def);
2825 
2826  if (res)
2827  PQclear(res);
2828 
2829  return retval;
2830 }
signed short int16
Definition: c.h:252
int PQnfields(const PGresult *res)
Definition: fe-exec.c:2681
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
void printTableCleanup(printTableContent *const content)
Definition: print.c:3099
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
const char * fmtId(const char *rawid)
Definition: string_utils.c:66
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
unsigned int Oid
Definition: postgres_ext.h:31
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:2968
unsigned short int expanded
Definition: print.h:99
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3008
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
int pg_wcswidth(const char *pwcs, size_t len, int encoding)
Definition: mbprint.c:177
static char * buf
Definition: pg_test_fsync.c:65
char * tablespace
Definition: pgbench.c:146
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3188
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:60
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:226
static void add_tablespace_footer(printTableContent *const cont, char relkind, Oid tablespace, const bool newline)
Definition: describe.c:2838
printQueryOpt popt
Definition: settings.h:91
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:2931
static StringInfoData tmpbuf
Definition: walsender.c:153
#define atooid(x)
Definition: lo.c:17
int i
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
int encoding
Definition: settings.h:83
int PQgetisnull(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3092
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
static bool describeOneTSConfig ( const char *  oid,
const char *  nspname,
const char *  cfgname,
const char *  pnspname,
const char *  prsname 
)
static

Definition at line 4344 of file describe.c.

References _, appendPQExpBuffer(), buf, PQExpBufferData::data, printTableOpt::default_footer, printQueryOpt::footers, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::topt, and printQueryOpt::translate_header.

Referenced by listTSConfigsVerbose().

4346 {
4348  title;
4349  PGresult *res;
4350  printQueryOpt myopt = pset.popt;
4351 
4352  initPQExpBuffer(&buf);
4353 
4354  printfPQExpBuffer(&buf,
4355  "SELECT \n"
4356  " ( SELECT t.alias FROM \n"
4357  " pg_catalog.ts_token_type(c.cfgparser) AS t \n"
4358  " WHERE t.tokid = m.maptokentype ) AS \"%s\", \n"
4359  " pg_catalog.btrim( \n"
4360  " ARRAY( SELECT mm.mapdict::pg_catalog.regdictionary \n"
4361  " FROM pg_catalog.pg_ts_config_map AS mm \n"
4362  " WHERE mm.mapcfg = m.mapcfg AND mm.maptokentype = m.maptokentype \n"
4363  " ORDER BY mapcfg, maptokentype, mapseqno \n"
4364  " ) :: pg_catalog.text , \n"
4365  " '{}') AS \"%s\" \n"
4366  "FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m \n"
4367  "WHERE c.oid = '%s' AND m.mapcfg = c.oid \n"
4368  "GROUP BY m.mapcfg, m.maptokentype, c.cfgparser \n"
4369  "ORDER BY 1;",
4370  gettext_noop("Token"),
4371  gettext_noop("Dictionaries"),
4372  oid);
4373 
4374  res = PSQLexec(buf.data);
4375  termPQExpBuffer(&buf);
4376  if (!res)
4377  return false;
4378 
4379  initPQExpBuffer(&title);
4380 
4381  if (nspname)
4382  appendPQExpBuffer(&title, _("Text search configuration \"%s.%s\""),
4383  nspname, cfgname);
4384  else
4385  appendPQExpBuffer(&title, _("Text search configuration \"%s\""),
4386  cfgname);
4387 
4388  if (pnspname)
4389  appendPQExpBuffer(&title, _("\nParser: \"%s.%s\""),
4390  pnspname, prsname);
4391  else
4392  appendPQExpBuffer(&title, _("\nParser: \"%s\""),
4393  prsname);
4394 
4395  myopt.nullPrint = NULL;
4396  myopt.title = title.data;
4397  myopt.footers = NULL;
4398  myopt.topt.default_footer = false;
4399  myopt.translate_header = true;
4400 
4401  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4402 
4403  termPQExpBuffer(&title);
4404 
4405  PQclear(res);
4406  return true;
4407 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
char ** footers
Definition: print.h:168
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
static bool describeOneTSParser ( const char *  oid,
const char *  nspname,
const char *  prsname 
)
static

Definition at line 3958 of file describe.c.

References _, buf, PQExpBufferData::data, printTableOpt::default_footer, printQueryOpt::footers, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::topt, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by listTSParsersVerbose().

3959 {
3961  PGresult *res;
3962  char title[1024];
3963  printQueryOpt myopt = pset.popt;
3964  static const bool translate_columns[] = {true, false, false};
3965 
3966  initPQExpBuffer(&buf);
3967 
3968  printfPQExpBuffer(&buf,
3969  "SELECT '%s' AS \"%s\", \n"
3970  " p.prsstart::pg_catalog.regproc AS \"%s\", \n"
3971  " pg_catalog.obj_description(p.prsstart, 'pg_proc') as \"%s\" \n"
3972  " FROM pg_catalog.pg_ts_parser p \n"
3973  " WHERE p.oid = '%s' \n"
3974  "UNION ALL \n"
3975  "SELECT '%s', \n"
3976  " p.prstoken::pg_catalog.regproc, \n"
3977  " pg_catalog.obj_description(p.prstoken, 'pg_proc') \n"
3978  " FROM pg_catalog.pg_ts_parser p \n"
3979  " WHERE p.oid = '%s' \n"
3980  "UNION ALL \n"
3981  "SELECT '%s', \n"
3982  " p.prsend::pg_catalog.regproc, \n"
3983  " pg_catalog.obj_description(p.prsend, 'pg_proc') \n"
3984  " FROM pg_catalog.pg_ts_parser p \n"
3985  " WHERE p.oid = '%s' \n"
3986  "UNION ALL \n"
3987  "SELECT '%s', \n"
3988  " p.prsheadline::pg_catalog.regproc, \n"
3989  " pg_catalog.obj_description(p.prsheadline, 'pg_proc') \n"
3990  " FROM pg_catalog.pg_ts_parser p \n"
3991  " WHERE p.oid = '%s' \n"
3992  "UNION ALL \n"
3993  "SELECT '%s', \n"
3994  " p.prslextype::pg_catalog.regproc, \n"
3995  " pg_catalog.obj_description(p.prslextype, 'pg_proc') \n"
3996  " FROM pg_catalog.pg_ts_parser p \n"
3997  " WHERE p.oid = '%s';",
3998  gettext_noop("Start parse"),
3999  gettext_noop("Method"),
4000  gettext_noop("Function"),
4001  gettext_noop("Description"),
4002  oid,
4003  gettext_noop("Get next token"),
4004  oid,
4005  gettext_noop("End parse"),
4006  oid,
4007  gettext_noop("Get headline"),
4008  oid,
4009  gettext_noop("Get token types"),
4010  oid);
4011 
4012  res = PSQLexec(buf.data);
4013  termPQExpBuffer(&buf);
4014  if (!res)
4015  return false;
4016 
4017  myopt.nullPrint = NULL;
4018  if (nspname)
4019  sprintf(title, _("Text search parser \"%s.%s\""), nspname, prsname);
4020  else
4021  sprintf(title, _("Text search parser \"%s\""), prsname);
4022  myopt.title = title;
4023  myopt.footers = NULL;
4024  myopt.topt.default_footer = false;
4025  myopt.translate_header = true;
4026  myopt.translate_columns = translate_columns;
4027  myopt.n_translate_columns = lengthof(translate_columns);
4028 
4029  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4030 
4031  PQclear(res);
4032 
4033  initPQExpBuffer(&buf);
4034 
4035  printfPQExpBuffer(&buf,
4036  "SELECT t.alias as \"%s\", \n"
4037  " t.description as \"%s\" \n"
4038  "FROM pg_catalog.ts_token_type( '%s'::pg_catalog.oid ) as t \n"
4039  "ORDER BY 1;",
4040  gettext_noop("Token name"),
4041  gettext_noop("Description"),
4042  oid);
4043 
4044  res = PSQLexec(buf.data);
4045  termPQExpBuffer(&buf);
4046  if (!res)
4047  return false;
4048 
4049  myopt.nullPrint = NULL;
4050  if (nspname)
4051  sprintf(title, _("Token types for parser \"%s.%s\""), nspname, prsname);
4052  else
4053  sprintf(title, _("Token types for parser \"%s\""), prsname);
4054  myopt.title = title;
4055  myopt.footers = NULL;
4056  myopt.topt.default_footer = true;
4057  myopt.translate_header = true;
4058  myopt.translate_columns = NULL;
4059  myopt.n_translate_columns = 0;
4060 
4061  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4062 
4063  PQclear(res);
4064  return true;
4065 }
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
#define lengthof(array)
Definition: c.h:558
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
char ** footers
Definition: print.h:168
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeOperators ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 700 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

701 {
703  PGresult *res;
704  printQueryOpt myopt = pset.popt;
705 
706  initPQExpBuffer(&buf);
707 
708  /*
709  * Note: before Postgres 9.1, we did not assign comments to any built-in
710  * operators, preferring to let the comment on the underlying function
711  * suffice. The coalesce() on the obj_description() calls below supports
712  * this convention by providing a fallback lookup of a comment on the
713  * operator's function. As of 9.1 there is a policy that every built-in
714  * operator should have a comment; so the coalesce() is no longer
715  * necessary so far as built-in operators are concerned. We keep it
716  * anyway, for now, because (1) third-party modules may still be following
717  * the old convention, and (2) we'd need to do it anyway when talking to a
718  * pre-9.1 server.
719  */
720 
721  printfPQExpBuffer(&buf,
722  "SELECT n.nspname as \"%s\",\n"
723  " o.oprname AS \"%s\",\n"
724  " CASE WHEN o.oprkind='l' THEN NULL ELSE pg_catalog.format_type(o.oprleft, NULL) END AS \"%s\",\n"
725  " CASE WHEN o.oprkind='r' THEN NULL ELSE pg_catalog.format_type(o.oprright, NULL) END AS \"%s\",\n"
726  " pg_catalog.format_type(o.oprresult, NULL) AS \"%s\",\n",
727  gettext_noop("Schema"),
728  gettext_noop("Name"),
729  gettext_noop("Left arg type"),
730  gettext_noop("Right arg type"),
731  gettext_noop("Result type"));
732 
733  if (verbose)
734  appendPQExpBuffer(&buf,
735  " o.oprcode AS \"%s\",\n",
736  gettext_noop("Function"));
737 
738  appendPQExpBuffer(&buf,
739  " coalesce(pg_catalog.obj_description(o.oid, 'pg_operator'),\n"
740  " pg_catalog.obj_description(o.oprcode, 'pg_proc')) AS \"%s\"\n"
741  "FROM pg_catalog.pg_operator o\n"
742  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = o.oprnamespace\n",
743  gettext_noop("Description"));
744 
745  if (!showSystem && !pattern)
746  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
747  " AND n.nspname <> 'information_schema'\n");
748 
749  processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, true,
750  "n.nspname", "o.oprname", NULL,
751  "pg_catalog.pg_operator_is_visible(o.oid)");
752 
753  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3, 4;");
754 
755  res = PSQLexec(buf.data);
756  termPQExpBuffer(&buf);
757  if (!res)
758  return false;
759 
760  myopt.nullPrint = NULL;
761  myopt.title = _("List of operators");
762  myopt.translate_header = true;
763 
764  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
765 
766  PQclear(res);
767  return true;
768 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describePublications ( const char *  pattern)

Definition at line 4950 of file describe.c.

References _, appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, i, initPQExpBuffer(), _psqlSettings::logfile, NULL, _psqlSettings::popt, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), printTable(), printTableAddCell(), printTableAddFooter(), printTableAddHeader(), printTableCleanup(), printTableInit(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), and printQueryOpt::topt.

Referenced by exec_command().

4951 {
4953  int i;
4954  PGresult *res;
4955 
4956  if (pset.sversion < 100000)
4957  {
4958  char sverbuf[32];
4959  psql_error("The server (version %s) does not support publications.\n",
4961  sverbuf, sizeof(sverbuf)));
4962  return true;
4963  }
4964 
4965  initPQExpBuffer(&buf);
4966 
4967  printfPQExpBuffer(&buf,
4968  "SELECT oid, pubname, puballtables, pubinsert,\n"
4969  " pubupdate, pubdelete\n"
4970  "FROM pg_catalog.pg_publication\n");
4971 
4972  processSQLNamePattern(pset.db, &buf, pattern, false, false,
4973  NULL, "pubname", NULL,
4974  NULL);
4975 
4976  appendPQExpBufferStr(&buf, "ORDER BY 2;");
4977 
4978  res = PSQLexec(buf.data);
4979  if (!res)
4980  {
4981  termPQExpBuffer(&buf);
4982  return false;
4983  }
4984 
4985  for (i = 0; i < PQntuples(res); i++)
4986  {
4987  const char align = 'l';
4988  int ncols = 3;
4989  int nrows = 1;
4990  int tables = 0;
4991  PGresult *tabres;
4992  char *pubid = PQgetvalue(res, i, 0);
4993  char *pubname = PQgetvalue(res, i, 1);
4994  bool puballtables = strcmp(PQgetvalue(res, i, 2), "t") == 0;
4995  int j;
4996  PQExpBufferData title;
4997  printTableOpt myopt = pset.popt.topt;
4998  printTableContent cont;
4999 
5000  initPQExpBuffer(&title);
5001  printfPQExpBuffer(&title, _("Publication %s"), pubname);
5002  printTableInit(&cont, &myopt, title.data, ncols, nrows);
5003 
5004  printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
5005  printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
5006  printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
5007 
5008  printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
5009  printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
5010  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
5011 
5012  if (puballtables)
5013  printfPQExpBuffer(&buf,
5014  "SELECT n.nspname, c.relname\n"
5015  "FROM pg_catalog.pg_class c,\n"
5016  " pg_catalog.pg_namespace n\n"
5017  "WHERE c.relnamespace = n.oid\n"
5018  " AND c.relkind = 'r'\n"
5019  " AND n.nspname <> 'pg_catalog'\n"
5020  " AND n.nspname <> 'information_schema'\n"
5021  "ORDER BY 1,2");
5022  else
5023  printfPQExpBuffer(&buf,
5024  "SELECT n.nspname, c.relname\n"
5025  "FROM pg_catalog.pg_class c,\n"
5026  " pg_catalog.pg_namespace n,\n"
5027  " pg_catalog.pg_publication_rel pr\n"
5028  "WHERE c.relnamespace = n.oid\n"
5029  " AND c.oid = pr.prrelid\n"
5030  " AND pr.prpubid = '%s'\n"
5031  "ORDER BY 1,2", pubid);
5032 
5033  tabres = PSQLexec(buf.data);
5034  if (!tabres)
5035  {
5036  printTableCleanup(&cont);
5037  PQclear(res);
5038  termPQExpBuffer(&buf);
5039  termPQExpBuffer(&title);
5040  return false;
5041  }
5042  else
5043  tables = PQntuples(tabres);
5044 
5045  if (tables > 0)
5046  printTableAddFooter(&cont, _("Tables:"));
5047 
5048  for (j = 0; j < tables; j++)
5049  {
5050  printfPQExpBuffer(&buf, " \"%s.%s\"",
5051  PQgetvalue(tabres, j, 0),
5052  PQgetvalue(tabres, j, 1));
5053 
5054  printTableAddFooter(&cont, buf.data);
5055  }
5056  PQclear(tabres);
5057 
5058  printTable(&cont, pset.queryFout, false, pset.logfile);
5059  printTableCleanup(&cont);
5060 
5061  termPQExpBuffer(&title);
5062  }
5063 
5064  termPQExpBuffer(&buf);
5065  PQclear(res);
5066 
5067  return true;
5068 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
void printTableCleanup(printTableContent *const content)
Definition: print.c:3099
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:2968
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3008
static char * buf
Definition: pg_test_fsync.c:65
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3188
void psql_error(const char *fmt,...)
Definition: common.c:177
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:2931
int i
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeRoles ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 2896 of file describe.c.

References _, add_role_attribute(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), buf, conns, PQExpBufferData::data, _psqlSettings::db, printTableOpt::default_footer, free, gettext_noop, i, initPQExpBuffer(), PQExpBufferData::len, _psqlSettings::logfile, ngettext, NULL, pg_malloc0(), pg_strdup(), _psqlSettings::popt, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), printTable(), printTableAddCell(), printTableAddHeader(), printTableCleanup(), printTableInit(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, resetPQExpBuffer(), _psqlSettings::sversion, termPQExpBuffer(), and printQueryOpt::topt.

Referenced by exec_command().

2897 {
2899  PGresult *res;
2900  printTableContent cont;
2901  printTableOpt myopt = pset.popt.topt;
2902  int ncols = 3;
2903  int nrows = 0;
2904  int i;
2905  int conns;
2906  const char align = 'l';
2907  char **attr;
2908 
2909  myopt.default_footer = false;
2910 
2911  initPQExpBuffer(&buf);
2912 
2913  if (pset.sversion >= 80100)
2914  {
2915  printfPQExpBuffer(&buf,
2916  "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
2917  " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
2918  " r.rolconnlimit, r.rolvaliduntil,\n"
2919  " ARRAY(SELECT b.rolname\n"
2920  " FROM pg_catalog.pg_auth_members m\n"
2921  " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
2922  " WHERE m.member = r.oid) as memberof");
2923 
2924  if (verbose && pset.sversion >= 80200)
2925  {
2926  appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
2927  ncols++;
2928  }
2929  if (pset.sversion >= 90100)
2930  {
2931  appendPQExpBufferStr(&buf, "\n, r.rolreplication");
2932  }
2933 
2934  if (pset.sversion >= 90500)
2935  {
2936  appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
2937  }
2938 
2939  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
2940 
2941  if (!showSystem && !pattern)
2942  appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
2943 
2944  processSQLNamePattern(pset.db, &buf, pattern, false, false,
2945  NULL, "r.rolname", NULL, NULL);
2946  }
2947  else
2948  {
2949  printfPQExpBuffer(&buf,
2950  "SELECT u.usename AS rolname,\n"
2951  " u.usesuper AS rolsuper,\n"
2952  " true AS rolinherit, false AS rolcreaterole,\n"
2953  " u.usecreatedb AS rolcreatedb, true AS rolcanlogin,\n"
2954  " -1 AS rolconnlimit,"
2955  " u.valuntil as rolvaliduntil,\n"
2956  " ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as memberof"
2957  "\nFROM pg_catalog.pg_user u\n");
2958 
2959  processSQLNamePattern(pset.db, &buf, pattern, false, false,
2960  NULL, "u.usename", NULL, NULL);
2961  }
2962 
2963  appendPQExpBufferStr(&buf, "ORDER BY 1;");
2964 
2965  res = PSQLexec(buf.data);
2966  if (!res)
2967  return false;
2968 
2969  nrows = PQntuples(res);
2970  attr = pg_malloc0((nrows + 1) * sizeof(*attr));
2971 
2972  printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
2973 
2974  printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
2975  printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
2976  printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
2977 
2978  if (verbose && pset.sversion >= 80200)
2979  printTableAddHeader(&cont, gettext_noop("Description"), true, align);
2980 
2981  for (i = 0; i < nrows; i++)
2982  {
2983  printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
2984 
2985  resetPQExpBuffer(&buf);
2986  if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
2987  add_role_attribute(&buf, _("Superuser"));
2988 
2989  if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
2990  add_role_attribute(&buf, _("No inheritance"));
2991 
2992  if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
2993  add_role_attribute(&buf, _("Create role"));
2994 
2995  if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
2996  add_role_attribute(&buf, _("Create DB"));
2997 
2998  if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
2999  add_role_attribute(&buf, _("Cannot login"));
3000 
3001  if (pset.sversion >= 90100)
3002  if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3003  add_role_attribute(&buf, _("Replication"));
3004 
3005  if (pset.sversion >= 90500)
3006  if (strcmp(PQgetvalue(res, i, (verbose ? 11 : 10)), "t") == 0)
3007  add_role_attribute(&buf, _("Bypass RLS"));
3008 
3009  conns = atoi(PQgetvalue(res, i, 6));
3010  if (conns >= 0)
3011  {
3012  if (buf.len > 0)
3013  appendPQExpBufferChar(&buf, '\n');
3014 
3015  if (conns == 0)
3016  appendPQExpBufferStr(&buf, _("No connections"));
3017  else
3018  appendPQExpBuffer(&buf, ngettext("%d connection",
3019  "%d connections",
3020  conns),
3021  conns);
3022  }
3023 
3024  if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3025  {
3026  if (buf.len > 0)
3027  appendPQExpBufferStr(&buf, "\n");
3028  appendPQExpBufferStr(&buf, _("Password valid until "));
3029  appendPQExpBufferStr(&buf, PQgetvalue(res, i, 7));
3030  }
3031 
3032  attr[i] = pg_strdup(buf.data);
3033 
3034  printTableAddCell(&cont, attr[i], false, false);
3035 
3036  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3037 
3038  if (verbose && pset.sversion >= 80200)
3039  printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
3040  }
3041  termPQExpBuffer(&buf);
3042 
3043  printTable(&cont, pset.queryFout, false, pset.logfile);
3044  printTableCleanup(&cont);
3045 
3046  for (i = 0; i < nrows; i++)
3047  free(attr[i]);
3048  free(attr);
3049 
3050  PQclear(res);
3051  return true;
3052 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
void printTableCleanup(printTableContent *const content)
Definition: print.c:3099
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
printTableOpt topt
Definition: print.h:165
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static void add_role_attribute(PQExpBuffer buf, const char *const str)
Definition: describe.c:3055
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:2968
static PGconn ** conns
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3008
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3188
static int verbose
Definition: pg_basebackup.c:86
#define ngettext(s, p, n)
Definition: c.h:127
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:60
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:2931
int i
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeSubscriptions ( const char *  pattern,
bool  verbose 
)

Definition at line 5076 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

5077 {
5079  PGresult *res;
5080  printQueryOpt myopt = pset.popt;
5081  static const bool translate_columns[] = {false, false, false, false, false};
5082 
5083  if (pset.sversion < 100000)
5084  {
5085  char sverbuf[32];
5086  psql_error("The server (version %s) does not support subscriptions.\n",
5088  sverbuf, sizeof(sverbuf)));
5089  return true;
5090  }
5091 
5092  initPQExpBuffer(&buf);
5093 
5094  printfPQExpBuffer(&buf,
5095  "SELECT subname AS \"%s\"\n"
5096  ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
5097  ", subenabled AS \"%s\"\n"
5098  ", subpublications AS \"%s\"\n",
5099  gettext_noop("Name"),
5100  gettext_noop("Owner"),
5101  gettext_noop("Enabled"),
5102  gettext_noop("Publication"));
5103 
5104  if (verbose)
5105  {
5106  appendPQExpBuffer(&buf,
5107  ", subconninfo AS \"%s\"\n",
5108  gettext_noop("Conninfo"));
5109  }
5110 
5111  /* Only display subscriptions in current database. */
5112  appendPQExpBufferStr(&buf,
5113  "FROM pg_catalog.pg_subscription\n"
5114  "WHERE subdbid = (SELECT oid\n"
5115  " FROM pg_catalog.pg_database\n"
5116  " WHERE datname = current_database())");
5117 
5118  processSQLNamePattern(pset.db, &buf, pattern, true, false,
5119  NULL, "subname", NULL,
5120  NULL);
5121 
5122  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5123 
5124  res = PSQLexec(buf.data);
5125  termPQExpBuffer(&buf);
5126  if (!res)
5127  return false;
5128 
5129  myopt.nullPrint = NULL;
5130  myopt.title = _("List of subscriptions");
5131  myopt.translate_header = true;
5132  myopt.translate_columns = translate_columns;
5133  myopt.n_translate_columns = lengthof(translate_columns);
5134 
5135  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5136 
5137  PQclear(res);
5138  return true;
5139 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeTableDetails ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 1276 of file describe.c.

References appendPQExpBufferStr(), buf, cancel_pressed, PQExpBufferData::data, _psqlSettings::db, describeOneTableDetails(), i, initPQExpBuffer(), NULL, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::quiet, and termPQExpBuffer().

Referenced by exec_command().

1277 {
1279  PGresult *res;
1280  int i;
1281 
1282  initPQExpBuffer(&buf);
1283 
1284  printfPQExpBuffer(&buf,
1285  "SELECT c.oid,\n"
1286  " n.nspname,\n"
1287  " c.relname\n"
1288  "FROM pg_catalog.pg_class c\n"
1289  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n");
1290 
1291  if (!showSystem && !pattern)
1292  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1293  " AND n.nspname <> 'information_schema'\n");
1294 
1295  processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, false,
1296  "n.nspname", "c.relname", NULL,
1297  "pg_catalog.pg_table_is_visible(c.oid)");
1298 
1299  appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
1300 
1301  res = PSQLexec(buf.data);
1302  termPQExpBuffer(&buf);
1303  if (!res)
1304  return false;
1305 
1306  if (PQntuples(res) == 0)
1307  {
1308  if (!pset.quiet)
1309  psql_error("Did not find any relation named \"%s\".\n",
1310  pattern);
1311  PQclear(res);
1312  return false;
1313  }
1314 
1315  for (i = 0; i < PQntuples(res); i++)
1316  {
1317  const char *oid;
1318  const char *nspname;
1319  const char *relname;
1320 
1321  oid = PQgetvalue(res, i, 0);
1322  nspname = PQgetvalue(res, i, 1);
1323  relname = PQgetvalue(res, i, 2);
1324 
1325  if (!describeOneTableDetails(nspname, relname, oid, verbose))
1326  {
1327  PQclear(res);
1328  return false;
1329  }
1330  if (cancel_pressed)
1331  {
1332  PQclear(res);
1333  return false;
1334  }
1335  }
1336 
1337  PQclear(res);
1338  return true;
1339 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
volatile bool cancel_pressed
Definition: print.c:46
static char * buf
Definition: pg_test_fsync.c:65
static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, bool verbose)
Definition: describe.c:1349
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:226
int i
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeTablespaces ( const char *  pattern,
bool  verbose 
)

Definition at line 203 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

204 {
206  PGresult *res;
207  printQueryOpt myopt = pset.popt;
208 
209  if (pset.sversion < 80000)
210  {
211  char sverbuf[32];
212 
213  psql_error("The server (version %s) does not support tablespaces.\n",
215  sverbuf, sizeof(sverbuf)));
216  return true;
217  }
218 
219  initPQExpBuffer(&buf);
220 
221  if (pset.sversion >= 90200)
222  printfPQExpBuffer(&buf,
223  "SELECT spcname AS \"%s\",\n"
224  " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
225  " pg_catalog.pg_tablespace_location(oid) AS \"%s\"",
226  gettext_noop("Name"),
227  gettext_noop("Owner"),
228  gettext_noop("Location"));
229  else
230  printfPQExpBuffer(&buf,
231  "SELECT spcname AS \"%s\",\n"
232  " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
233  " spclocation AS \"%s\"",
234  gettext_noop("Name"),
235  gettext_noop("Owner"),
236  gettext_noop("Location"));
237 
238  if (verbose)
239  {
240  appendPQExpBufferStr(&buf, ",\n ");
241  printACLColumn(&buf, "spcacl");
242  }
243 
244  if (verbose && pset.sversion >= 90000)
245  appendPQExpBuffer(&buf,
246  ",\n spcoptions AS \"%s\"",
247  gettext_noop("Options"));
248 
249  if (verbose && pset.sversion >= 90200)
250  appendPQExpBuffer(&buf,
251  ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
252  gettext_noop("Size"));
253 
254  if (verbose && pset.sversion >= 80200)
255  appendPQExpBuffer(&buf,
256  ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
257  gettext_noop("Description"));
258 
260  "\nFROM pg_catalog.pg_tablespace\n");
261 
262  processSQLNamePattern(pset.db, &buf, pattern, false, false,
263  NULL, "spcname", NULL,
264  NULL);
265 
266  appendPQExpBufferStr(&buf, "ORDER BY 1;");
267 
268  res = PSQLexec(buf.data);
269  termPQExpBuffer(&buf);
270  if (!res)
271  return false;
272 
273  myopt.nullPrint = NULL;
274  myopt.title = _("List of tablespaces");
275  myopt.translate_header = true;
276 
277  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
278 
279  PQclear(res);
280  return true;
281 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool describeTypes ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 586 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

587 {
589  PGresult *res;
590  printQueryOpt myopt = pset.popt;
591 
592  initPQExpBuffer(&buf);
593 
594  printfPQExpBuffer(&buf,
595  "SELECT n.nspname as \"%s\",\n"
596  " pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
597  gettext_noop("Schema"),
598  gettext_noop("Name"));
599  if (verbose)
600  appendPQExpBuffer(&buf,
601  " t.typname AS \"%s\",\n"
602  " CASE WHEN t.typrelid != 0\n"
603  " THEN CAST('tuple' AS pg_catalog.text)\n"
604  " WHEN t.typlen < 0\n"
605  " THEN CAST('var' AS pg_catalog.text)\n"
606  " ELSE CAST(t.typlen AS pg_catalog.text)\n"
607  " END AS \"%s\",\n",
608  gettext_noop("Internal name"),
609  gettext_noop("Size"));
610  if (verbose && pset.sversion >= 80300)
611  {
613  " pg_catalog.array_to_string(\n"
614  " ARRAY(\n"
615  " SELECT e.enumlabel\n"
616  " FROM pg_catalog.pg_enum e\n"
617  " WHERE e.enumtypid = t.oid\n");
618 
619  if (pset.sversion >= 90100)
621  " ORDER BY e.enumsortorder\n");
622  else
624  " ORDER BY e.oid\n");
625 
626  appendPQExpBuffer(&buf,
627  " ),\n"
628  " E'\\n'\n"
629  " ) AS \"%s\",\n",
630  gettext_noop("Elements"));
631  }
632  if (verbose)
633  {
634  appendPQExpBuffer(&buf,
635  " pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
636  gettext_noop("Owner"));
637  }
638  if (verbose && pset.sversion >= 90200)
639  {
640  printACLColumn(&buf, "t.typacl");
641  appendPQExpBufferStr(&buf, ",\n ");
642  }
643 
644  appendPQExpBuffer(&buf,
645  " pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n",
646  gettext_noop("Description"));
647 
648  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_type t\n"
649  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
650 
651  /*
652  * do not include complex types (typrelid!=0) unless they are standalone
653  * composite types
654  */
655  appendPQExpBufferStr(&buf, "WHERE (t.typrelid = 0 ");
656  appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c "
657  "WHERE c.oid = t.typrelid))\n");
658 
659  /*
660  * do not include array types (before 8.3 we have to use the assumption
661  * that their names start with underscore)
662  */
663  if (pset.sversion >= 80300)
664  appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n");
665  else
666  appendPQExpBufferStr(&buf, " AND t.typname !~ '^_'\n");
667 
668  if (!showSystem && !pattern)
669  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
670  " AND n.nspname <> 'information_schema'\n");
671 
672  /* Match name pattern against either internal or external name */
673  processSQLNamePattern(pset.db, &buf, pattern, true, false,
674  "n.nspname", "t.typname",
675  "pg_catalog.format_type(t.oid, NULL)",
676  "pg_catalog.pg_type_is_visible(t.oid)");
677 
678  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
679 
680  res = PSQLexec(buf.data);
681  termPQExpBuffer(&buf);
682  if (!res)
683  return false;
684 
685  myopt.nullPrint = NULL;
686  myopt.title = _("List of data types");
687  myopt.translate_header = true;
688 
689  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
690 
691  PQclear(res);
692  return true;
693 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listAllDbs ( const char *  pattern,
bool  verbose 
)

Definition at line 777 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command(), and main().

778 {
779  PGresult *res;
781  printQueryOpt myopt = pset.popt;
782 
783  initPQExpBuffer(&buf);
784 
785  printfPQExpBuffer(&buf,
786  "SELECT d.datname as \"%s\",\n"
787  " pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
788  " pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n",
789  gettext_noop("Name"),
790  gettext_noop("Owner"),
791  gettext_noop("Encoding"));
792  if (pset.sversion >= 80400)
793  appendPQExpBuffer(&buf,
794  " d.datcollate as \"%s\",\n"
795  " d.datctype as \"%s\",\n",
796  gettext_noop("Collate"),
797  gettext_noop("Ctype"));
798  appendPQExpBufferStr(&buf, " ");
799  printACLColumn(&buf, "d.datacl");
800  if (verbose && pset.sversion >= 80200)
801  appendPQExpBuffer(&buf,
802  ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
803  " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
804  " ELSE 'No Access'\n"
805  " END as \"%s\"",
806  gettext_noop("Size"));
807  if (verbose && pset.sversion >= 80000)
808  appendPQExpBuffer(&buf,
809  ",\n t.spcname as \"%s\"",
810  gettext_noop("Tablespace"));
811  if (verbose && pset.sversion >= 80200)
812  appendPQExpBuffer(&buf,
813  ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
814  gettext_noop("Description"));
816  "\nFROM pg_catalog.pg_database d\n");
817  if (verbose && pset.sversion >= 80000)
819  " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
820 
821  if (pattern)
822  processSQLNamePattern(pset.db, &buf, pattern, false, false,
823  NULL, "d.datname", NULL, NULL);
824 
825  appendPQExpBufferStr(&buf, "ORDER BY 1;");
826  res = PSQLexec(buf.data);
827  termPQExpBuffer(&buf);
828  if (!res)
829  return false;
830 
831  myopt.nullPrint = NULL;
832  myopt.title = _("List of databases");
833  myopt.translate_header = true;
834 
835  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
836 
837  PQclear(res);
838  return true;
839 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listCasts ( const char *  pattern,
bool  verbose 
)

Definition at line 3600 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

3601 {
3603  PGresult *res;
3604  printQueryOpt myopt = pset.popt;
3605  static const bool translate_columns[] = {false, false, false, true, false};
3606 
3607  initPQExpBuffer(&buf);
3608 
3609  /*
3610  * We need a left join to pg_proc for binary casts; the others are just
3611  * paranoia. Also note that we don't attempt to localize '(binary
3612  * coercible)', because there's too much risk of gettext translating a
3613  * function name that happens to match some string in the PO database.
3614  */
3615  printfPQExpBuffer(&buf,
3616  "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n"
3617  " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n"
3618  " CASE WHEN castfunc = 0 THEN '(binary coercible)'\n"
3619  " ELSE p.proname\n"
3620  " END as \"%s\",\n"
3621  " CASE WHEN c.castcontext = 'e' THEN '%s'\n"
3622  " WHEN c.castcontext = 'a' THEN '%s'\n"
3623  " ELSE '%s'\n"
3624  " END as \"%s\"",
3625  gettext_noop("Source type"),
3626  gettext_noop("Target type"),
3627  gettext_noop("Function"),
3628  gettext_noop("no"),
3629  gettext_noop("in assignment"),
3630  gettext_noop("yes"),
3631  gettext_noop("Implicit?"));
3632 
3633  if (verbose)
3634  appendPQExpBuffer(&buf,
3635  ",\n d.description AS \"%s\"\n",
3636  gettext_noop("Description"));
3637 
3638  appendPQExpBufferStr(&buf,
3639  "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
3640  " ON c.castfunc = p.oid\n"
3641  " LEFT JOIN pg_catalog.pg_type ts\n"
3642  " ON c.castsource = ts.oid\n"
3643  " LEFT JOIN pg_catalog.pg_namespace ns\n"
3644  " ON ns.oid = ts.typnamespace\n"
3645  " LEFT JOIN pg_catalog.pg_type tt\n"
3646  " ON c.casttarget = tt.oid\n"
3647  " LEFT JOIN pg_catalog.pg_namespace nt\n"
3648  " ON nt.oid = tt.typnamespace\n");
3649 
3650  if (verbose)
3651  appendPQExpBufferStr(&buf,
3652  " LEFT JOIN pg_catalog.pg_description d\n"
3653  " ON d.classoid = c.tableoid AND d.objoid = "
3654  "c.oid AND d.objsubid = 0\n");
3655 
3656  appendPQExpBufferStr(&buf, "WHERE ( (true");
3657 
3658  /*
3659  * Match name pattern against either internal or external name of either
3660  * castsource or casttarget
3661  */
3662  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3663  "ns.nspname", "ts.typname",
3664  "pg_catalog.format_type(ts.oid, NULL)",
3665  "pg_catalog.pg_type_is_visible(ts.oid)");
3666 
3667  appendPQExpBufferStr(&buf, ") OR (true");
3668 
3669  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3670  "nt.nspname", "tt.typname",
3671  "pg_catalog.format_type(tt.oid, NULL)",
3672  "pg_catalog.pg_type_is_visible(tt.oid)");
3673 
3674  appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
3675 
3676  res = PSQLexec(buf.data);
3677  termPQExpBuffer(&buf);
3678  if (!res)
3679  return false;
3680 
3681  myopt.nullPrint = NULL;
3682  myopt.title = _("List of casts");
3683  myopt.translate_header = true;
3684  myopt.translate_columns = translate_columns;
3685  myopt.n_translate_columns = lengthof(translate_columns);
3686 
3687  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3688 
3689  PQclear(res);
3690  return true;
3691 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listCollations ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3699 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

3700 {
3702  PGresult *res;
3703  printQueryOpt myopt = pset.popt;
3704  static const bool translate_columns[] = {false, false, false, false, false};
3705 
3706  if (pset.sversion < 90100)
3707  {
3708  char sverbuf[32];
3709 
3710  psql_error("The server (version %s) does not support collations.\n",
3712  sverbuf, sizeof(sverbuf)));
3713  return true;
3714  }
3715 
3716  initPQExpBuffer(&buf);
3717 
3718  printfPQExpBuffer(&buf,
3719  "SELECT n.nspname AS \"%s\",\n"
3720  " c.collname AS \"%s\",\n"
3721  " c.collcollate AS \"%s\",\n"
3722  " c.collctype AS \"%s\"",
3723  gettext_noop("Schema"),
3724  gettext_noop("Name"),
3725  gettext_noop("Collate"),
3726  gettext_noop("Ctype"));
3727 
3728  if (verbose)
3729  appendPQExpBuffer(&buf,
3730  ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
3731  gettext_noop("Description"));
3732 
3733  appendPQExpBufferStr(&buf,
3734  "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
3735  "WHERE n.oid = c.collnamespace\n");
3736 
3737  if (!showSystem && !pattern)
3738  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3739  " AND n.nspname <> 'information_schema'\n");
3740 
3741  /*
3742  * Hide collations that aren't usable in the current database's encoding.
3743  * If you think to change this, note that pg_collation_is_visible rejects
3744  * unusable collations, so you will need to hack name pattern processing
3745  * somehow to avoid inconsistent behavior.
3746  */
3747  appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
3748 
3749  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3750  "n.nspname", "c.collname", NULL,
3751  "pg_catalog.pg_collation_is_visible(c.oid)");
3752 
3753  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3754 
3755  res = PSQLexec(buf.data);
3756  termPQExpBuffer(&buf);
3757  if (!res)
3758  return false;
3759 
3760  myopt.nullPrint = NULL;
3761  myopt.title = _("List of collations");
3762  myopt.translate_header = true;
3763  myopt.translate_columns = translate_columns;
3764  myopt.n_translate_columns = lengthof(translate_columns);
3765 
3766  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3767 
3768  PQclear(res);
3769  return true;
3770 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listConversions ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3458 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

3459 {
3461  PGresult *res;
3462  printQueryOpt myopt = pset.popt;
3463  static const bool translate_columns[] =
3464  {false, false, false, false, true, false};
3465 
3466  initPQExpBuffer(&buf);
3467 
3468  printfPQExpBuffer(&buf,
3469  "SELECT n.nspname AS \"%s\",\n"
3470  " c.conname AS \"%s\",\n"
3471  " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
3472  " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
3473  " CASE WHEN c.condefault THEN '%s'\n"
3474  " ELSE '%s' END AS \"%s\"",
3475  gettext_noop("Schema"),
3476  gettext_noop("Name"),
3477  gettext_noop("Source"),
3478  gettext_noop("Destination"),
3479  gettext_noop("yes"), gettext_noop("no"),
3480  gettext_noop("Default?"));
3481 
3482  if (verbose)
3483  appendPQExpBuffer(&buf,
3484  ",\n d.description AS \"%s\"",
3485  gettext_noop("Description"));
3486 
3487  appendPQExpBufferStr(&buf,
3488  "\nFROM pg_catalog.pg_conversion c\n"
3489  " JOIN pg_catalog.pg_namespace n "
3490  "ON n.oid = c.connamespace\n");
3491 
3492  if (verbose)
3493  appendPQExpBufferStr(&buf,
3494  "LEFT JOIN pg_catalog.pg_description d "
3495  "ON d.classoid = c.tableoid\n"
3496  " AND d.objoid = c.oid "
3497  "AND d.objsubid = 0\n");
3498 
3499  appendPQExpBufferStr(&buf, "WHERE true\n");
3500 
3501  if (!showSystem && !pattern)
3502  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3503  " AND n.nspname <> 'information_schema'\n");
3504 
3505  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3506  "n.nspname", "c.conname", NULL,
3507  "pg_catalog.pg_conversion_is_visible(c.oid)");
3508 
3509  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3510 
3511  res = PSQLexec(buf.data);
3512  termPQExpBuffer(&buf);
3513  if (!res)
3514  return false;
3515 
3516  myopt.nullPrint = NULL;
3517  myopt.title = _("List of conversions");
3518  myopt.translate_header = true;
3519  myopt.translate_columns = translate_columns;
3520  myopt.n_translate_columns = lengthof(translate_columns);
3521 
3522  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3523 
3524  PQclear(res);
3525  return true;
3526 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listDbRoleSettings ( const char *  pattern,
const char *  pattern2 
)

Definition at line 3067 of file describe.c.

References _, appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), PQntuples(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, resetPQExpBuffer(), _psqlSettings::sversion, printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

3068 {
3070  PGresult *res;
3071  printQueryOpt myopt = pset.popt;
3072 
3073  initPQExpBuffer(&buf);
3074 
3075  if (pset.sversion >= 90000)
3076  {
3077  bool havewhere;
3078 
3079  printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
3080  "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
3081  "FROM pg_db_role_setting AS s\n"
3082  "LEFT JOIN pg_database ON pg_database.oid = setdatabase\n"
3083  "LEFT JOIN pg_roles ON pg_roles.oid = setrole\n",
3084  gettext_noop("Role"),
3085  gettext_noop("Database"),
3086  gettext_noop("Settings"));
3087  havewhere = processSQLNamePattern(pset.db, &buf, pattern, false, false,
3088  NULL, "pg_roles.rolname", NULL, NULL);
3089  processSQLNamePattern(pset.db, &buf, pattern2, havewhere, false,
3090  NULL, "pg_database.datname", NULL, NULL);
3091  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3092  }
3093  else
3094  {
3095  fprintf(pset.queryFout,
3096  _("No per-database role settings support in this server version.\n"));
3097  return false;
3098  }
3099 
3100  res = PSQLexec(buf.data);
3101  if (!res)
3102  return false;
3103 
3104  if (PQntuples(res) == 0 && !pset.quiet)
3105  {
3106  if (pattern)
3107  fprintf(pset.queryFout, _("No matching settings found.\n"));
3108  else
3109  fprintf(pset.queryFout, _("No settings found.\n"));
3110  }
3111  else
3112  {
3113  myopt.nullPrint = NULL;
3114  myopt.title = _("List of settings");
3115  myopt.translate_header = true;
3116 
3117  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3118  }
3119 
3120  PQclear(res);
3121  resetPQExpBuffer(&buf);
3122  return true;
3123 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listDefaultACLs ( const char *  pattern)

Definition at line 1001 of file describe.c.

References _, appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, DEFACLOBJ_FUNCTION, DEFACLOBJ_RELATION, DEFACLOBJ_SEQUENCE, DEFACLOBJ_TYPE, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

1002 {
1004  PGresult *res;
1005  printQueryOpt myopt = pset.popt;
1006  static const bool translate_columns[] = {false, false, true, false};
1007 
1008  if (pset.sversion < 90000)
1009  {
1010  char sverbuf[32];
1011 
1012  psql_error("The server (version %s) does not support altering default privileges.\n",
1014  sverbuf, sizeof(sverbuf)));
1015  return true;
1016  }
1017 
1018  initPQExpBuffer(&buf);
1019 
1020  printfPQExpBuffer(&buf,
1021  "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
1022  " n.nspname AS \"%s\",\n"
1023  " CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
1024  " ",
1025  gettext_noop("Owner"),
1026  gettext_noop("Schema"),
1028  gettext_noop("table"),
1030  gettext_noop("sequence"),
1032  gettext_noop("function"),
1034  gettext_noop("type"),
1035  gettext_noop("Type"));
1036 
1037  printACLColumn(&buf, "d.defaclacl");
1038 
1039  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
1040  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
1041 
1042  processSQLNamePattern(pset.db, &buf, pattern, false, false,
1043  NULL,
1044  "n.nspname",
1045  "pg_catalog.pg_get_userbyid(d.defaclrole)",
1046  NULL);
1047 
1048  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1049 
1050  res = PSQLexec(buf.data);
1051  if (!res)
1052  {
1053  termPQExpBuffer(&buf);
1054  return false;
1055  }
1056 
1057  myopt.nullPrint = NULL;
1058  printfPQExpBuffer(&buf, _("Default access privileges"));
1059  myopt.title = buf.data;
1060  myopt.translate_header = true;
1061  myopt.translate_columns = translate_columns;
1062  myopt.n_translate_columns = lengthof(translate_columns);
1063 
1064  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1065 
1066  termPQExpBuffer(&buf);
1067  PQclear(res);
1068  return true;
1069 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
#define DEFACLOBJ_SEQUENCE
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
#define DEFACLOBJ_TYPE
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define DEFACLOBJ_RELATION
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
#define DEFACLOBJ_FUNCTION
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listDomains ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3372 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

3373 {
3375  PGresult *res;
3376  printQueryOpt myopt = pset.popt;
3377 
3378  initPQExpBuffer(&buf);
3379 
3380  printfPQExpBuffer(&buf,
3381  "SELECT n.nspname as \"%s\",\n"
3382  " t.typname as \"%s\",\n"
3383  " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n",
3384  gettext_noop("Schema"),
3385  gettext_noop("Name"),
3386  gettext_noop("Type"));
3387 
3388  if (pset.sversion >= 90100)
3389  appendPQExpBuffer(&buf,
3390  " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
3391  " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n",
3392  gettext_noop("Collation"));
3393  appendPQExpBuffer(&buf,
3394  " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
3395  " t.typdefault as \"%s\",\n"
3396  " pg_catalog.array_to_string(ARRAY(\n"
3397  " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
3398  " ), ' ') as \"%s\"",
3399  gettext_noop("Nullable"),
3400  gettext_noop("Default"),
3401  gettext_noop("Check"));
3402 
3403  if (verbose)
3404  {
3405  if (pset.sversion >= 90200)
3406  {
3407  appendPQExpBufferStr(&buf, ",\n ");
3408  printACLColumn(&buf, "t.typacl");
3409  }
3410  appendPQExpBuffer(&buf,
3411  ",\n d.description as \"%s\"",
3412  gettext_noop("Description"));
3413  }
3414 
3415  appendPQExpBufferStr(&buf,
3416  "\nFROM pg_catalog.pg_type t\n"
3417  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
3418 
3419  if (verbose)
3420  appendPQExpBufferStr(&buf,
3421  " LEFT JOIN pg_catalog.pg_description d "
3422  "ON d.classoid = t.tableoid AND d.objoid = t.oid "
3423  "AND d.objsubid = 0\n");
3424 
3425  appendPQExpBufferStr(&buf, "WHERE t.typtype = 'd'\n");
3426 
3427  if (!showSystem && !pattern)
3428  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3429  " AND n.nspname <> 'information_schema'\n");
3430 
3431  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3432  "n.nspname", "t.typname", NULL,
3433  "pg_catalog.pg_type_is_visible(t.oid)");
3434 
3435  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3436 
3437  res = PSQLexec(buf.data);
3438  termPQExpBuffer(&buf);
3439  if (!res)
3440  return false;
3441 
3442  myopt.nullPrint = NULL;
3443  myopt.title = _("List of domains");
3444  myopt.translate_header = true;
3445 
3446  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3447 
3448  PQclear(res);
3449  return true;
3450 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:5149
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listEventTriggers ( const char *  pattern,
bool  verbose 
)

Definition at line 3534 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, and printQueryOpt::translate_header.

Referenced by exec_command().

3535 {
3537  PGresult *res;
3538  printQueryOpt myopt = pset.popt;
3539  static const bool translate_columns[] =
3540  {false, false, false, true, false, false, false};
3541 
3542  initPQExpBuffer(&buf);
3543 
3544  printfPQExpBuffer(&buf,
3545  "SELECT evtname as \"%s\", "
3546  "evtevent as \"%s\", "
3547  "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n"
3548  " case evtenabled when 'O' then '%s'"
3549  " when 'R' then '%s'"
3550  " when 'A' then '%s'"
3551  " when 'D' then '%s' end as \"%s\",\n"
3552  " e.evtfoid::pg_catalog.regproc as \"%s\", "
3553  "pg_catalog.array_to_string(array(select x"
3554  " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
3555  gettext_noop("Name"),
3556  gettext_noop("Event"),
3557  gettext_noop("Owner"),
3558  gettext_noop("enabled"),
3559  gettext_noop("replica"),
3560  gettext_noop("always"),
3561  gettext_noop("disabled"),
3562  gettext_noop("Enabled"),
3563  gettext_noop("Procedure"),
3564  gettext_noop("Tags"));
3565  if (verbose)
3566  appendPQExpBuffer(&buf,
3567  ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
3568  gettext_noop("Description"));
3569  appendPQExpBufferStr(&buf,
3570  "\nFROM pg_catalog.pg_event_trigger e ");
3571 
3572  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3573  NULL, "evtname", NULL, NULL);
3574 
3575  appendPQExpBufferStr(&buf, "ORDER BY 1");
3576 
3577  res = PSQLexec(buf.data);
3578  termPQExpBuffer(&buf);
3579  if (!res)
3580  return false;
3581 
3582  myopt.nullPrint = NULL;
3583  myopt.title = _("List of event triggers");
3584  myopt.translate_header = true;
3585  myopt.translate_columns = translate_columns;
3586  myopt.n_translate_columns = lengthof(translate_columns);
3587 
3588  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3589 
3590  PQclear(res);
3591  return true;
3592 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
#define lengthof(array)
Definition: c.h:558
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:86
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
int n_translate_columns
Definition: print.h:172
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
const bool * translate_columns
Definition: print.h:170
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listExtensionContents ( const char *  pattern)

Definition at line 4777 of file describe.c.

References appendPQExpBufferStr(), buf, cancel_pressed, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), i, initPQExpBuffer(), listOneExtensionContents(), NULL, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::quiet, _psqlSettings::sversion, and termPQExpBuffer().

Referenced by exec_command().

4778 {
4780  PGresult *res;
4781  int i;
4782 
4783  if (pset.sversion < 90100)
4784  {
4785  char sverbuf[32];
4786 
4787  psql_error("The server (version %s) does not support extensions.\n",
4789  sverbuf, sizeof(sverbuf)));
4790  return true;
4791  }
4792 
4793  initPQExpBuffer(&buf);
4794  printfPQExpBuffer(&buf,
4795  "SELECT e.extname, e.oid\n"
4796  "FROM pg_catalog.pg_extension e\n");
4797 
4798  processSQLNamePattern(pset.db, &buf, pattern,
4799  false, false,
4800  NULL, "e.extname", NULL,
4801  NULL);
4802 
4803  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4804 
4805  res = PSQLexec(buf.data);
4806  termPQExpBuffer(&buf);
4807  if (!res)
4808  return false;
4809 
4810  if (PQntuples(res) == 0)
4811  {
4812  if (!pset.quiet)
4813  {
4814  if (pattern)
4815  psql_error("Did not find any extension named \"%s\".\n",
4816  pattern);
4817  else
4818  psql_error("Did not find any extensions.\n");
4819  }
4820  PQclear(res);
4821  return false;
4822  }
4823 
4824  for (i = 0; i < PQntuples(res); i++)
4825  {
4826  const char *extname;
4827  const char *oid;
4828 
4829  extname = PQgetvalue(res, i, 0);
4830  oid = PQgetvalue(res, i, 1);
4831 
4832  if (!listOneExtensionContents(extname, oid))
4833  {
4834  PQclear(res);
4835  return false;
4836  }
4837  if (cancel_pressed)
4838  {
4839  PQclear(res);
4840  return false;
4841  }
4842  }
4843 
4844  PQclear(res);
4845  return true;
4846 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
volatile bool cancel_pressed
Definition: print.c:46
static char * buf
Definition: pg_test_fsync.c:65
static bool listOneExtensionContents(const char *extname, const char *oid)
Definition: describe.c:4849
void psql_error(const char *fmt,...)
Definition: common.c:177
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:226
int i
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listExtensions ( const char *  pattern)

Definition at line 4720 of file describe.c.

References _, appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

4721 {
4723  PGresult *res;
4724  printQueryOpt myopt = pset.popt;
4725 
4726  if (pset.sversion < 90100)
4727  {
4728  char sverbuf[32];
4729 
4730  psql_error("The server (version %s) does not support extensions.\n",
4732  sverbuf, sizeof(sverbuf)));
4733  return true;
4734  }
4735 
4736  initPQExpBuffer(&buf);
4737  printfPQExpBuffer(&buf,
4738  "SELECT e.extname AS \"%s\", "
4739  "e.extversion AS \"%s\", n.nspname AS \"%s\", c.description AS \"%s\"\n"
4740  "FROM pg_catalog.pg_extension e "
4741  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
4742  "LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid "
4743  "AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n",
4744  gettext_noop("Name"),
4745  gettext_noop("Version"),
4746  gettext_noop("Schema"),
4747  gettext_noop("Description"));
4748 
4749  processSQLNamePattern(pset.db, &buf, pattern,
4750  false, false,
4751  NULL, "e.extname", NULL,
4752  NULL);
4753 
4754  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4755 
4756  res = PSQLexec(buf.data);
4757  termPQExpBuffer(&buf);
4758  if (!res)
4759  return false;
4760 
4761  myopt.nullPrint = NULL;
4762  myopt.title = _("List of installed extensions");
4763  myopt.translate_header = true;
4764 
4765  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4766 
4767  PQclear(res);
4768  return true;
4769 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
char * nullPrint
Definition: print.h:166
PsqlSettings pset
Definition: startup.c:33
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
#define gettext_noop(x)
Definition: c.h:139
FILE * queryFout
Definition: settings.h:84
bool processSQLNamePattern(PGconn *conn, PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule)
Definition: string_utils.c:817
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
void psql_error(const char *fmt,...)
Definition: common.c:177
FILE * logfile
Definition: settings.h:113
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:226
printQueryOpt popt
Definition: settings.h:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3285
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:182
PGresult * PSQLexec(const char *query)
Definition: common.c:599
bool listForeignDataWrappers ( const char *  pattern,
bool  verbose 
)

Definition at line 4416 of file describe.c.

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, NULL, printQueryOpt::nullPrint, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, psql_error(), PSQLexec(), _psqlSettings::queryFout, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, and printQueryOpt::translate_header.

Referenced by exec_command().

4417 {
4419  PGresult *res;
4420  printQueryOpt myopt = pset.popt;
4421 
4422  if (pset.sversion < 80400)
4423  {
4424  char sverbuf[32];
4425 
4426  psql_error("The server (version %s) does not support foreign-data wrappers.\n",
4428  sverbuf, sizeof(sverbuf)));
4429  return true;
4430  }
4431 
4432  initPQExpBuffer(&buf);
4433  printfPQExpBuffer(&buf,
4434  "SELECT fdw.fdwname AS \"%s\",\n"
4435  " pg_catalog.pg_get_userbyid(fdw.fdwowner) AS \"%s\",\n",
4436  gettext_noop("Name"),
4437  gettext_noop("Owner"));
4438  if (pset.sversion >= 90100)
4439  appendPQExpBuffer(&buf,
4440  " fdw.fdwhandler::pg_catalog.regproc AS \"%s\",\n",
4441  gettext_noop("Handler"));
4442  appendPQExpBuffer(&buf,
4443  " fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
4444  gettext_noop("Validator"));
4445 
4446  if (verbose)
4447  {
4448  appendPQExpBufferStr(&buf, ",\n ");
4449  printACLColumn(&buf, "fdwacl");
4450  appendPQExpBuffer(&buf,
4451  ",\n CASE WHEN fdwoptions IS NULL THEN '' ELSE "
4452  " '(' || array_to_string(ARRAY(SELECT "
4453  " quote_ident(option_name) || ' ' || "
4454  " quote_literal(option_value) FROM "
4455  " pg_options_to_table(fdwoptions)), ', ') || ')' "
4456  " END AS \"%s\"",
4457  gettext_noop("FDW Options"));
4458 
4459  if (pset.sversion >= 90100)
4460  appendPQExpBuffer(&buf,
4461  ",\n d.description AS \"%s\" ",
4462  gettext_noop("Description"));
4463  }
4464