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_attribute.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 3211 of file describe.c.

References appendPQExpBufferStr(), and PQExpBufferData::len.

Referenced by describeRoles().

3212 {
3213  if (buf->len > 0)
3214  appendPQExpBufferStr(buf, ", ");
3215 
3216  appendPQExpBufferStr(buf, str);
3217 }
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 2991 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().

2993 {
2994  /* relkinds for which we support tablespaces */
2995  if (relkind == RELKIND_RELATION ||
2996  relkind == RELKIND_MATVIEW ||
2997  relkind == RELKIND_INDEX ||
2998  relkind == RELKIND_PARTITIONED_TABLE)
2999  {
3000  /*
3001  * We ignore the database default tablespace so that users not using
3002  * tablespaces don't need to know about them. This case also covers
3003  * pre-8.0 servers, for which tablespace will always be 0.
3004  */
3005  if (tablespace != 0)
3006  {
3007  PGresult *result = NULL;
3009 
3010  initPQExpBuffer(&buf);
3011  printfPQExpBuffer(&buf,
3012  "SELECT spcname FROM pg_catalog.pg_tablespace\n"
3013  "WHERE oid = '%u';", tablespace);
3014  result = PSQLexec(buf.data);
3015  if (!result)
3016  return;
3017  /* Should always be the case, but.... */
3018  if (PQntuples(result) > 0)
3019  {
3020  if (newline)
3021  {
3022  /* Add the tablespace as a new footer */
3023  printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
3024  PQgetvalue(result, 0, 0));
3025  printTableAddFooter(cont, buf.data);
3026  }
3027  else
3028  {
3029  /* Append the tablespace to the latest footer */
3030  printfPQExpBuffer(&buf, "%s", cont->footer->data);
3031 
3032  /*-------
3033  translator: before this string there's an index description like
3034  '"foo_pkey" PRIMARY KEY, btree (a)' */
3035  appendPQExpBuffer(&buf, _(", tablespace \"%s\""),
3036  PQgetvalue(result, 0, 0));
3037  printTableSetFooter(cont, buf.data);
3038  }
3039  }
3040  PQclear(result);
3041  termPQExpBuffer(&buf);
3042  }
3043  }
3044 }
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:1632
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:66
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:642
bool describeAccessMethods ( const char *  pattern,
bool  verbose 
)

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

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

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

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

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

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

Definition at line 1360 of file describe.c.

References _, add_tablespace_footer(), appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), atooid, ATTRIBUTE_IDENTITY_ALWAYS, ATTRIBUTE_IDENTITY_BY_DEFAULT, 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().

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

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

4508 {
4510  title;
4511  PGresult *res;
4512  printQueryOpt myopt = pset.popt;
4513 
4514  initPQExpBuffer(&buf);
4515 
4516  printfPQExpBuffer(&buf,
4517  "SELECT\n"
4518  " ( SELECT t.alias FROM\n"
4519  " pg_catalog.ts_token_type(c.cfgparser) AS t\n"
4520  " WHERE t.tokid = m.maptokentype ) AS \"%s\",\n"
4521  " pg_catalog.btrim(\n"
4522  " ARRAY( SELECT mm.mapdict::pg_catalog.regdictionary\n"
4523  " FROM pg_catalog.pg_ts_config_map AS mm\n"
4524  " WHERE mm.mapcfg = m.mapcfg AND mm.maptokentype = m.maptokentype\n"
4525  " ORDER BY mapcfg, maptokentype, mapseqno\n"
4526  " ) :: pg_catalog.text,\n"
4527  " '{}') AS \"%s\"\n"
4528  "FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m\n"
4529  "WHERE c.oid = '%s' AND m.mapcfg = c.oid\n"
4530  "GROUP BY m.mapcfg, m.maptokentype, c.cfgparser\n"
4531  "ORDER BY 1;",
4532  gettext_noop("Token"),
4533  gettext_noop("Dictionaries"),
4534  oid);
4535 
4536  res = PSQLexec(buf.data);
4537  termPQExpBuffer(&buf);
4538  if (!res)
4539  return false;
4540 
4541  initPQExpBuffer(&title);
4542 
4543  if (nspname)
4544  appendPQExpBuffer(&title, _("Text search configuration \"%s.%s\""),
4545  nspname, cfgname);
4546  else
4547  appendPQExpBuffer(&title, _("Text search configuration \"%s\""),
4548  cfgname);
4549 
4550  if (pnspname)
4551  appendPQExpBuffer(&title, _("\nParser: \"%s.%s\""),
4552  pnspname, prsname);
4553  else
4554  appendPQExpBuffer(&title, _("\nParser: \"%s\""),
4555  prsname);
4556 
4557  myopt.nullPrint = NULL;
4558  myopt.title = title.data;
4559  myopt.footers = NULL;
4560  myopt.topt.default_footer = false;
4561  myopt.translate_header = true;
4562 
4563  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4564 
4565  termPQExpBuffer(&title);
4566 
4567  PQclear(res);
4568  return true;
4569 }
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:66
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:642
static bool describeOneTSParser ( const char *  oid,
const char *  nspname,
const char *  prsname 
)
static

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

