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_class.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 3144 of file describe.c.

References appendPQExpBufferStr(), and PQExpBufferData::len.

Referenced by describeRoles().

3145 {
3146  if (buf->len > 0)
3147  appendPQExpBufferStr(buf, ", ");
3148 
3149  appendPQExpBufferStr(buf, str);
3150 }
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 2924 of file describe.c.

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

Referenced by describeOneTableDetails().

2926 {
2927  /* relkinds for which we support tablespaces */
2928  if (relkind == RELKIND_RELATION ||
2929  relkind == RELKIND_MATVIEW ||
2930  relkind == RELKIND_INDEX ||
2931  relkind == RELKIND_PARTITIONED_TABLE)
2932  {
2933  /*
2934  * We ignore the database default tablespace so that users not using
2935  * tablespaces don't need to know about them. This case also covers
2936  * pre-8.0 servers, for which tablespace will always be 0.
2937  */
2938  if (tablespace != 0)
2939  {
2940  PGresult *result = NULL;
2942 
2943  initPQExpBuffer(&buf);
2944  printfPQExpBuffer(&buf,
2945  "SELECT spcname FROM pg_catalog.pg_tablespace\n"
2946  "WHERE oid = '%u';", tablespace);
2947  result = PSQLexec(buf.data);
2948  if (!result)
2949  return;
2950  /* Should always be the case, but.... */
2951  if (PQntuples(result) > 0)
2952  {
2953  if (newline)
2954  {
2955  /* Add the tablespace as a new footer */
2956  printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
2957  PQgetvalue(result, 0, 0));
2958  printTableAddFooter(cont, buf.data);
2959  }
2960  else
2961  {
2962  /* Append the tablespace to the latest footer */
2963  printfPQExpBuffer(&buf, "%s", cont->footer->data);
2964 
2965  /*-------
2966  translator: before this string there's an index description like
2967  '"foo_pkey" PRIMARY KEY, btree (a)' */
2968  appendPQExpBuffer(&buf, _(", tablespace \"%s\""),
2969  PQgetvalue(result, 0, 0));
2970  printTableSetFooter(cont, buf.data);
2971  }
2972  }
2973  PQclear(result);
2974  termPQExpBuffer(&buf);
2975  }
2976  }
2977 }
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
#define RELKIND_MATVIEW
Definition: pg_class.h:165
return result
Definition: formatting.c:1618
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
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
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:229
char * data
Definition: print.h:135
#define RELKIND_INDEX
Definition: pg_class.h:161
#define RELKIND_RELATION
Definition: pg_class.h:160
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:603
bool describeAccessMethods ( const char *  pattern,
bool  verbose 
)

Definition at line 137 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().

138 {
140  PGresult *res;
141  printQueryOpt myopt = pset.popt;
142  static const bool translate_columns[] = {false, true, false, false};
143 
144  if (pset.sversion < 90600)
145  {
146  char sverbuf[32];
147 
148  psql_error("The server (version %s) does not support access methods.\n",
150  sverbuf, sizeof(sverbuf)));
151  return true;
152  }
153 
154  initPQExpBuffer(&buf);
155 
156  printfPQExpBuffer(&buf,
157  "SELECT amname AS \"%s\",\n"
158  " CASE amtype"
159  " WHEN 'i' THEN '%s'"
160  " END AS \"%s\"",
161  gettext_noop("Name"),
162  gettext_noop("Index"),
163  gettext_noop("Type"));
164 
165  if (verbose)
166  {
167  appendPQExpBuffer(&buf,
168  ",\n amhandler AS \"%s\",\n"
169  " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
170  gettext_noop("Handler"),
171  gettext_noop("Description"));
172  }
173 
175  "\nFROM pg_catalog.pg_am\n");
176 
177  processSQLNamePattern(pset.db, &buf, pattern, false, false,
178  NULL, "amname", NULL,
179  NULL);
180 
181  appendPQExpBufferStr(&buf, "ORDER BY 1;");
182 
183  res = PSQLexec(buf.data);
184  termPQExpBuffer(&buf);
185  if (!res)
186  return false;
187 
188  myopt.nullPrint = NULL;
189  myopt.title = _("List of access methods");
190  myopt.translate_header = true;
191  myopt.translate_columns = translate_columns;
192  myopt.n_translate_columns = lengthof(translate_columns);
193 
194  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
195 
196  PQclear(res);
197  return true;
198 }
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:562
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:84
void psql_error(const char *fmt,...)
Definition: common.c:181
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool describeAggregates ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 60 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().