4121 {
4123  PGresult *res;
4124  char title[1024];
4125  printQueryOpt myopt = pset.popt;
4126  static const bool translate_columns[] = {true, false, false};
4127 
4128  initPQExpBuffer(&buf);
4129 
4130  printfPQExpBuffer(&buf,
4131  "SELECT '%s' AS \"%s\",\n"
4132  " p.prsstart::pg_catalog.regproc AS \"%s\",\n"
4133  " pg_catalog.obj_description(p.prsstart, 'pg_proc') as \"%s\"\n"
4134  " FROM pg_catalog.pg_ts_parser p\n"
4135  " WHERE p.oid = '%s'\n"
4136  "UNION ALL\n"
4137  "SELECT '%s',\n"
4138  " p.prstoken::pg_catalog.regproc,\n"
4139  " pg_catalog.obj_description(p.prstoken, 'pg_proc')\n"
4140  " FROM pg_catalog.pg_ts_parser p\n"
4141  " WHERE p.oid = '%s'\n"
4142  "UNION ALL\n"
4143  "SELECT '%s',\n"
4144  " p.prsend::pg_catalog.regproc,\n"
4145  " pg_catalog.obj_description(p.prsend, 'pg_proc')\n"
4146  " FROM pg_catalog.pg_ts_parser p\n"
4147  " WHERE p.oid = '%s'\n"
4148  "UNION ALL\n"
4149  "SELECT '%s',\n"
4150  " p.prsheadline::pg_catalog.regproc,\n"
4151  " pg_catalog.obj_description(p.prsheadline, 'pg_proc')\n"
4152  " FROM pg_catalog.pg_ts_parser p\n"
4153  " WHERE p.oid = '%s'\n"
4154  "UNION ALL\n"
4155  "SELECT '%s',\n"
4156  " p.prslextype::pg_catalog.regproc,\n"
4157  " pg_catalog.obj_description(p.prslextype, 'pg_proc')\n"
4158  " FROM pg_catalog.pg_ts_parser p\n"
4159  " WHERE p.oid = '%s';",
4160  gettext_noop("Start parse"),
4161  gettext_noop("Method"),
4162  gettext_noop("Function"),
4163  gettext_noop("Description"),
4164  oid,
4165  gettext_noop("Get next token"),
4166  oid,
4167  gettext_noop("End parse"),
4168  oid,
4169  gettext_noop("Get headline"),
4170  oid,
4171  gettext_noop("Get token types"),
4172  oid);
4173 
4174  res = PSQLexec(buf.data);
4175  termPQExpBuffer(&buf);
4176  if (!res)
4177  return false;
4178 
4179  myopt.nullPrint = NULL;
4180  if (nspname)
4181  sprintf(title, _("Text search parser \"%s.%s\""), nspname, prsname);
4182  else
4183  sprintf(title, _("Text search parser \"%s\""), prsname);
4184  myopt.title = title;
4185  myopt.footers = NULL;
4186  myopt.topt.default_footer = false;
4187  myopt.translate_header = true;
4188  myopt.translate_columns = translate_columns;
4189  myopt.n_translate_columns = lengthof(translate_columns);
4190 
4191  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4192 
4193  PQclear(res);
4194 
4195  initPQExpBuffer(&buf);
4196 
4197  printfPQExpBuffer(&buf,
4198  "SELECT t.alias as \"%s\",\n"
4199  " t.description as \"%s\"\n"
4200  "FROM pg_catalog.ts_token_type( '%s'::pg_catalog.oid ) as t\n"
4201  "ORDER BY 1;",
4202  gettext_noop("Token name"),
4203  gettext_noop("Description"),
4204  oid);
4205 
4206  res = PSQLexec(buf.data);
4207  termPQExpBuffer(&buf);
4208  if (!res)
4209  return false;
4210 
4211  myopt.nullPrint = NULL;
4212  if (nspname)
4213  sprintf(title, _("Token types for parser \"%s.%s\""), nspname, prsname);
4214  else
4215  sprintf(title, _("Token types for parser \"%s\""), prsname);
4216  myopt.title = title;
4217  myopt.footers = NULL;
4218  myopt.topt.default_footer = true;
4219  myopt.translate_header = true;
4220  myopt.translate_columns = NULL;
4221  myopt.n_translate_columns = 0;
4222 
4223  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4224 
4225  PQclear(res);
4226  return true;
4227 }
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:66
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:642
bool describeOperators ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

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

Definition at line 5115 of file describe.c.

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

Referenced by exec_command_d().

5116 {
5118  int i;
5119  PGresult *res;
5120 
5121  if (pset.sversion < 100000)
5122  {
5123  char sverbuf[32];
5124 
5125  psql_error("The server (version %s) does not support publications.\n",
5127  sverbuf, sizeof(sverbuf)));
5128  return true;
5129  }
5130 
5131  initPQExpBuffer(&buf);
5132 
5133  printfPQExpBuffer(&buf,
5134  "SELECT oid, pubname, puballtables, pubinsert,\n"
5135  " pubupdate, pubdelete\n"
5136  "FROM pg_catalog.pg_publication\n");
5137 
5138  processSQLNamePattern(pset.db, &buf, pattern, false, false,
5139  NULL, "pubname", NULL,
5140  NULL);
5141 
5142  appendPQExpBufferStr(&buf, "ORDER BY 2;");
5143 
5144  res = PSQLexec(buf.data);
5145  if (!res)
5146  {
5147  termPQExpBuffer(&buf);
5148  return false;
5149  }
5150 
5151  for (i = 0; i < PQntuples(res); i++)
5152  {
5153  const char align = 'l';
5154  int ncols = 4;
5155  int nrows = 1;
5156  int tables = 0;
5157  PGresult *tabres;
5158  char *pubid = PQgetvalue(res, i, 0);
5159  char *pubname = PQgetvalue(res, i, 1);
5160  bool puballtables = strcmp(PQgetvalue(res, i, 2), "t") == 0;
5161  int j;
5162  PQExpBufferData title;
5163  printTableOpt myopt = pset.popt.topt;
5164  printTableContent cont;
5165 
5166  initPQExpBuffer(&title);
5167  printfPQExpBuffer(&title, _("Publication %s"), pubname);
5168  printTableInit(&cont, &myopt, title.data, ncols, nrows);
5169 
5170  printTableAddHeader(&cont, gettext_noop("All tables"), true, align);
5171  printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
5172  printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
5173  printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
5174 
5175  printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
5176  printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
5177  printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
5178  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
5179 
5180  if (!puballtables)
5181  {
5182  printfPQExpBuffer(&buf,
5183  "SELECT n.nspname, c.relname\n"
5184  "FROM pg_catalog.pg_class c,\n"
5185  " pg_catalog.pg_namespace n,\n"
5186  " pg_catalog.pg_publication_rel pr\n"
5187  "WHERE c.relnamespace = n.oid\n"
5188  " AND c.oid = pr.prrelid\n"
5189  " AND pr.prpubid = '%s'\n"
5190  "ORDER BY 1,2", pubid);
5191 
5192  tabres = PSQLexec(buf.data);
5193  if (!tabres)
5194  {
5195  printTableCleanup(&cont);
5196  PQclear(res);
5197  termPQExpBuffer(&buf);
5198  termPQExpBuffer(&title);
5199  return false;
5200  }
5201  else
5202  tables = PQntuples(tabres);
5203 
5204  if (tables > 0)
5205  printTableAddFooter(&cont, _("Tables:"));
5206 
5207  for (j = 0; j < tables; j++)
5208  {
5209  printfPQExpBuffer(&buf, " \"%s.%s\"",
5210  PQgetvalue(tabres, j, 0),
5211  PQgetvalue(tabres, j, 1));
5212 
5213  printTableAddFooter(&cont, buf.data);
5214  }
5215  PQclear(tabres);
5216  }
5217 
5218  printTable(&cont, pset.queryFout, false, pset.logfile);
5219  printTableCleanup(&cont);
5220 
5221  termPQExpBuffer(&title);
5222  }
5223 
5224  termPQExpBuffer(&buf);
5225  PQclear(res);
5226 
5227  return true;
5228 }
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:833
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:66
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3188
void psql_error(const char *fmt,...)
Definition: common.c:220
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 _(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:642
bool describeRoles ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

3053 {
3055  PGresult *res;
3056  printTableContent cont;
3057  printTableOpt myopt = pset.popt.topt;
3058  int ncols = 3;
3059  int nrows = 0;
3060  int i;
3061  int conns;
3062  const char align = 'l';
3063  char **attr;
3064 
3065  myopt.default_footer = false;
3066 
3067  initPQExpBuffer(&buf);
3068 
3069  if (pset.sversion >= 80100)
3070  {
3071  printfPQExpBuffer(&buf,
3072  "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
3073  " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
3074  " r.rolconnlimit, r.rolvaliduntil,\n"
3075  " ARRAY(SELECT b.rolname\n"
3076  " FROM pg_catalog.pg_auth_members m\n"
3077  " JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
3078  " WHERE m.member = r.oid) as memberof");
3079 
3080  if (verbose && pset.sversion >= 80200)
3081  {
3082  appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
3083  ncols++;
3084  }
3085  if (pset.sversion >= 90100)
3086  {
3087  appendPQExpBufferStr(&buf, "\n, r.rolreplication");
3088  }
3089 
3090  if (pset.sversion >= 90500)
3091  {
3092  appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
3093  }
3094 
3095  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
3096 
3097  if (!showSystem && !pattern)
3098  appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
3099 
3100  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3101  NULL, "r.rolname", NULL, NULL);
3102  }
3103  else
3104  {
3105  printfPQExpBuffer(&buf,
3106  "SELECT u.usename AS rolname,\n"
3107  " u.usesuper AS rolsuper,\n"
3108  " true AS rolinherit, false AS rolcreaterole,\n"
3109  " u.usecreatedb AS rolcreatedb, true AS rolcanlogin,\n"
3110  " -1 AS rolconnlimit,"
3111  " u.valuntil as rolvaliduntil,\n"
3112  " ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as memberof"
3113  "\nFROM pg_catalog.pg_user u\n");
3114 
3115  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3116  NULL, "u.usename", NULL, NULL);
3117  }
3118 
3119  appendPQExpBufferStr(&buf, "ORDER BY 1;");
3120 
3121  res = PSQLexec(buf.data);
3122  if (!res)
3123  return false;
3124 
3125  nrows = PQntuples(res);
3126  attr = pg_malloc0((nrows + 1) * sizeof(*attr));
3127 
3128  printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
3129 
3130  printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
3131  printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
3132  printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
3133 
3134  if (verbose && pset.sversion >= 80200)
3135  printTableAddHeader(&cont, gettext_noop("Description"), true, align);
3136 
3137  for (i = 0; i < nrows; i++)
3138  {
3139  printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
3140 
3141  resetPQExpBuffer(&buf);
3142  if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
3143  add_role_attribute(&buf, _("Superuser"));
3144 
3145  if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
3146  add_role_attribute(&buf, _("No inheritance"));
3147 
3148  if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
3149  add_role_attribute(&buf, _("Create role"));
3150 
3151  if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
3152  add_role_attribute(&buf, _("Create DB"));
3153 
3154  if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
3155  add_role_attribute(&buf, _("Cannot login"));
3156 
3157  if (pset.sversion >= 90100)
3158  if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3159  add_role_attribute(&buf, _("Replication"));
3160 
3161  if (pset.sversion >= 90500)
3162  if (strcmp(PQgetvalue(res, i, (verbose ? 11 : 10)), "t") == 0)
3163  add_role_attribute(&buf, _("Bypass RLS"));
3164 
3165  conns = atoi(PQgetvalue(res, i, 6));
3166  if (conns >= 0)
3167  {
3168  if (buf.len > 0)
3169  appendPQExpBufferChar(&buf, '\n');
3170 
3171  if (conns == 0)
3172  appendPQExpBufferStr(&buf, _("No connections"));
3173  else
3174  appendPQExpBuffer(&buf, ngettext("%d connection",
3175  "%d connections",
3176  conns),
3177  conns);
3178  }
3179 
3180  if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3181  {
3182  if (buf.len > 0)
3183  appendPQExpBufferStr(&buf, "\n");
3184  appendPQExpBufferStr(&buf, _("Password valid until "));
3185  appendPQExpBufferStr(&buf, PQgetvalue(res, i, 7));
3186  }
3187 
3188  attr[i] = pg_strdup(buf.data);
3189 
3190  printTableAddCell(&cont, attr[i], false, false);
3191 
3192  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3193 
3194  if (verbose && pset.sversion >= 80200)
3195  printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
3196  }
3197  termPQExpBuffer(&buf);
3198 
3199  printTable(&cont, pset.queryFout, false, pset.logfile);
3200  printTableCleanup(&cont);
3201 
3202  for (i = 0; i < nrows; i++)
3203  free(attr[i]);
3204  free(attr);
3205 
3206  PQclear(res);
3207  return true;
3208 }
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:833
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static void add_role_attribute(PQExpBuffer buf, const char *const str)
Definition: describe.c:3211
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:66
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:642
bool describeSubscriptions ( const char *  pattern,
bool  verbose 
)

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