61 {
63  PGresult *res;
64  printQueryOpt myopt = pset.popt;
65 
66  initPQExpBuffer(&buf);
67 
68  printfPQExpBuffer(&buf,
69  "SELECT n.nspname as \"%s\",\n"
70  " p.proname AS \"%s\",\n"
71  " pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n",
72  gettext_noop("Schema"),
73  gettext_noop("Name"),
74  gettext_noop("Result data type"));
75 
76  if (pset.sversion >= 80400)
77  appendPQExpBuffer(&buf,
78  " CASE WHEN p.pronargs = 0\n"
79  " THEN CAST('*' AS pg_catalog.text)\n"
80  " ELSE pg_catalog.pg_get_function_arguments(p.oid)\n"
81  " END AS \"%s\",\n",
82  gettext_noop("Argument data types"));
83  else if (pset.sversion >= 80200)
84  appendPQExpBuffer(&buf,
85  " CASE WHEN p.pronargs = 0\n"
86  " THEN CAST('*' AS pg_catalog.text)\n"
87  " ELSE\n"
88  " pg_catalog.array_to_string(ARRAY(\n"
89  " SELECT\n"
90  " pg_catalog.format_type(p.proargtypes[s.i], NULL)\n"
91  " FROM\n"
92  " pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
93  " ), ', ')\n"
94  " END AS \"%s\",\n",
95  gettext_noop("Argument data types"));
96  else
97  appendPQExpBuffer(&buf,
98  " pg_catalog.format_type(p.proargtypes[0], NULL) AS \"%s\",\n",
99  gettext_noop("Argument data types"));
100 
101  appendPQExpBuffer(&buf,
102  " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
103  "FROM pg_catalog.pg_proc p\n"
104  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
105  "WHERE p.proisagg\n",
106  gettext_noop("Description"));
107 
108  if (!showSystem && !pattern)
109  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
110  " AND n.nspname <> 'information_schema'\n");
111 
112  processSQLNamePattern(pset.db, &buf, pattern, true, false,
113  "n.nspname", "p.proname", NULL,
114  "pg_catalog.pg_function_is_visible(p.oid)");
115 
116  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
117 
118  res = PSQLexec(buf.data);
119  termPQExpBuffer(&buf);
120  if (!res)
121  return false;
122 
123  myopt.nullPrint = NULL;
124  myopt.title = _("List of aggregate functions");
125  myopt.translate_header = true;
126 
127  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
128 
129  PQclear(res);
130  return true;
131 }
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:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool describeFunctions ( const char *  functypes,
const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 298 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().

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

Definition at line 1359 of file describe.c.

References _, add_tablespace_footer(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), atooid, buf, CppAsString2, 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, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_INDEX, RELKIND_MATVIEW, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_TOASTVALUE, RELKIND_VIEW, resetPQExpBuffer(), result, _psqlSettings::sversion, tablespace, termPQExpBuffer(), tmpbuf, and printQueryOpt::topt.

Referenced by describeTableDetails().

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

Definition at line 4439 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().

4441 {
4443  title;
4444  PGresult *res;
4445  printQueryOpt myopt = pset.popt;
4446 
4447  initPQExpBuffer(&buf);
4448 
4449  printfPQExpBuffer(&buf,
4450  "SELECT \n"
4451  " ( SELECT t.alias FROM \n"
4452  " pg_catalog.ts_token_type(c.cfgparser) AS t \n"
4453  " WHERE t.tokid = m.maptokentype ) AS \"%s\", \n"
4454  " pg_catalog.btrim( \n"
4455  " ARRAY( SELECT mm.mapdict::pg_catalog.regdictionary \n"
4456  " FROM pg_catalog.pg_ts_config_map AS mm \n"
4457  " WHERE mm.mapcfg = m.mapcfg AND mm.maptokentype = m.maptokentype \n"
4458  " ORDER BY mapcfg, maptokentype, mapseqno \n"
4459  " ) :: pg_catalog.text , \n"
4460  " '{}') AS \"%s\" \n"
4461  "FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m \n"
4462  "WHERE c.oid = '%s' AND m.mapcfg = c.oid \n"
4463  "GROUP BY m.mapcfg, m.maptokentype, c.cfgparser \n"
4464  "ORDER BY 1;",
4465  gettext_noop("Token"),
4466  gettext_noop("Dictionaries"),
4467  oid);
4468 
4469  res = PSQLexec(buf.data);
4470  termPQExpBuffer(&buf);
4471  if (!res)
4472  return false;
4473 
4474  initPQExpBuffer(&title);
4475 
4476  if (nspname)
4477  appendPQExpBuffer(&title, _("Text search configuration \"%s.%s\""),
4478  nspname, cfgname);
4479  else
4480  appendPQExpBuffer(&title, _("Text search configuration \"%s\""),
4481  cfgname);
4482 
4483  if (pnspname)
4484  appendPQExpBuffer(&title, _("\nParser: \"%s.%s\""),
4485  pnspname, prsname);
4486  else
4487  appendPQExpBuffer(&title, _("\nParser: \"%s\""),
4488  prsname);
4489 
4490  myopt.nullPrint = NULL;
4491  myopt.title = title.data;
4492  myopt.footers = NULL;
4493  myopt.topt.default_footer = false;
4494  myopt.translate_header = true;
4495 
4496  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4497 
4498  termPQExpBuffer(&title);
4499 
4500  PQclear(res);
4501  return true;
4502 }
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:114
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:229
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:603
static bool describeOneTSParser ( const char *  oid,
const char *  nspname,
const char *  prsname 
)
static

Definition at line 4053 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().

4054 {
4056  PGresult *res;
4057  char title[1024];
4058  printQueryOpt myopt = pset.popt;
4059  static const bool translate_columns[] = {true, false, false};
4060 
4061  initPQExpBuffer(&buf);
4062 
4063  printfPQExpBuffer(&buf,
4064  "SELECT '%s' AS \"%s\", \n"
4065  " p.prsstart::pg_catalog.regproc AS \"%s\", \n"
4066  " pg_catalog.obj_description(p.prsstart, 'pg_proc') as \"%s\" \n"
4067  " FROM pg_catalog.pg_ts_parser p \n"
4068  " WHERE p.oid = '%s' \n"
4069  "UNION ALL \n"
4070  "SELECT '%s', \n"
4071  " p.prstoken::pg_catalog.regproc, \n"
4072  " pg_catalog.obj_description(p.prstoken, 'pg_proc') \n"
4073  " FROM pg_catalog.pg_ts_parser p \n"
4074  " WHERE p.oid = '%s' \n"
4075  "UNION ALL \n"
4076  "SELECT '%s', \n"
4077  " p.prsend::pg_catalog.regproc, \n"
4078  " pg_catalog.obj_description(p.prsend, 'pg_proc') \n"
4079  " FROM pg_catalog.pg_ts_parser p \n"
4080  " WHERE p.oid = '%s' \n"
4081  "UNION ALL \n"
4082  "SELECT '%s', \n"
4083  " p.prsheadline::pg_catalog.regproc, \n"
4084  " pg_catalog.obj_description(p.prsheadline, 'pg_proc') \n"
4085  " FROM pg_catalog.pg_ts_parser p \n"
4086  " WHERE p.oid = '%s' \n"
4087  "UNION ALL \n"
4088  "SELECT '%s', \n"
4089  " p.prslextype::pg_catalog.regproc, \n"
4090  " pg_catalog.obj_description(p.prslextype, 'pg_proc') \n"
4091  " FROM pg_catalog.pg_ts_parser p \n"
4092  " WHERE p.oid = '%s';",
4093  gettext_noop("Start parse"),
4094  gettext_noop("Method"),
4095  gettext_noop("Function"),
4096  gettext_noop("Description"),
4097  oid,
4098  gettext_noop("Get next token"),
4099  oid,
4100  gettext_noop("End parse"),
4101  oid,
4102  gettext_noop("Get headline"),
4103  oid,
4104  gettext_noop("Get token types"),
4105  oid);
4106 
4107  res = PSQLexec(buf.data);
4108  termPQExpBuffer(&buf);
4109  if (!res)
4110  return false;
4111 
4112  myopt.nullPrint = NULL;
4113  if (nspname)
4114  sprintf(title, _("Text search parser \"%s.%s\""), nspname, prsname);
4115  else
4116  sprintf(title, _("Text search parser \"%s\""), prsname);
4117  myopt.title = title;
4118  myopt.footers = NULL;
4119  myopt.topt.default_footer = false;
4120  myopt.translate_header = true;
4121  myopt.translate_columns = translate_columns;
4122  myopt.n_translate_columns = lengthof(translate_columns);
4123 
4124  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4125 
4126  PQclear(res);
4127 
4128  initPQExpBuffer(&buf);
4129 
4130  printfPQExpBuffer(&buf,
4131  "SELECT t.alias as \"%s\", \n"
4132  " t.description as \"%s\" \n"
4133  "FROM pg_catalog.ts_token_type( '%s'::pg_catalog.oid ) as t \n"
4134  "ORDER BY 1;",
4135  gettext_noop("Token name"),
4136  gettext_noop("Description"),
4137  oid);
4138 
4139  res = PSQLexec(buf.data);
4140  termPQExpBuffer(&buf);
4141  if (!res)
4142  return false;
4143 
4144  myopt.nullPrint = NULL;
4145  if (nspname)
4146  sprintf(title, _("Token types for parser \"%s.%s\""), nspname, prsname);
4147  else
4148  sprintf(title, _("Token types for parser \"%s\""), prsname);
4149  myopt.title = title;
4150  myopt.footers = NULL;
4151  myopt.topt.default_footer = true;
4152  myopt.translate_header = true;
4153  myopt.translate_columns = NULL;
4154  myopt.n_translate_columns = 0;
4155 
4156  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4157 
4158  PQclear(res);
4159  return true;
4160 }
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:562
static char * buf
Definition: pg_test_fsync.c:65
bool translate_header
Definition: print.h:169
FILE * logfile
Definition: settings.h:114
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:229
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:603
bool describeOperators ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 702 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().

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

Definition at line 5045 of file describe.c.

References _, appendPQExpBufferStr(), buf, CppAsString2, 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, RELKIND_RELATION, _psqlSettings::sversion, termPQExpBuffer(), and printQueryOpt::topt.

Referenced by exec_command().

5046 {
5048  int i;
5049  PGresult *res;
5050 
5051  if (pset.sversion < 100000)
5052  {
5053  char sverbuf[32];
5054  psql_error("The server (version %s) does not support publications.\n",
5056  sverbuf, sizeof(sverbuf)));
5057  return true;
5058  }
5059 
5060  initPQExpBuffer(&buf);
5061 
5062  printfPQExpBuffer(&buf,
5063  "SELECT oid, pubname, puballtables, pubinsert,\n"
5064  " pubupdate, pubdelete\n"
5065  "FROM pg_catalog.pg_publication\n");
5066 
5067  processSQLNamePattern(pset.db, &buf, pattern, false, false,
5068  NULL, "pubname", NULL,
5069  NULL);
5070 
5071  appendPQExpBufferStr(&buf, "ORDER BY 2;");
5072 
5073  res = PSQLexec(buf.data);
5074  if (!res)
5075  {
5076  termPQExpBuffer(&buf);
5077  return false;
5078  }
5079 
5080  for (i = 0; i < PQntuples(res); i++)
5081  {
5082  const char align = 'l';
5083  int ncols = 3;
5084  int nrows = 1;
5085  int tables = 0;
5086  PGresult *tabres;
5087  char *pubid = PQgetvalue(res, i, 0);
5088  char *pubname = PQgetvalue(res, i, 1);
5089  bool puballtables = strcmp(PQgetvalue(res, i, 2), "t") == 0;
5090  int j;
5091  PQExpBufferData title;
5092  printTableOpt myopt = pset.popt.topt;
5093  printTableContent cont;
5094 
5095  initPQExpBuffer(&title);
5096  printfPQExpBuffer(&title, _("Publication %s"), pubname);
5097  printTableInit(&cont, &myopt, title.data, ncols, nrows);
5098 
5099  printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
5100  printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
5101  printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
5102 
5103  printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
5104  printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
5105  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
5106 
5107  if (puballtables)
5108  printfPQExpBuffer(&buf,
5109  "SELECT n.nspname, c.relname\n"
5110  "FROM pg_catalog.pg_class c,\n"
5111  " pg_catalog.pg_namespace n\n"
5112  "WHERE c.relnamespace = n.oid\n"
5113  " AND c.relkind = " CppAsString2(RELKIND_RELATION) "\n"
5114  " AND n.nspname <> 'pg_catalog'\n"
5115  " AND n.nspname <> 'information_schema'\n"
5116  "ORDER BY 1,2");
5117  else
5118  printfPQExpBuffer(&buf,
5119  "SELECT n.nspname, c.relname\n"
5120  "FROM pg_catalog.pg_class c,\n"
5121  " pg_catalog.pg_namespace n,\n"
5122  " pg_catalog.pg_publication_rel pr\n"
5123  "WHERE c.relnamespace = n.oid\n"
5124  " AND c.oid = pr.prrelid\n"
5125  " AND pr.prpubid = '%s'\n"
5126  "ORDER BY 1,2", pubid);
5127 
5128  tabres = PSQLexec(buf.data);
5129  if (!tabres)
5130  {
5131  printTableCleanup(&cont);
5132  PQclear(res);
5133  termPQExpBuffer(&buf);
5134  termPQExpBuffer(&title);
5135  return false;
5136  }
5137  else
5138  tables = PQntuples(tabres);
5139 
5140  if (tables > 0)
5141  printTableAddFooter(&cont, _("Tables:"));
5142 
5143  for (j = 0; j < tables; j++)
5144  {
5145  printfPQExpBuffer(&buf, " \"%s.%s\"",
5146  PQgetvalue(tabres, j, 0),
5147  PQgetvalue(tabres, j, 1));
5148 
5149  printTableAddFooter(&cont, buf.data);
5150  }
5151  PQclear(tabres);
5152 
5153  printTable(&cont, pset.queryFout, false, pset.logfile);
5154  printTableCleanup(&cont);
5155 
5156  termPQExpBuffer(&title);
5157  }
5158 
5159  termPQExpBuffer(&buf);
5160  PQclear(res);
5161 
5162  return true;
5163 }
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
#define CppAsString2(x)
Definition: c.h:162
void psql_error(const char *fmt,...)
Definition: common.c:181
void printTableAddFooter(printTableContent *const content, const char *footer)
Definition: print.c:3056
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
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 RELKIND_RELATION
Definition: pg_class.h:160
#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:603
bool describeRoles ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 2985 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().