5237 {
5239  PGresult *res;
5240  printQueryOpt myopt = pset.popt;
5241  static const bool translate_columns[] = {false, false, false, false,
5242  false, false};
5243 
5244  if (pset.sversion < 100000)
5245  {
5246  char sverbuf[32];
5247 
5248  psql_error("The server (version %s) does not support subscriptions.\n",
5250  sverbuf, sizeof(sverbuf)));
5251  return true;
5252  }
5253 
5254  initPQExpBuffer(&buf);
5255 
5256  printfPQExpBuffer(&buf,
5257  "SELECT subname AS \"%s\"\n"
5258  ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
5259  ", subenabled AS \"%s\"\n"
5260  ", subpublications AS \"%s\"\n",
5261  gettext_noop("Name"),
5262  gettext_noop("Owner"),
5263  gettext_noop("Enabled"),
5264  gettext_noop("Publication"));
5265 
5266  if (verbose)
5267  {
5268  appendPQExpBuffer(&buf,
5269  ", subsynccommit AS \"%s\"\n"
5270  ", subconninfo AS \"%s\"\n",
5271  gettext_noop("Synchronous commit"),
5272  gettext_noop("Conninfo"));
5273  }
5274 
5275  /* Only display subscriptions in current database. */
5276  appendPQExpBufferStr(&buf,
5277  "FROM pg_catalog.pg_subscription\n"
5278  "WHERE subdbid = (SELECT oid\n"
5279  " FROM pg_catalog.pg_database\n"
5280  " WHERE datname = current_database())");
5281 
5282  processSQLNamePattern(pset.db, &buf, pattern, true, false,
5283  NULL, "subname", NULL,
5284  NULL);
5285 
5286  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5287 
5288  res = PSQLexec(buf.data);
5289  termPQExpBuffer(&buf);
5290  if (!res)
5291  return false;
5292 
5293  myopt.nullPrint = NULL;
5294  myopt.title = _("List of subscriptions");
5295  myopt.translate_header = true;
5296  myopt.translate_columns = translate_columns;
5297  myopt.n_translate_columns = lengthof(translate_columns);
5298 
5299  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5300 
5301  PQclear(res);
5302  return true;
5303 }
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:833
#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:66
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:84
void psql_error(const char *fmt,...)
Definition: common.c:220
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:642
bool describeTableDetails ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

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

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

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

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

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