2986 {
2988  PGresult *res;
2989  printTableContent cont;
2990  printTableOpt myopt = pset.popt.topt;
2991  int ncols = 3;
2992  int nrows = 0;
2993  int i;
2994  int conns;
2995  const char align = 'l';
2996  char **attr;
2997 
2998  myopt.default_footer = false;
2999 
3000  initPQExpBuffer(&buf);
3001 
3002  if (pset.sversion >= 80100)
3003  {
3004  printfPQExpBuffer(&buf,
3005  "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
3006  " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
3007  " r.rolconnlimit, r.rolvaliduntil,\n"
3008  " ARRAY(SELECT b.rolname\n"
3009  " FROM pg_catalog.pg_auth_members m\n"
3010  " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
3011  " WHERE m.member = r.oid) as memberof");
3012 
3013  if (verbose && pset.sversion >= 80200)
3014  {
3015  appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
3016  ncols++;
3017  }
3018  if (pset.sversion >= 90100)
3019  {
3020  appendPQExpBufferStr(&buf, "\n, r.rolreplication");
3021  }
3022 
3023  if (pset.sversion >= 90500)
3024  {
3025  appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
3026  }
3027 
3028  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
3029 
3030  if (!showSystem && !pattern)
3031  appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
3032 
3033  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3034  NULL, "r.rolname", NULL, NULL);
3035  }
3036  else
3037  {
3038  printfPQExpBuffer(&buf,
3039  "SELECT u.usename AS rolname,\n"
3040  " u.usesuper AS rolsuper,\n"
3041  " true AS rolinherit, false AS rolcreaterole,\n"
3042  " u.usecreatedb AS rolcreatedb, true AS rolcanlogin,\n"
3043  " -1 AS rolconnlimit,"
3044  " u.valuntil as rolvaliduntil,\n"
3045  " ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as memberof"
3046  "\nFROM pg_catalog.pg_user u\n");
3047 
3048  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3049  NULL, "u.usename", NULL, NULL);
3050  }
3051 
3052  appendPQExpBufferStr(&buf, "ORDER BY 1;");
3053 
3054  res = PSQLexec(buf.data);
3055  if (!res)
3056  return false;
3057 
3058  nrows = PQntuples(res);
3059  attr = pg_malloc0((nrows + 1) * sizeof(*attr));
3060 
3061  printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
3062 
3063  printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
3064  printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
3065  printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
3066 
3067  if (verbose && pset.sversion >= 80200)
3068  printTableAddHeader(&cont, gettext_noop("Description"), true, align);
3069 
3070  for (i = 0; i < nrows; i++)
3071  {
3072  printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
3073 
3074  resetPQExpBuffer(&buf);
3075  if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
3076  add_role_attribute(&buf, _("Superuser"));
3077 
3078  if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
3079  add_role_attribute(&buf, _("No inheritance"));
3080 
3081  if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
3082  add_role_attribute(&buf, _("Create role"));
3083 
3084  if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
3085  add_role_attribute(&buf, _("Create DB"));
3086 
3087  if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
3088  add_role_attribute(&buf, _("Cannot login"));
3089 
3090  if (pset.sversion >= 90100)
3091  if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3092  add_role_attribute(&buf, _("Replication"));
3093 
3094  if (pset.sversion >= 90500)
3095  if (strcmp(PQgetvalue(res, i, (verbose ? 11 : 10)), "t") == 0)
3096  add_role_attribute(&buf, _("Bypass RLS"));
3097 
3098  conns = atoi(PQgetvalue(res, i, 6));
3099  if (conns >= 0)
3100  {
3101  if (buf.len > 0)
3102  appendPQExpBufferChar(&buf, '\n');
3103 
3104  if (conns == 0)
3105  appendPQExpBufferStr(&buf, _("No connections"));
3106  else
3107  appendPQExpBuffer(&buf, ngettext("%d connection",
3108  "%d connections",
3109  conns),
3110  conns);
3111  }
3112 
3113  if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3114  {
3115  if (buf.len > 0)
3116  appendPQExpBufferStr(&buf, "\n");
3117  appendPQExpBufferStr(&buf, _("Password valid until "));
3118  appendPQExpBufferStr(&buf, PQgetvalue(res, i, 7));
3119  }
3120 
3121  attr[i] = pg_strdup(buf.data);
3122 
3123  printTableAddCell(&cont, attr[i], false, false);
3124 
3125  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3126 
3127  if (verbose && pset.sversion >= 80200)
3128  printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
3129  }
3130  termPQExpBuffer(&buf);
3131 
3132  printTable(&cont, pset.queryFout, false, pset.logfile);
3133  printTableCleanup(&cont);
3134 
3135  for (i = 0; i < nrows; i++)
3136  free(attr[i]);
3137  free(attr);
3138 
3139  PQclear(res);
3140  return true;
3141 }
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:3144
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:84
#define ngettext(s, p, n)
Definition: c.h:127
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define free(a)
Definition: header.h:65
bool default_footer
Definition: print.h:110
#define NULL
Definition: c.h:229
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:603
bool describeSubscriptions ( const char *  pattern,
bool  verbose 
)

Definition at line 5171 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().

5172 {
5174  PGresult *res;
5175  printQueryOpt myopt = pset.popt;
5176  static const bool translate_columns[] = {false, false, false, false, false};
5177 
5178  if (pset.sversion < 100000)
5179  {
5180  char sverbuf[32];
5181  psql_error("The server (version %s) does not support subscriptions.\n",
5183  sverbuf, sizeof(sverbuf)));
5184  return true;
5185  }
5186 
5187  initPQExpBuffer(&buf);
5188 
5189  printfPQExpBuffer(&buf,
5190  "SELECT subname AS \"%s\"\n"
5191  ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
5192  ", subenabled AS \"%s\"\n"
5193  ", subpublications AS \"%s\"\n",
5194  gettext_noop("Name"),
5195  gettext_noop("Owner"),
5196  gettext_noop("Enabled"),
5197  gettext_noop("Publication"));
5198 
5199  if (verbose)
5200  {
5201  appendPQExpBuffer(&buf,
5202  ", subconninfo AS \"%s\"\n",
5203  gettext_noop("Conninfo"));
5204  }
5205 
5206  /* Only display subscriptions in current database. */
5207  appendPQExpBufferStr(&buf,
5208  "FROM pg_catalog.pg_subscription\n"
5209  "WHERE subdbid = (SELECT oid\n"
5210  " FROM pg_catalog.pg_database\n"
5211  " WHERE datname = current_database())");
5212 
5213  processSQLNamePattern(pset.db, &buf, pattern, true, false,
5214  NULL, "subname", NULL,
5215  NULL);
5216 
5217  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5218 
5219  res = PSQLexec(buf.data);
5220  termPQExpBuffer(&buf);
5221  if (!res)
5222  return false;
5223 
5224  myopt.nullPrint = NULL;
5225  myopt.title = _("List of subscriptions");
5226  myopt.translate_header = true;
5227  myopt.translate_columns = translate_columns;
5228  myopt.n_translate_columns = lengthof(translate_columns);
5229 
5230  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5231 
5232  PQclear(res);
5233  return true;
5234 }
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:562
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:84
void psql_error(const char *fmt,...)
Definition: common.c:181
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool describeTableDetails ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 1286 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().