Definition at line 780 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_list(), and main().

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

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

3758 {
3760  PGresult *res;
3761  printQueryOpt myopt = pset.popt;
3762  static const bool translate_columns[] = {false, false, false, true, false};
3763 
3764  initPQExpBuffer(&buf);
3765 
3766  /*
3767  * We need a left join to pg_proc for binary casts; the others are just
3768  * paranoia. Also note that we don't attempt to localize '(binary
3769  * coercible)', because there's too much risk of gettext translating a
3770  * function name that happens to match some string in the PO database.
3771  */
3772  printfPQExpBuffer(&buf,
3773  "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n"
3774  " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n"
3775  " CASE WHEN castfunc = 0 THEN '(binary coercible)'\n"
3776  " ELSE p.proname\n"
3777  " END as \"%s\",\n"
3778  " CASE WHEN c.castcontext = 'e' THEN '%s'\n"
3779  " WHEN c.castcontext = 'a' THEN '%s'\n"
3780  " ELSE '%s'\n"
3781  " END as \"%s\"",
3782  gettext_noop("Source type"),
3783  gettext_noop("Target type"),
3784  gettext_noop("Function"),
3785  gettext_noop("no"),
3786  gettext_noop("in assignment"),
3787  gettext_noop("yes"),
3788  gettext_noop("Implicit?"));
3789 
3790  if (verbose)
3791  appendPQExpBuffer(&buf,
3792  ",\n d.description AS \"%s\"\n",
3793  gettext_noop("Description"));
3794 
3795  appendPQExpBufferStr(&buf,
3796  "FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
3797  " ON c.castfunc = p.oid\n"
3798  " LEFT JOIN pg_catalog.pg_type ts\n"
3799  " ON c.castsource = ts.oid\n"
3800  " LEFT JOIN pg_catalog.pg_namespace ns\n"
3801  " ON ns.oid = ts.typnamespace\n"
3802  " LEFT JOIN pg_catalog.pg_type tt\n"
3803  " ON c.casttarget = tt.oid\n"
3804  " LEFT JOIN pg_catalog.pg_namespace nt\n"
3805  " ON nt.oid = tt.typnamespace\n");
3806 
3807  if (verbose)
3808  appendPQExpBufferStr(&buf,
3809  " LEFT JOIN pg_catalog.pg_description d\n"
3810  " ON d.classoid = c.tableoid AND d.objoid = "
3811  "c.oid AND d.objsubid = 0\n");
3812 
3813  appendPQExpBufferStr(&buf, "WHERE ( (true");
3814 
3815  /*
3816  * Match name pattern against either internal or external name of either
3817  * castsource or casttarget
3818  */
3819  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3820  "ns.nspname", "ts.typname",
3821  "pg_catalog.format_type(ts.oid, NULL)",
3822  "pg_catalog.pg_type_is_visible(ts.oid)");
3823 
3824  appendPQExpBufferStr(&buf, ") OR (true");
3825 
3826  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3827  "nt.nspname", "tt.typname",
3828  "pg_catalog.format_type(tt.oid, NULL)",
3829  "pg_catalog.pg_type_is_visible(tt.oid)");
3830 
3831  appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
3832 
3833  res = PSQLexec(buf.data);
3834  termPQExpBuffer(&buf);
3835  if (!res)
3836  return false;
3837 
3838  myopt.nullPrint = NULL;
3839  myopt.title = _("List of casts");
3840  myopt.translate_header = true;
3841  myopt.translate_columns = translate_columns;
3842  myopt.n_translate_columns = lengthof(translate_columns);
3843 
3844  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3845 
3846  PQclear(res);
3847  return true;
3848 }
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:833
#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:66
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:642
bool listCollations ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