1287 {
1289  PGresult *res;
1290  int i;
1291 
1292  initPQExpBuffer(&buf);
1293 
1294  printfPQExpBuffer(&buf,
1295  "SELECT c.oid,\n"
1296  " n.nspname,\n"
1297  " c.relname\n"
1298  "FROM pg_catalog.pg_class c\n"
1299  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n");
1300 
1301  if (!showSystem && !pattern)
1302  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1303  " AND n.nspname <> 'information_schema'\n");
1304 
1305  processSQLNamePattern(pset.db, &buf, pattern, !showSystem && !pattern, false,
1306  "n.nspname", "c.relname", NULL,
1307  "pg_catalog.pg_table_is_visible(c.oid)");
1308 
1309  appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
1310 
1311  res = PSQLexec(buf.data);
1312  termPQExpBuffer(&buf);
1313  if (!res)
1314  return false;
1315 
1316  if (PQntuples(res) == 0)
1317  {
1318  if (!pset.quiet)
1319  psql_error("Did not find any relation named \"%s\".\n",
1320  pattern);
1321  PQclear(res);
1322  return false;
1323  }
1324 
1325  for (i = 0; i < PQntuples(res); i++)
1326  {
1327  const char *oid;
1328  const char *nspname;
1329  const char *relname;
1330 
1331  oid = PQgetvalue(res, i, 0);
1332  nspname = PQgetvalue(res, i, 1);
1333  relname = PQgetvalue(res, i, 2);
1334 
1335  if (!describeOneTableDetails(nspname, relname, oid, verbose))
1336  {
1337  PQclear(res);
1338  return false;
1339  }
1340  if (cancel_pressed)
1341  {
1342  PQclear(res);
1343  return false;
1344  }
1345  }
1346 
1347  PQclear(res);
1348  return true;
1349 }
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:1359
static int verbose
Definition: pg_basebackup.c:84
void psql_error(const char *fmt,...)
Definition: common.c:181
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
int i
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:603
bool describeTablespaces ( const char *  pattern,
bool  verbose 
)

Definition at line 204 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().

205 {
207  PGresult *res;
208  printQueryOpt myopt = pset.popt;
209 
210  if (pset.sversion < 80000)
211  {
212  char sverbuf[32];
213 
214  psql_error("The server (version %s) does not support tablespaces.\n",
216  sverbuf, sizeof(sverbuf)));
217  return true;
218  }
219 
220  initPQExpBuffer(&buf);
221 
222  if (pset.sversion >= 90200)
223  printfPQExpBuffer(&buf,
224  "SELECT spcname AS \"%s\",\n"
225  " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
226  " pg_catalog.pg_tablespace_location(oid) AS \"%s\"",
227  gettext_noop("Name"),
228  gettext_noop("Owner"),
229  gettext_noop("Location"));
230  else
231  printfPQExpBuffer(&buf,
232  "SELECT spcname AS \"%s\",\n"
233  " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
234  " spclocation AS \"%s\"",
235  gettext_noop("Name"),
236  gettext_noop("Owner"),
237  gettext_noop("Location"));
238 
239  if (verbose)
240  {
241  appendPQExpBufferStr(&buf, ",\n ");
242  printACLColumn(&buf, "spcacl");
243  }
244 
245  if (verbose && pset.sversion >= 90000)
246  appendPQExpBuffer(&buf,
247  ",\n spcoptions AS \"%s\"",
248  gettext_noop("Options"));
249 
250  if (verbose && pset.sversion >= 90200)
251  appendPQExpBuffer(&buf,
252  ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\"",
253  gettext_noop("Size"));
254 
255  if (verbose && pset.sversion >= 80200)
256  appendPQExpBuffer(&buf,
257  ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
258  gettext_noop("Description"));
259 
261  "\nFROM pg_catalog.pg_tablespace\n");
262 
263  processSQLNamePattern(pset.db, &buf, pattern, false, false,
264  NULL, "spcname", NULL,
265  NULL);
266 
267  appendPQExpBufferStr(&buf, "ORDER BY 1;");
268 
269  res = PSQLexec(buf.data);
270  termPQExpBuffer(&buf);
271  if (!res)
272  return false;
273 
274  myopt.nullPrint = NULL;
275  myopt.title = _("List of tablespaces");
276  myopt.translate_header = true;
277 
278  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
279 
280  PQclear(res);
281  return true;
282 }
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:84
void psql_error(const char *fmt,...)
Definition: common.c:181
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:5244
#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:603
bool describeTypes ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 587 of file describe.c.

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

Referenced by exec_command().

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

Definition at line 779 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().

780 {
781  PGresult *res;
783  printQueryOpt myopt = pset.popt;
784 
785  initPQExpBuffer(&buf);
786 
787  printfPQExpBuffer(&buf,
788  "SELECT d.datname as \"%s\",\n"
789  " pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
790  " pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n",
791  gettext_noop("Name"),
792  gettext_noop("Owner"),
793  gettext_noop("Encoding"));
794  if (pset.sversion >= 80400)
795  appendPQExpBuffer(&buf,
796  " d.datcollate as \"%s\",\n"
797  " d.datctype as \"%s\",\n",
798  gettext_noop("Collate"),
799  gettext_noop("Ctype"));
800  appendPQExpBufferStr(&buf, " ");
801  printACLColumn(&buf, "d.datacl");
802  if (verbose && pset.sversion >= 80200)
803  appendPQExpBuffer(&buf,
804  ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
805  " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
806  " ELSE 'No Access'\n"
807  " END as \"%s\"",
808  gettext_noop("Size"));
809  if (verbose && pset.sversion >= 80000)
810  appendPQExpBuffer(&buf,
811  ",\n t.spcname as \"%s\"",
812  gettext_noop("Tablespace"));
813  if (verbose && pset.sversion >= 80200)
814  appendPQExpBuffer(&buf,
815  ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
816  gettext_noop("Description"));
818  "\nFROM pg_catalog.pg_database d\n");
819  if (verbose && pset.sversion >= 80000)
821  " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
822 
823  if (pattern)
824  processSQLNamePattern(pset.db, &buf, pattern, false, false,
825  NULL, "d.datname", NULL, NULL);
826 
827  appendPQExpBufferStr(&buf, "ORDER BY 1;");
828  res = PSQLexec(buf.data);
829  termPQExpBuffer(&buf);
830  if (!res)
831  return false;
832 
833  myopt.nullPrint = NULL;
834  myopt.title = _("List of databases");
835  myopt.translate_header = true;
836 
837  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
838 
839  PQclear(res);
840  return true;
841 }
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:84
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:5244
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:603
bool listCasts ( const char *  pattern,
bool  verbose 
)

Definition at line 3690 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().

3691 {
3693  PGresult *res;
3694  printQueryOpt myopt = pset.popt;
3695  static const bool translate_columns[] = {false, false, false, true, false};
3696 
3697  initPQExpBuffer(&buf);
3698 
3699  /*
3700  * We need a left join to pg_proc for binary casts; the others are just
3701  * paranoia. Also note that we don't attempt to localize '(binary
3702  * coercible)', because there's too much risk of gettext translating a
3703  * function name that happens to match some string in the PO database.
3704  */
3705  printfPQExpBuffer(&buf,
3706  "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n"
3707  " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n"
3708  " CASE WHEN castfunc = 0 THEN '(binary coercible)'\n"
3709  " ELSE p.proname\n"
3710  " END as \"%s\",\n"
3711  " CASE WHEN c.castcontext = 'e' THEN '%s'\n"
3712  " WHEN c.castcontext = 'a' THEN '%s'\n"
3713  " ELSE '%s'\n"
3714  " END as \"%s\"",
3715  gettext_noop("Source type"),
3716  gettext_noop("Target type"),
3717  gettext_noop("Function"),
3718  gettext_noop("no"),
3719  gettext_noop("in assignment"),
3720  gettext_noop("yes"),
3721  gettext_noop("Implicit?"));
3722 
3723  if (verbose)
3724  appendPQExpBuffer(&buf,
3725  ",\n d.description AS \"%s\"\n",
3726  gettext_noop("Description"));
3727 
3728  appendPQExpBufferStr(&buf,
3729  "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
3730  " ON c.castfunc = p.oid\n"
3731  " LEFT JOIN pg_catalog.pg_type ts\n"
3732  " ON c.castsource = ts.oid\n"
3733  " LEFT JOIN pg_catalog.pg_namespace ns\n"
3734  " ON ns.oid = ts.typnamespace\n"
3735  " LEFT JOIN pg_catalog.pg_type tt\n"
3736  " ON c.casttarget = tt.oid\n"
3737  " LEFT JOIN pg_catalog.pg_namespace nt\n"
3738  " ON nt.oid = tt.typnamespace\n");
3739 
3740  if (verbose)
3741  appendPQExpBufferStr(&buf,
3742  " LEFT JOIN pg_catalog.pg_description d\n"
3743  " ON d.classoid = c.tableoid AND d.objoid = "
3744  "c.oid AND d.objsubid = 0\n");
3745 
3746  appendPQExpBufferStr(&buf, "WHERE ( (true");
3747 
3748  /*
3749  * Match name pattern against either internal or external name of either
3750  * castsource or casttarget
3751  */
3752  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3753  "ns.nspname", "ts.typname",
3754  "pg_catalog.format_type(ts.oid, NULL)",
3755  "pg_catalog.pg_type_is_visible(ts.oid)");
3756 
3757  appendPQExpBufferStr(&buf, ") OR (true");
3758 
3759  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3760  "nt.nspname", "tt.typname",
3761  "pg_catalog.format_type(tt.oid, NULL)",
3762  "pg_catalog.pg_type_is_visible(tt.oid)");
3763 
3764  appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
3765 
3766  res = PSQLexec(buf.data);
3767  termPQExpBuffer(&buf);
3768  if (!res)
3769  return false;
3770 
3771  myopt.nullPrint = NULL;
3772  myopt.title = _("List of casts");
3773  myopt.translate_header = true;
3774  myopt.translate_columns = translate_columns;
3775  myopt.n_translate_columns = lengthof(translate_columns);
3776 
3777  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3778 
3779  PQclear(res);
3780  return true;
3781 }
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:562
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:84
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool listCollations ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3789 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().

3790 {
3792  PGresult *res;
3793  printQueryOpt myopt = pset.popt;
3794  static const bool translate_columns[] = {false, false, false, false, false, false};
3795 
3796  if (pset.sversion < 90100)
3797  {
3798  char sverbuf[32];
3799 
3800  psql_error("The server (version %s) does not support collations.\n",
3802  sverbuf, sizeof(sverbuf)));
3803  return true;
3804  }
3805 
3806  initPQExpBuffer(&buf);
3807 
3808  printfPQExpBuffer(&buf,
3809  "SELECT n.nspname AS \"%s\",\n"
3810  " c.collname AS \"%s\",\n"
3811  " c.collcollate AS \"%s\",\n"
3812  " c.collctype AS \"%s\"",
3813  gettext_noop("Schema"),
3814  gettext_noop("Name"),
3815  gettext_noop("Collate"),
3816  gettext_noop("Ctype"));
3817 
3818  if (pset.sversion >= 100000)
3819  appendPQExpBuffer(&buf,
3820  ",\n CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\"",
3821  gettext_noop("Provider"));
3822 
3823  if (verbose)
3824  appendPQExpBuffer(&buf,
3825  ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
3826  gettext_noop("Description"));
3827 
3828  appendPQExpBufferStr(&buf,
3829  "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
3830  "WHERE n.oid = c.collnamespace\n");
3831 
3832  if (!showSystem && !pattern)
3833  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3834  " AND n.nspname <> 'information_schema'\n");
3835 
3836  /*
3837  * Hide collations that aren't usable in the current database's encoding.
3838  * If you think to change this, note that pg_collation_is_visible rejects
3839  * unusable collations, so you will need to hack name pattern processing
3840  * somehow to avoid inconsistent behavior.
3841  */
3842  appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
3843 
3844  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3845  "n.nspname", "c.collname", NULL,
3846  "pg_catalog.pg_collation_is_visible(c.oid)");
3847 
3848  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3849 
3850  res = PSQLexec(buf.data);
3851  termPQExpBuffer(&buf);
3852  if (!res)
3853  return false;
3854 
3855  myopt.nullPrint = NULL;
3856  myopt.title = _("List of collations");
3857  myopt.translate_header = true;
3858  myopt.translate_columns = translate_columns;
3859  myopt.n_translate_columns = lengthof(translate_columns);
3860 
3861  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3862 
3863  PQclear(res);
3864  return true;
3865 }
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:562
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:84
void psql_error(const char *fmt,...)
Definition: common.c:181
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool listConversions ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3548 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().