3857 {
3859  PGresult *res;
3860  printQueryOpt myopt = pset.popt;
3861  static const bool translate_columns[] = {false, false, false, false, false, false};
3862 
3863  if (pset.sversion < 90100)
3864  {
3865  char sverbuf[32];
3866 
3867  psql_error("The server (version %s) does not support collations.\n",
3869  sverbuf, sizeof(sverbuf)));
3870  return true;
3871  }
3872 
3873  initPQExpBuffer(&buf);
3874 
3875  printfPQExpBuffer(&buf,
3876  "SELECT n.nspname AS \"%s\",\n"
3877  " c.collname AS \"%s\",\n"
3878  " c.collcollate AS \"%s\",\n"
3879  " c.collctype AS \"%s\"",
3880  gettext_noop("Schema"),
3881  gettext_noop("Name"),
3882  gettext_noop("Collate"),
3883  gettext_noop("Ctype"));
3884 
3885  if (pset.sversion >= 100000)
3886  appendPQExpBuffer(&buf,
3887  ",\n CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\"",
3888  gettext_noop("Provider"));
3889 
3890  if (verbose)
3891  appendPQExpBuffer(&buf,
3892  ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
3893  gettext_noop("Description"));
3894 
3895  appendPQExpBufferStr(&buf,
3896  "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
3897  "WHERE n.oid = c.collnamespace\n");
3898 
3899  if (!showSystem && !pattern)
3900  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3901  " AND n.nspname <> 'information_schema'\n");
3902 
3903  /*
3904  * Hide collations that aren't usable in the current database's encoding.
3905  * If you think to change this, note that pg_collation_is_visible rejects
3906  * unusable collations, so you will need to hack name pattern processing
3907  * somehow to avoid inconsistent behavior.
3908  */
3909  appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
3910 
3911  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3912  "n.nspname", "c.collname", NULL,
3913  "pg_catalog.pg_collation_is_visible(c.oid)");
3914 
3915  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3916 
3917  res = PSQLexec(buf.data);
3918  termPQExpBuffer(&buf);
3919  if (!res)
3920  return false;
3921 
3922  myopt.nullPrint = NULL;
3923  myopt.title = _("List of collations");
3924  myopt.translate_header = true;
3925  myopt.translate_columns = translate_columns;
3926  myopt.n_translate_columns = lengthof(translate_columns);
3927 
3928  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3929 
3930  PQclear(res);
3931  return true;
3932 }
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:833
#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:66
bool translate_header
Definition: print.h:169
static int verbose
Definition: pg_basebackup.c:84
void psql_error(const char *fmt,...)
Definition: common.c:220
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:642
bool listConversions ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

3616 {
3618  PGresult *res;
3619  printQueryOpt myopt = pset.popt;
3620  static const bool translate_columns[] =
3621  {false, false, false, false, true, false};
3622 
3623  initPQExpBuffer(&buf);
3624 
3625  printfPQExpBuffer(&buf,
3626  "SELECT n.nspname AS \"%s\",\n"
3627  " c.conname AS \"%s\",\n"
3628  " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
3629  " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
3630  " CASE WHEN c.condefault THEN '%s'\n"
3631  " ELSE '%s' END AS \"%s\"",
3632  gettext_noop("Schema"),
3633  gettext_noop("Name"),
3634  gettext_noop("Source"),
3635  gettext_noop("Destination"),
3636  gettext_noop("yes"), gettext_noop("no"),
3637  gettext_noop("Default?"));
3638 
3639  if (verbose)
3640  appendPQExpBuffer(&buf,
3641  ",\n d.description AS \"%s\"",
3642  gettext_noop("Description"));
3643 
3644  appendPQExpBufferStr(&buf,
3645  "\nFROM pg_catalog.pg_conversion c\n"
3646  " JOIN pg_catalog.pg_namespace n "
3647  "ON n.oid = c.connamespace\n");
3648 
3649  if (verbose)
3650  appendPQExpBufferStr(&buf,
3651  "LEFT JOIN pg_catalog.pg_description d "
3652  "ON d.classoid = c.tableoid\n"
3653  " AND d.objoid = c.oid "
3654  "AND d.objsubid = 0\n");
3655 
3656  appendPQExpBufferStr(&buf, "WHERE true\n");
3657 
3658  if (!showSystem && !pattern)
3659  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3660  " AND n.nspname <> 'information_schema'\n");
3661 
3662  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3663  "n.nspname", "c.conname", NULL,
3664  "pg_catalog.pg_conversion_is_visible(c.oid)");
3665 
3666  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3667 
3668  res = PSQLexec(buf.data);
3669  termPQExpBuffer(&buf);
3670  if (!res)
3671  return false;
3672 
3673  myopt.nullPrint = NULL;
3674  myopt.title = _("List of conversions");
3675  myopt.translate_header = true;
3676  myopt.translate_columns = translate_columns;
3677  myopt.n_translate_columns = lengthof(translate_columns);
3678 
3679  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3680 
3681  PQclear(res);
3682  return true;
3683 }
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:833
#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:66
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:642
bool listDbRoleSettings ( const char *  pattern,
const char *  pattern2 
)

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

3224 {
3226  PGresult *res;
3227  printQueryOpt myopt = pset.popt;
3228 
3229  initPQExpBuffer(&buf);
3230 
3231  if (pset.sversion >= 90000)
3232  {
3233  bool havewhere;
3234 
3235  printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
3236  "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
3237  "FROM pg_db_role_setting AS s\n"
3238  "LEFT JOIN pg_database ON pg_database.oid = setdatabase\n"
3239  "LEFT JOIN pg_roles ON pg_roles.oid = setrole\n",
3240  gettext_noop("Role"),
3241  gettext_noop("Database"),
3242  gettext_noop("Settings"));
3243  havewhere = processSQLNamePattern(pset.db, &buf, pattern, false, false,
3244  NULL, "pg_roles.rolname", NULL, NULL);
3245  processSQLNamePattern(pset.db, &buf, pattern2, havewhere, false,
3246  NULL, "pg_database.datname", NULL, NULL);
3247  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3248  }
3249  else
3250  {
3251  fprintf(pset.queryFout,
3252  _("No per-database role settings support in this server version.\n"));
3253  return false;
3254  }
3255 
3256  res = PSQLexec(buf.data);
3257  if (!res)
3258  return false;
3259 
3260  if (PQntuples(res) == 0 && !pset.quiet)
3261  {
3262  if (pattern)
3263  fprintf(pset.queryFout, _("No matching settings found.\n"));
3264  else
3265  fprintf(pset.queryFout, _("No settings found.\n"));
3266  }
3267  else
3268  {
3269  myopt.nullPrint = NULL;
3270  myopt.title = _("List of settings");
3271  myopt.translate_header = true;
3272 
3273  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3274  }
3275 
3276  PQclear(res);
3277  resetPQExpBuffer(&buf);
3278  return true;
3279 }
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:833
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
static char * buf
Definition: pg_test_fsync.c:66
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:642
bool listDefaultACLs ( const char *  pattern)

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

1011 {
1013  PGresult *res;
1014  printQueryOpt myopt = pset.popt;
1015  static const bool translate_columns[] = {false, false, true, false};
1016 
1017  if (pset.sversion < 90000)
1018  {
1019  char sverbuf[32];
1020 
1021  psql_error("The server (version %s) does not support altering default privileges.\n",
1023  sverbuf, sizeof(sverbuf)));
1024  return true;
1025  }
1026 
1027  initPQExpBuffer(&buf);
1028 
1029  printfPQExpBuffer(&buf,
1030  "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
1031  " n.nspname AS \"%s\",\n"
1032  " 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"
1033  " ",
1034  gettext_noop("Owner"),
1035  gettext_noop("Schema"),
1037  gettext_noop("table"),
1039  gettext_noop("sequence"),
1041  gettext_noop("function"),
1043  gettext_noop("type"),
1045  gettext_noop("schema"),
1046  gettext_noop("Type"));
1047 
1048  printACLColumn(&buf, "d.defaclacl");
1049 
1050  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
1051  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
1052 
1053  processSQLNamePattern(pset.db, &buf, pattern, false, false,
1054  NULL,
1055  "n.nspname",
1056  "pg_catalog.pg_get_userbyid(d.defaclrole)",
1057  NULL);
1058 
1059  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1060 
1061  res = PSQLexec(buf.data);
1062  if (!res)
1063  {
1064  termPQExpBuffer(&buf);
1065  return false;
1066  }
1067 
1068  myopt.nullPrint = NULL;
1069  printfPQExpBuffer(&buf, _("Default access privileges"));
1070  myopt.title = buf.data;
1071  myopt.translate_header = true;
1072  myopt.translate_columns = translate_columns;
1073  myopt.n_translate_columns = lengthof(translate_columns);
1074 
1075  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1076 
1077  termPQExpBuffer(&buf);
1078  PQclear(res);
1079  return true;
1080 }
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:833
#define lengthof(array)
Definition: c.h:562
#define DEFACLOBJ_SEQUENCE
static char * buf
Definition: pg_test_fsync.c:66
bool translate_header
Definition: print.h:169
#define DEFACLOBJ_TYPE
void psql_error(const char *fmt,...)
Definition: common.c:220
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:5313
#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:642
bool listDomains ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

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

3530 {
3532  PGresult *res;
3533  printQueryOpt myopt = pset.popt;
3534 
3535  initPQExpBuffer(&buf);
3536 
3537  printfPQExpBuffer(&buf,
3538  "SELECT n.nspname as \"%s\",\n"
3539  " t.typname as \"%s\",\n"
3540  " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n",
3541  gettext_noop("Schema"),
3542  gettext_noop("Name"),
3543  gettext_noop("Type"));
3544 
3545  if (pset.sversion >= 90100)
3546  appendPQExpBuffer(&buf,
3547  " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
3548  " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n",
3549  gettext_noop("Collation"));
3550  appendPQExpBuffer(&buf,
3551  " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
3552  " t.typdefault as \"%s\",\n"
3553  " pg_catalog.array_to_string(ARRAY(\n"
3554  " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid\n"
3555  " ), ' ') as \"%s\"",
3556  gettext_noop("Nullable"),
3557  gettext_noop("Default"),
3558  gettext_noop("Check"));
3559 
3560  if (verbose)
3561  {
3562  if (pset.sversion >= 90200)
3563  {
3564  appendPQExpBufferStr(&buf, ",\n ");
3565  printACLColumn(&buf, "t.typacl");
3566  }
3567  appendPQExpBuffer(&buf,
3568  ",\n d.description as \"%s\"",
3569  gettext_noop("Description"));
3570  }
3571 
3572  appendPQExpBufferStr(&buf,
3573  "\nFROM pg_catalog.pg_type t\n"
3574  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
3575 
3576  if (verbose)
3577  appendPQExpBufferStr(&buf,
3578  " LEFT JOIN pg_catalog.pg_description d "
3579  "ON d.classoid = t.tableoid AND d.objoid = t.oid "
3580  "AND d.objsubid = 0\n");
3581 
3582  appendPQExpBufferStr(&buf, "WHERE t.typtype = 'd'\n");
3583 
3584  if (!showSystem && !pattern)
3585  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
3586  " AND n.nspname <> 'information_schema'\n");
3587 
3588  processSQLNamePattern(pset.db, &buf, pattern, true, false,
3589  "n.nspname", "t.typname", NULL,
3590  "pg_catalog.pg_type_is_visible(t.oid)");
3591 
3592  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3593 
3594  res = PSQLexec(buf.data);
3595  termPQExpBuffer(&buf);
3596  if (!res)
3597  return false;
3598 
3599  myopt.nullPrint = NULL;
3600  myopt.title = _("List of domains");
3601  myopt.translate_header = true;
3602 
3603  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3604 
3605  PQclear(res);
3606  return true;
3607 }
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:833
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:66
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:5313
#define _(x)
Definition: elog.c:84
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
PGresult * PSQLexec(const char *query)
Definition: common.c:642
bool listEventTriggers ( const char *  pattern,
bool  verbose 
)

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