3549 {
3551  PGresult *res;
3552  printQueryOpt myopt = pset.popt;
3553  static const bool translate_columns[] =
3554  {false, false, false, false, true, false};
3555 
3556  initPQExpBuffer(&buf);
3557 
3558  printfPQExpBuffer(&buf,
3559  "SELECT n.nspname AS \"%s\",\n"
3560  " c.conname AS \"%s\",\n"
3561  " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
3562  " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
3563  " CASE WHEN c.condefault THEN '%s'\n"
3564  " ELSE '%s' END AS \"%s\"",
3565  gettext_noop("Schema"),
3566  gettext_noop("Name"),
3567  gettext_noop("Source"),
3568  gettext_noop("Destination"),
3569  gettext_noop("yes"), gettext_noop("no"),
3570  gettext_noop("Default?"));
3571 
3572  if (verbose)
3573  appendPQExpBuffer(&buf,
3574  ",\n d.description AS \"%s\"",
3575  gettext_noop("Description"));
3576 
3577  appendPQExpBufferStr(&buf,
3578  "\nFROM pg_catalog.pg_conversion c\n"
3579  " JOIN pg_catalog.pg_namespace n "
3580  "ON n.oid = c.connamespace\n");
3581 
3582  if (verbose)
3583  appendPQExpBufferStr(&buf,
3584  "LEFT JOIN pg_catalog.pg_description d "
3585  "ON d.classoid = c.tableoid\n"
3586  " AND d.objoid = c.oid "
3587  "AND d.objsubid = 0\n");
3588 
3589  appendPQExpBufferStr(&buf, "WHERE true\n");
3590 
3591  if (!showSystem && !pattern)
3592  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3593  " AND n.nspname <> 'information_schema'\n");
3594 
3595  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3596  "n.nspname", "c.conname", NULL,
3597  "pg_catalog.pg_conversion_is_visible(c.oid)");
3598 
3599  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3600 
3601  res = PSQLexec(buf.data);
3602  termPQExpBuffer(&buf);
3603  if (!res)
3604  return false;
3605 
3606  myopt.nullPrint = NULL;
3607  myopt.title = _("List of conversions");
3608  myopt.translate_header = true;
3609  myopt.translate_columns = translate_columns;
3610  myopt.n_translate_columns = lengthof(translate_columns);
3611 
3612  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3613 
3614  PQclear(res);
3615  return true;
3616 }
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:562
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:84
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool listDbRoleSettings ( const char *  pattern,
const char *  pattern2 
)

Definition at line 3156 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().

3157 {
3159  PGresult *res;
3160  printQueryOpt myopt = pset.popt;
3161 
3162  initPQExpBuffer(&buf);
3163 
3164  if (pset.sversion >= 90000)
3165  {
3166  bool havewhere;
3167 
3168  printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
3169  "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
3170  "FROM pg_db_role_setting AS s\n"
3171  "LEFT JOIN pg_database ON pg_database.oid = setdatabase\n"
3172  "LEFT JOIN pg_roles ON pg_roles.oid = setrole\n",
3173  gettext_noop("Role"),
3174  gettext_noop("Database"),
3175  gettext_noop("Settings"));
3176  havewhere = processSQLNamePattern(pset.db, &buf, pattern, false, false,
3177  NULL, "pg_roles.rolname", NULL, NULL);
3178  processSQLNamePattern(pset.db, &buf, pattern2, havewhere, false,
3179  NULL, "pg_database.datname", NULL, NULL);
3180  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3181  }
3182  else
3183  {
3184  fprintf(pset.queryFout,
3185  _("No per-database role settings support in this server version.\n"));
3186  return false;
3187  }
3188 
3189  res = PSQLexec(buf.data);
3190  if (!res)
3191  return false;
3192 
3193  if (PQntuples(res) == 0 && !pset.quiet)
3194  {
3195  if (pattern)
3196  fprintf(pset.queryFout, _("No matching settings found.\n"));
3197  else
3198  fprintf(pset.queryFout, _("No settings found.\n"));
3199  }
3200  else
3201  {
3202  myopt.nullPrint = NULL;
3203  myopt.title = _("List of settings");
3204  myopt.translate_header = true;
3205 
3206  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3207  }
3208 
3209  PQclear(res);
3210  resetPQExpBuffer(&buf);
3211  return true;
3212 }
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:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool listDefaultACLs ( const char *  pattern)

Definition at line 1009 of file describe.c.

References _, appendPQExpBufferStr(), buf, PQExpBufferData::data, _psqlSettings::db, DEFACLOBJ_FUNCTION, DEFACLOBJ_NAMESPACE, 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().

1010 {
1012  PGresult *res;
1013  printQueryOpt myopt = pset.popt;
1014  static const bool translate_columns[] = {false, false, true, false};
1015 
1016  if (pset.sversion < 90000)
1017  {
1018  char sverbuf[32];
1019 
1020  psql_error("The server (version %s) does not support altering default privileges.\n",
1022  sverbuf, sizeof(sverbuf)));
1023  return true;
1024  }
1025 
1026  initPQExpBuffer(&buf);
1027 
1028  printfPQExpBuffer(&buf,
1029  "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
1030  " n.nspname AS \"%s\",\n"
1031  " CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
1032  " ",
1033  gettext_noop("Owner"),
1034  gettext_noop("Schema"),
1036  gettext_noop("table"),
1038  gettext_noop("sequence"),
1040  gettext_noop("function"),
1042  gettext_noop("type"),
1044  gettext_noop("schema"),
1045  gettext_noop("Type"));
1046 
1047  printACLColumn(&buf, "d.defaclacl");
1048 
1049  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
1050  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
1051 
1052  processSQLNamePattern(pset.db, &buf, pattern, false, false,
1053  NULL,
1054  "n.nspname",
1055  "pg_catalog.pg_get_userbyid(d.defaclrole)",
1056  NULL);
1057 
1058  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1059 
1060  res = PSQLexec(buf.data);
1061  if (!res)
1062  {
1063  termPQExpBuffer(&buf);
1064  return false;
1065  }
1066 
1067  myopt.nullPrint = NULL;
1068  printfPQExpBuffer(&buf, _("Default access privileges"));
1069  myopt.title = buf.data;
1070  myopt.translate_header = true;
1071  myopt.translate_columns = translate_columns;
1072  myopt.n_translate_columns = lengthof(translate_columns);
1073 
1074  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1075 
1076  termPQExpBuffer(&buf);
1077  PQclear(res);
1078  return true;
1079 }
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:562
#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:181
FILE * logfile
Definition: settings.h:114
#define DEFACLOBJ_NAMESPACE
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define DEFACLOBJ_RELATION
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
#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:5244
#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:603
bool listDomains ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3462 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().

3463 {
3465  PGresult *res;
3466  printQueryOpt myopt = pset.popt;
3467 
3468  initPQExpBuffer(&buf);
3469 
3470  printfPQExpBuffer(&buf,
3471  "SELECT n.nspname as \"%s\",\n"
3472  " t.typname as \"%s\",\n"
3473  " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n",
3474  gettext_noop("Schema"),
3475  gettext_noop("Name"),
3476  gettext_noop("Type"));
3477 
3478  if (pset.sversion >= 90100)
3479  appendPQExpBuffer(&buf,
3480  " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
3481  " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n",
3482  gettext_noop("Collation"));
3483  appendPQExpBuffer(&buf,
3484  " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
3485  " t.typdefault as \"%s\",\n"
3486  " pg_catalog.array_to_string(ARRAY(\n"
3487  " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
3488  " ), ' ') as \"%s\"",
3489  gettext_noop("Nullable"),
3490  gettext_noop("Default"),
3491  gettext_noop("Check"));
3492 
3493  if (verbose)
3494  {
3495  if (pset.sversion >= 90200)
3496  {
3497  appendPQExpBufferStr(&buf, ",\n ");
3498  printACLColumn(&buf, "t.typacl");
3499  }
3500  appendPQExpBuffer(&buf,
3501  ",\n d.description as \"%s\"",
3502  gettext_noop("Description"));
3503  }
3504 
3505  appendPQExpBufferStr(&buf,
3506  "\nFROM pg_catalog.pg_type t\n"
3507  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
3508 
3509  if (verbose)
3510  appendPQExpBufferStr(&buf,
3511  " LEFT JOIN pg_catalog.pg_description d "
3512  "ON d.classoid = t.tableoid AND d.objoid = t.oid "
3513  "AND d.objsubid = 0\n");
3514 
3515  appendPQExpBufferStr(&buf, "WHERE t.typtype = 'd'\n");
3516 
3517  if (!showSystem && !pattern)
3518  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3519  " AND n.nspname <> 'information_schema'\n");
3520 
3521  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3522  "n.nspname", "t.typname", NULL,
3523  "pg_catalog.pg_type_is_visible(t.oid)");
3524 
3525  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3526 
3527  res = PSQLexec(buf.data);
3528  termPQExpBuffer(&buf);
3529  if (!res)
3530  return false;
3531 
3532  myopt.nullPrint = NULL;
3533  myopt.title = _("List of domains");
3534  myopt.translate_header = true;
3535 
3536  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3537 
3538  PQclear(res);
3539  return true;
3540 }
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:84
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:5244
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:603
bool listEventTriggers ( const char *  pattern,
bool  verbose 
)

Definition at line 3624 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().

3625 {
3627  PGresult *res;
3628  printQueryOpt myopt = pset.popt;
3629  static const bool translate_columns[] =
3630  {false, false, false, true, false, false, false};
3631 
3632  initPQExpBuffer(&buf);
3633 
3634  printfPQExpBuffer(&buf,
3635  "SELECT evtname as \"%s\", "
3636  "evtevent as \"%s\", "
3637  "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n"
3638  " case evtenabled when 'O' then '%s'"
3639  " when 'R' then '%s'"
3640  " when 'A' then '%s'"
3641  " when 'D' then '%s' end as \"%s\",\n"
3642  " e.evtfoid::pg_catalog.regproc as \"%s\", "
3643  "pg_catalog.array_to_string(array(select x"
3644  " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
3645  gettext_noop("Name"),
3646  gettext_noop("Event"),
3647  gettext_noop("Owner"),
3648  gettext_noop("enabled"),
3649  gettext_noop("replica"),
3650  gettext_noop("always"),
3651  gettext_noop("disabled"),
3652  gettext_noop("Enabled"),
3653  gettext_noop("Procedure"),
3654  gettext_noop("Tags"));
3655  if (verbose)
3656  appendPQExpBuffer(&buf,
3657  ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
3658  gettext_noop("Description"));
3659  appendPQExpBufferStr(&buf,
3660  "\nFROM pg_catalog.pg_event_trigger e ");
3661 
3662  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3663  NULL, "evtname", NULL, NULL);
3664 
3665  appendPQExpBufferStr(&buf, "ORDER BY 1");
3666 
3667  res = PSQLexec(buf.data);
3668  termPQExpBuffer(&buf);
3669  if (!res)
3670  return false;
3671 
3672  myopt.nullPrint = NULL;
3673  myopt.title = _("List of event triggers");
3674  myopt.translate_header = true;
3675  myopt.translate_columns = translate_columns;
3676  myopt.n_translate_columns = lengthof(translate_columns);
3677 
3678  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3679 
3680  PQclear(res);
3681  return true;
3682 }
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:562
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:84
FILE * logfile
Definition: settings.h:114
void PQclear(PGresult *res)
Definition: fe-exec.c:650
char * title
Definition: print.h:167
#define NULL
Definition: c.h:229
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:603
bool listExtensionContents ( const char *  pattern)

Definition at line 4872 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().

4873 {
4875  PGresult *res;
4876  int i;
4877 
4878  if (pset.sversion < 90100)
4879  {
4880  char sverbuf[32];
4881 
4882  psql_error("The server (version %s) does not support extensions.\n",
4884  sverbuf, sizeof(sverbuf)));
4885  return true;
4886  }
4887 
4888  initPQExpBuffer(&buf);
4889  printfPQExpBuffer(&buf,
4890  "SELECT e.extname, e.oid\n"
4891  "FROM pg_catalog.pg_extension e\n");
4892 
4893  processSQLNamePattern(pset.db, &buf, pattern,
4894  false, false,
4895  NULL, "e.extname", NULL,
4896  NULL);
4897 
4898  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4899 
4900  res = PSQLexec(buf.data);
4901  termPQExpBuffer(&buf);
4902  if (!res)
4903  return false;
4904 
4905  if (PQntuples(res) == 0)
4906  {
4907  if (!pset.quiet)
4908  {
4909  if (pattern)
4910  psql_error("Did not find any extension named \"%s\".\n",
4911  pattern);
4912  else
4913  psql_error("Did not find any extensions.\n");
4914  }
4915  PQclear(res);
4916  return false;
4917  }
4918 
4919  for (i = 0; i < PQntuples(res); i++)
4920  {
4921  const char *extname;
4922  const char *oid;
4923 
4924  extname = PQgetvalue(res, i, 0);
4925  oid = PQgetvalue(res, i, 1);
4926 
4927  if (!listOneExtensionContents(extname, oid))
4928  {
4929  PQclear(res);
4930  return false;
4931  }
4932  if (cancel_pressed)
4933  {
4934  PQclear(res);
4935  return false;
4936  }
4937  }
4938 
4939  PQclear(res);
4940  return true;
4941 }
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:4944
void psql_error(const char *fmt,...)
Definition: common.c:181
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
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:603
bool listExtensions ( const char *  pattern)

Definition at line 4815 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().

4816 {
4818  PGresult *res;
4819  printQueryOpt myopt = pset.popt;
4820 
4821  if (pset.sversion < 90100)
4822  {
4823  char sverbuf[32];
4824 
4825  psql_error("The server (version %s) does not support extensions.\n",
4827  sverbuf, sizeof(sverbuf)));
4828  return true;
4829  }
4830 
4831  initPQExpBuffer(&buf);
4832  printfPQExpBuffer(&buf,
4833  "SELECT e.extname AS \"%s\", "
4834  "e.extversion AS \"%s\", n.nspname AS \"%s\", c.description AS \"%s\"\n"
4835  "FROM pg_catalog.pg_extension e "
4836  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
4837  "LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid "
4838  "AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n",