3692 {
3694  PGresult *res;
3695  printQueryOpt myopt = pset.popt;
3696  static const bool translate_columns[] =
3697  {false, false, false, true, false, false, false};
3698 
3699  initPQExpBuffer(&buf);
3700 
3701  printfPQExpBuffer(&buf,
3702  "SELECT evtname as \"%s\", "
3703  "evtevent as \"%s\", "
3704  "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n"
3705  " case evtenabled when 'O' then '%s'"
3706  " when 'R' then '%s'"
3707  " when 'A' then '%s'"
3708  " when 'D' then '%s' end as \"%s\",\n"
3709  " e.evtfoid::pg_catalog.regproc as \"%s\", "
3710  "pg_catalog.array_to_string(array(select x"
3711  " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
3712  gettext_noop("Name"),
3713  gettext_noop("Event"),
3714  gettext_noop("Owner"),
3715  gettext_noop("enabled"),
3716  gettext_noop("replica"),
3717  gettext_noop("always"),
3718  gettext_noop("disabled"),
3719  gettext_noop("Enabled"),
3720  gettext_noop("Procedure"),
3721  gettext_noop("Tags"));
3722  if (verbose)
3723  appendPQExpBuffer(&buf,
3724  ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
3725  gettext_noop("Description"));
3726  appendPQExpBufferStr(&buf,
3727  "\nFROM pg_catalog.pg_event_trigger e ");
3728 
3729  processSQLNamePattern(pset.db, &buf, pattern, false, false,
3730  NULL, "evtname", NULL, NULL);
3731 
3732  appendPQExpBufferStr(&buf, "ORDER BY 1");
3733 
3734  res = PSQLexec(buf.data);
3735  termPQExpBuffer(&buf);
3736  if (!res)
3737  return false;
3738 
3739  myopt.nullPrint = NULL;
3740  myopt.title = _("List of event triggers");
3741  myopt.translate_header = true;
3742  myopt.translate_columns = translate_columns;
3743  myopt.n_translate_columns = lengthof(translate_columns);
3744 
3745  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3746 
3747  PQclear(res);
3748  return true;
3749 }
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:833
#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:66
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:642
bool listExtensionContents ( const char *  pattern)

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

4940 {
4942  PGresult *res;
4943  int i;
4944 
4945  if (pset.sversion < 90100)
4946  {
4947  char sverbuf[32];
4948 
4949  psql_error("The server (version %s) does not support extensions.\n",
4951  sverbuf, sizeof(sverbuf)));
4952  return true;
4953  }
4954 
4955  initPQExpBuffer(&buf);
4956  printfPQExpBuffer(&buf,
4957  "SELECT e.extname, e.oid\n"
4958  "FROM pg_catalog.pg_extension e\n");
4959 
4960  processSQLNamePattern(pset.db, &buf, pattern,
4961  false, false,
4962  NULL, "e.extname", NULL,
4963  NULL);
4964 
4965  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4966 
4967  res = PSQLexec(buf.data);
4968  termPQExpBuffer(&buf);
4969  if (!res)
4970  return false;
4971 
4972  if (PQntuples(res) == 0)
4973  {
4974  if (!pset.quiet)
4975  {
4976  if (pattern)
4977  psql_error("Did not find any extension named \"%s\".\n",
4978  pattern);
4979  else
4980  psql_error("Did not find any extensions.\n");
4981  }
4982  PQclear(res);
4983  return false;
4984  }
4985 
4986  for (i = 0; i < PQntuples(res); i++)
4987  {
4988  const char *extname;
4989  const char *oid;
4990 
4991  extname = PQgetvalue(res, i, 0);
4992  oid = PQgetvalue(res, i, 1);
4993 
4994  if (!listOneExtensionContents(extname, oid))
4995  {
4996  PQclear(res);
4997  return false;
4998  }
4999  if (cancel_pressed)
5000  {
5001  PQclear(res);
5002  return false;
5003  }
5004  }
5005 
5006  PQclear(res);
5007  return true;
5008 }
PGconn * db
Definition: settings.h:82
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:234
PsqlSettings pset
Definition: startup.c:33