PostgreSQL Source Code  git master
describe.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

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 *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
 
bool describeTypes (const char *pattern, bool verbose, bool showSystem)
 
bool describeOperators (const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
 
bool describeRoles (const char *pattern, bool verbose, bool showSystem)
 
bool listDbRoleSettings (const char *pattern, const char *pattern2)
 
bool describeRoleGrants (const char *pattern, bool showSystem)
 
bool permissionsList (const char *pattern, bool showSystem)
 
bool listDefaultACLs (const char *pattern)
 
bool objectDescription (const char *pattern, bool showSystem)
 
bool describeTableDetails (const char *pattern, bool verbose, bool showSystem)
 
bool listTSConfigs (const char *pattern, bool verbose)
 
bool listTSParsers (const char *pattern, bool verbose)
 
bool listTSDictionaries (const char *pattern, bool verbose)
 
bool listTSTemplates (const char *pattern, bool verbose)
 
bool listAllDbs (const char *pattern, bool verbose)
 
bool listTables (const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
 
bool listPartitionedTables (const char *reltypes, const char *pattern, bool verbose)
 
bool listDomains (const char *pattern, bool verbose, bool showSystem)
 
bool listConversions (const char *pattern, bool verbose, bool showSystem)
 
bool describeConfigurationParameters (const char *pattern, bool verbose, bool showSystem)
 
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 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 listLanguages (const char *pattern, bool verbose, bool showSystem)
 
bool listExtensions (const char *pattern)
 
bool listExtensionContents (const char *pattern)
 
bool listExtendedStats (const char *pattern)
 
bool listEventTriggers (const char *pattern, bool verbose)
 
bool listPublications (const char *pattern)
 
bool describePublications (const char *pattern)
 
bool describeSubscriptions (const char *pattern, bool verbose)
 
bool listOperatorClasses (const char *access_method_pattern, const char *type_pattern, bool verbose)
 
bool listOperatorFamilies (const char *access_method_pattern, const char *type_pattern, bool verbose)
 
bool listOpFamilyOperators (const char *access_method_pattern, const char *family_pattern, bool verbose)
 
bool listOpFamilyFunctions (const char *access_method_pattern, const char *family_pattern, bool verbose)
 
bool listLargeObjects (bool verbose)
 

Function Documentation

◆ describeAccessMethods()

bool describeAccessMethods ( const char *  pattern,
bool  verbose 
)

Definition at line 141 of file describe.c.

142 {
144  PGresult *res;
145  printQueryOpt myopt = pset.popt;
146  static const bool translate_columns[] = {false, true, false, false};
147 
148  if (pset.sversion < 90600)
149  {
150  char sverbuf[32];
151 
152  pg_log_error("The server (version %s) does not support access methods.",
154  sverbuf, sizeof(sverbuf)));
155  return true;
156  }
157 
159 
161  "SELECT amname AS \"%s\",\n"
162  " CASE amtype"
163  " WHEN 'i' THEN '%s'"
164  " WHEN 't' THEN '%s'"
165  " END AS \"%s\"",
166  gettext_noop("Name"),
167  gettext_noop("Index"),
168  gettext_noop("Table"),
169  gettext_noop("Type"));
170 
171  if (verbose)
172  {
174  ",\n amhandler AS \"%s\",\n"
175  " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
176  gettext_noop("Handler"),
177  gettext_noop("Description"));
178  }
179 
181  "\nFROM pg_catalog.pg_am\n");
182 
183  if (!validateSQLNamePattern(&buf, pattern, false, false,
184  NULL, "amname", NULL,
185  NULL,
186  NULL, 1))
187  {
189  return false;
190  }
191 
192  appendPQExpBufferStr(&buf, "ORDER BY 1;");
193 
194  res = PSQLexec(buf.data);
196  if (!res)
197  return false;
198 
199  myopt.title = _("List of access methods");
200  myopt.translate_header = true;
201  myopt.translate_columns = translate_columns;
202  myopt.n_translate_columns = lengthof(translate_columns);
203 
204  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
205 
206  PQclear(res);
207  return true;
208 }
PGresult * PSQLexec(const char *query)
Definition: common.c:620
#define gettext_noop(x)
Definition: c.h:1196
#define lengthof(array)
Definition: c.h:788
static bool validateSQLNamePattern(PQExpBuffer buf, const char *pattern, bool have_where, bool force_escape, const char *schemavar, const char *namevar, const char *altnamevar, const char *visibilityrule, bool *added_clause, int maxparts)
Definition: describe.c:6216
#define _(x)
Definition: elog.c:90
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3549
int verbose
#define pg_log_error(...)
Definition: logging.h:106
static char * buf
Definition: pg_test_fsync.c:73
void printfPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:235
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:265
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
PsqlSettings pset
Definition: startup.c:32
char * formatPGVersionNumber(int version_number, bool include_minor, char *buf, size_t buflen)
Definition: string_utils.c:177
printQueryOpt popt
Definition: settings.h:91
FILE * logfile
Definition: settings.h:120
FILE * queryFout
Definition: settings.h:84
const bool * translate_columns
Definition: print.h:190
char * title
Definition: print.h:187
bool translate_header
Definition: print.h:189
int n_translate_columns
Definition: print.h:192

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ describeAggregates()

bool describeAggregates ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 71 of file describe.c.

72 {
74  PGresult *res;
75  printQueryOpt myopt = pset.popt;
76 
78 
80  "SELECT n.nspname as \"%s\",\n"
81  " p.proname AS \"%s\",\n"
82  " pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n"
83  " CASE WHEN p.pronargs = 0\n"
84  " THEN CAST('*' AS pg_catalog.text)\n"
85  " ELSE pg_catalog.pg_get_function_arguments(p.oid)\n"
86  " END AS \"%s\",\n",
87  gettext_noop("Schema"),
88  gettext_noop("Name"),
89  gettext_noop("Result data type"),
90  gettext_noop("Argument data types"));
91 
92  if (pset.sversion >= 110000)
94  " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
95  "FROM pg_catalog.pg_proc p\n"
96  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
97  "WHERE p.prokind = 'a'\n",
98  gettext_noop("Description"));
99  else
101  " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
102  "FROM pg_catalog.pg_proc p\n"
103  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
104  "WHERE p.proisagg\n",
105  gettext_noop("Description"));
106 
107  if (!showSystem && !pattern)
108  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
109  " AND n.nspname <> 'information_schema'\n");
110 
111  if (!validateSQLNamePattern(&buf, pattern, true, false,
112  "n.nspname", "p.proname", NULL,
113  "pg_catalog.pg_function_is_visible(p.oid)",
114  NULL, 3))
115  {
117  return false;
118  }
119 
120  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
121 
122  res = PSQLexec(buf.data);
124  if (!res)
125  return false;
126 
127  myopt.title = _("List of aggregate functions");
128  myopt.translate_header = true;
129 
130  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
131 
132  PQclear(res);
133  return true;
134 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ describeConfigurationParameters()

bool describeConfigurationParameters ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 4598 of file describe.c.

4600 {
4602  PGresult *res;
4603  printQueryOpt myopt = pset.popt;
4604 
4605  initPQExpBuffer(&buf);
4607  "SELECT s.name AS \"%s\", "
4608  "pg_catalog.current_setting(s.name) AS \"%s\"",
4609  gettext_noop("Parameter"),
4610  gettext_noop("Value"));
4611 
4612  if (verbose)
4613  {
4615  ", s.vartype AS \"%s\", s.context AS \"%s\", ",
4616  gettext_noop("Type"),
4617  gettext_noop("Context"));
4618  if (pset.sversion >= 150000)
4619  printACLColumn(&buf, "p.paracl");
4620  else
4621  appendPQExpBuffer(&buf, "NULL AS \"%s\"",
4622  gettext_noop("Access privileges"));
4623  }
4624 
4625  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_settings s\n");
4626 
4627  if (verbose && pset.sversion >= 150000)
4629  " LEFT JOIN pg_catalog.pg_parameter_acl p\n"
4630  " ON pg_catalog.lower(s.name) = p.parname\n");
4631 
4632  if (pattern)
4633  processSQLNamePattern(pset.db, &buf, pattern,
4634  false, false,
4635  NULL, "pg_catalog.lower(s.name)", NULL,
4636  NULL, NULL, NULL);
4637  else
4638  appendPQExpBufferStr(&buf, "WHERE s.source <> 'default' AND\n"
4639  " s.setting IS DISTINCT FROM s.boot_val\n");
4640 
4641  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4642 
4643  res = PSQLexec(buf.data);
4644  termPQExpBuffer(&buf);
4645  if (!res)
4646  return false;
4647 
4648  if (pattern)
4649  myopt.title = _("List of configuration parameters");
4650  else
4651  myopt.title = _("List of non-default configuration parameters");
4652  myopt.translate_header = true;
4653 
4654  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4655 
4656  PQclear(res);
4657  return true;
4658 }
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:6711
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, PQExpBuffer dbnamebuf, int *dotcnt)
Definition: string_utils.c:891
PGconn * db
Definition: settings.h:82

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

Referenced by exec_command_d().

◆ describeFunctions()

bool describeFunctions ( const char *  functypes,
const char *  func_pattern,
char **  arg_patterns,
int  num_arg_patterns,
bool  verbose,
bool  showSystem 
)

Definition at line 288 of file describe.c.

291 {
292  bool showAggregate = strchr(functypes, 'a') != NULL;
293  bool showNormal = strchr(functypes, 'n') != NULL;
294  bool showProcedure = strchr(functypes, 'p') != NULL;
295  bool showTrigger = strchr(functypes, 't') != NULL;
296  bool showWindow = strchr(functypes, 'w') != NULL;
297  bool have_where;
299  PGresult *res;
300  printQueryOpt myopt = pset.popt;
301  static const bool translate_columns[] = {false, false, false, false, true, true, true, false, true, false, false, false, false};
302 
303  /* No "Parallel" column before 9.6 */
304  static const bool translate_columns_pre_96[] = {false, false, false, false, true, true, false, true, false, false, false, false};
305 
306  if (strlen(functypes) != strspn(functypes, "anptwS+"))
307  {
308  pg_log_error("\\df only takes [anptwS+] as options");
309  return true;
310  }
311 
312  if (showProcedure && pset.sversion < 110000)
313  {
314  char sverbuf[32];
315 
316  pg_log_error("\\df does not take a \"%c\" option with server version %s",
317  'p',
319  sverbuf, sizeof(sverbuf)));
320  return true;
321  }
322 
323  if (!showAggregate && !showNormal && !showProcedure && !showTrigger && !showWindow)
324  {
325  showAggregate = showNormal = showTrigger = showWindow = true;
326  if (pset.sversion >= 110000)
327  showProcedure = true;
328  }
329 
331 
333  "SELECT n.nspname as \"%s\",\n"
334  " p.proname as \"%s\",\n",
335  gettext_noop("Schema"),
336  gettext_noop("Name"));
337 
338  if (pset.sversion >= 110000)
340  " pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n"
341  " pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n"
342  " CASE p.prokind\n"
343  " WHEN 'a' THEN '%s'\n"
344  " WHEN 'w' THEN '%s'\n"
345  " WHEN 'p' THEN '%s'\n"
346  " ELSE '%s'\n"
347  " END as \"%s\"",
348  gettext_noop("Result data type"),
349  gettext_noop("Argument data types"),
350  /* translator: "agg" is short for "aggregate" */
351  gettext_noop("agg"),
352  gettext_noop("window"),
353  gettext_noop("proc"),
354  gettext_noop("func"),
355  gettext_noop("Type"));
356  else
358  " pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n"
359  " pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n"
360  " CASE\n"
361  " WHEN p.proisagg THEN '%s'\n"
362  " WHEN p.proiswindow THEN '%s'\n"
363  " WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s'\n"
364  " ELSE '%s'\n"
365  " END as \"%s\"",
366  gettext_noop("Result data type"),
367  gettext_noop("Argument data types"),
368  /* translator: "agg" is short for "aggregate" */
369  gettext_noop("agg"),
370  gettext_noop("window"),
371  gettext_noop("trigger"),
372  gettext_noop("func"),
373  gettext_noop("Type"));
374 
375  if (verbose)
376  {
378  ",\n CASE\n"
379  " WHEN p.provolatile = 'i' THEN '%s'\n"
380  " WHEN p.provolatile = 's' THEN '%s'\n"
381  " WHEN p.provolatile = 'v' THEN '%s'\n"
382  " END as \"%s\"",
383  gettext_noop("immutable"),
384  gettext_noop("stable"),
385  gettext_noop("volatile"),
386  gettext_noop("Volatility"));
387  if (pset.sversion >= 90600)
389  ",\n CASE\n"
390  " WHEN p.proparallel = 'r' THEN '%s'\n"
391  " WHEN p.proparallel = 's' THEN '%s'\n"
392  " WHEN p.proparallel = 'u' THEN '%s'\n"
393  " END as \"%s\"",
394  gettext_noop("restricted"),
395  gettext_noop("safe"),
396  gettext_noop("unsafe"),
397  gettext_noop("Parallel"));
399  ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\""
400  ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"",
401  gettext_noop("Owner"),
402  gettext_noop("definer"),
403  gettext_noop("invoker"),
404  gettext_noop("Security"));
405  appendPQExpBufferStr(&buf, ",\n ");
406  printACLColumn(&buf, "p.proacl");
408  ",\n l.lanname as \"%s\"",
409  gettext_noop("Language"));
411  ",\n CASE WHEN l.lanname IN ('internal', 'c') THEN p.prosrc END as \"%s\"",
412  gettext_noop("Internal name"));
414  ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
415  gettext_noop("Description"));
416  }
417 
419  "\nFROM pg_catalog.pg_proc p"
420  "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n");
421 
422  for (int i = 0; i < num_arg_patterns; i++)
423  {
425  " LEFT JOIN pg_catalog.pg_type t%d ON t%d.oid = p.proargtypes[%d]\n"
426  " LEFT JOIN pg_catalog.pg_namespace nt%d ON nt%d.oid = t%d.typnamespace\n",
427  i, i, i, i, i, i);
428  }
429 
430  if (verbose)
432  " LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
433 
434  have_where = false;
435 
436  /* filter by function type, if requested */
437  if (showNormal && showAggregate && showProcedure && showTrigger && showWindow)
438  /* Do nothing */ ;
439  else if (showNormal)
440  {
441  if (!showAggregate)
442  {
443  if (have_where)
444  appendPQExpBufferStr(&buf, " AND ");
445  else
446  {
447  appendPQExpBufferStr(&buf, "WHERE ");
448  have_where = true;
449  }
450  if (pset.sversion >= 110000)
451  appendPQExpBufferStr(&buf, "p.prokind <> 'a'\n");
452  else
453  appendPQExpBufferStr(&buf, "NOT p.proisagg\n");
454  }
455  if (!showProcedure && pset.sversion >= 110000)
456  {
457  if (have_where)
458  appendPQExpBufferStr(&buf, " AND ");
459  else
460  {
461  appendPQExpBufferStr(&buf, "WHERE ");
462  have_where = true;
463  }
464  appendPQExpBufferStr(&buf, "p.prokind <> 'p'\n");
465  }
466  if (!showTrigger)
467  {
468  if (have_where)
469  appendPQExpBufferStr(&buf, " AND ");
470  else
471  {
472  appendPQExpBufferStr(&buf, "WHERE ");
473  have_where = true;
474  }
475  appendPQExpBufferStr(&buf, "p.prorettype <> 'pg_catalog.trigger'::pg_catalog.regtype\n");
476  }
477  if (!showWindow)
478  {
479  if (have_where)
480  appendPQExpBufferStr(&buf, " AND ");
481  else
482  {
483  appendPQExpBufferStr(&buf, "WHERE ");
484  have_where = true;
485  }
486  if (pset.sversion >= 110000)
487  appendPQExpBufferStr(&buf, "p.prokind <> 'w'\n");
488  else
489  appendPQExpBufferStr(&buf, "NOT p.proiswindow\n");
490  }
491  }
492  else
493  {
494  bool needs_or = false;
495 
496  appendPQExpBufferStr(&buf, "WHERE (\n ");
497  have_where = true;
498  /* Note: at least one of these must be true ... */
499  if (showAggregate)
500  {
501  if (pset.sversion >= 110000)
502  appendPQExpBufferStr(&buf, "p.prokind = 'a'\n");
503  else
504  appendPQExpBufferStr(&buf, "p.proisagg\n");
505  needs_or = true;
506  }
507  if (showTrigger)
508  {
509  if (needs_or)
510  appendPQExpBufferStr(&buf, " OR ");
512  "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n");
513  needs_or = true;
514  }
515  if (showProcedure)
516  {
517  if (needs_or)
518  appendPQExpBufferStr(&buf, " OR ");
519  appendPQExpBufferStr(&buf, "p.prokind = 'p'\n");
520  needs_or = true;
521  }
522  if (showWindow)
523  {
524  if (needs_or)
525  appendPQExpBufferStr(&buf, " OR ");
526  if (pset.sversion >= 110000)
527  appendPQExpBufferStr(&buf, "p.prokind = 'w'\n");
528  else
529  appendPQExpBufferStr(&buf, "p.proiswindow\n");
530  }
531  appendPQExpBufferStr(&buf, " )\n");
532  }
533 
534  if (!validateSQLNamePattern(&buf, func_pattern, have_where, false,
535  "n.nspname", "p.proname", NULL,
536  "pg_catalog.pg_function_is_visible(p.oid)",
537  NULL, 3))
538  goto error_return;
539 
540  for (int i = 0; i < num_arg_patterns; i++)
541  {
542  if (strcmp(arg_patterns[i], "-") != 0)
543  {
544  /*
545  * Match type-name patterns against either internal or external
546  * name, like \dT. Unlike \dT, there seems no reason to
547  * discriminate against arrays or composite types.
548  */
549  char nspname[64];
550  char typname[64];
551  char ft[64];
552  char tiv[64];
553 
554  snprintf(nspname, sizeof(nspname), "nt%d.nspname", i);
555  snprintf(typname, sizeof(typname), "t%d.typname", i);
556  snprintf(ft, sizeof(ft),
557  "pg_catalog.format_type(t%d.oid, NULL)", i);
558  snprintf(tiv, sizeof(tiv),
559  "pg_catalog.pg_type_is_visible(t%d.oid)", i);
561  map_typename_pattern(arg_patterns[i]),
562  true, false,
563  nspname, typname, ft, tiv,
564  NULL, 3))
565  goto error_return;
566  }
567  else
568  {
569  /* "-" pattern specifies no such parameter */
570  appendPQExpBuffer(&buf, " AND t%d.typname IS NULL\n", i);
571  }
572  }
573 
574  if (!showSystem && !func_pattern)
575  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
576  " AND n.nspname <> 'information_schema'\n");
577 
578  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
579 
580  res = PSQLexec(buf.data);
582  if (!res)
583  return false;
584 
585  myopt.title = _("List of functions");
586  myopt.translate_header = true;
587  if (pset.sversion >= 90600)
588  {
589  myopt.translate_columns = translate_columns;
590  myopt.n_translate_columns = lengthof(translate_columns);
591  }
592  else
593  {
594  myopt.translate_columns = translate_columns_pre_96;
595  myopt.n_translate_columns = lengthof(translate_columns_pre_96);
596  }
597 
598  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
599 
600  PQclear(res);
601  return true;
602 
603 error_return:
605  return false;
606 }
static const char * map_typename_pattern(const char *pattern)
Definition: describe.c:720
int i
Definition: isn.c:73
NameData typname
Definition: pg_type.h:41
#define snprintf
Definition: port.h:238

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, i, initPQExpBuffer(), lengthof, _psqlSettings::logfile, map_typename_pattern(), printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, snprintf, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, typname, validateSQLNamePattern(), and verbose.

Referenced by exec_command_dfo().

◆ describeOperators()

bool describeOperators ( const char *  oper_pattern,
char **  arg_patterns,
int  num_arg_patterns,
bool  verbose,
bool  showSystem 
)

Definition at line 770 of file describe.c.

773 {
775  PGresult *res;
776  printQueryOpt myopt = pset.popt;
777 
779 
780  /*
781  * Note: before Postgres 9.1, we did not assign comments to any built-in
782  * operators, preferring to let the comment on the underlying function
783  * suffice. The coalesce() on the obj_description() calls below supports
784  * this convention by providing a fallback lookup of a comment on the
785  * operator's function. Since 9.1 there is a policy that every built-in
786  * operator should have a comment; so the coalesce() is no longer
787  * necessary so far as built-in operators are concerned. We keep it
788  * anyway, for now, because third-party modules may still be following the
789  * old convention.
790  *
791  * The support for postfix operators in this query is dead code as of
792  * Postgres 14, but we need to keep it for as long as we support talking
793  * to pre-v14 servers.
794  */
795 
797  "SELECT n.nspname as \"%s\",\n"
798  " o.oprname AS \"%s\",\n"
799  " CASE WHEN o.oprkind='l' THEN NULL ELSE pg_catalog.format_type(o.oprleft, NULL) END AS \"%s\",\n"
800  " CASE WHEN o.oprkind='r' THEN NULL ELSE pg_catalog.format_type(o.oprright, NULL) END AS \"%s\",\n"
801  " pg_catalog.format_type(o.oprresult, NULL) AS \"%s\",\n",
802  gettext_noop("Schema"),
803  gettext_noop("Name"),
804  gettext_noop("Left arg type"),
805  gettext_noop("Right arg type"),
806  gettext_noop("Result type"));
807 
808  if (verbose)
810  " o.oprcode AS \"%s\",\n",
811  gettext_noop("Function"));
812 
814  " coalesce(pg_catalog.obj_description(o.oid, 'pg_operator'),\n"
815  " pg_catalog.obj_description(o.oprcode, 'pg_proc')) AS \"%s\"\n"
816  "FROM pg_catalog.pg_operator o\n"
817  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = o.oprnamespace\n",
818  gettext_noop("Description"));
819 
820  if (num_arg_patterns >= 2)
821  {
822  num_arg_patterns = 2; /* ignore any additional arguments */
824  " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprleft\n"
825  " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n"
826  " LEFT JOIN pg_catalog.pg_type t1 ON t1.oid = o.oprright\n"
827  " LEFT JOIN pg_catalog.pg_namespace nt1 ON nt1.oid = t1.typnamespace\n");
828  }
829  else if (num_arg_patterns == 1)
830  {
832  " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprright\n"
833  " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n");
834  }
835 
836  if (!showSystem && !oper_pattern)
837  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
838  " AND n.nspname <> 'information_schema'\n");
839 
840  if (!validateSQLNamePattern(&buf, oper_pattern,
841  !showSystem && !oper_pattern, true,
842  "n.nspname", "o.oprname", NULL,
843  "pg_catalog.pg_operator_is_visible(o.oid)",
844  NULL, 3))
845  goto error_return;
846 
847  if (num_arg_patterns == 1)
848  appendPQExpBufferStr(&buf, " AND o.oprleft = 0\n");
849 
850  for (int i = 0; i < num_arg_patterns; i++)
851  {
852  if (strcmp(arg_patterns[i], "-") != 0)
853  {
854  /*
855  * Match type-name patterns against either internal or external
856  * name, like \dT. Unlike \dT, there seems no reason to
857  * discriminate against arrays or composite types.
858  */
859  char nspname[64];
860  char typname[64];
861  char ft[64];
862  char tiv[64];
863 
864  snprintf(nspname, sizeof(nspname), "nt%d.nspname", i);
865  snprintf(typname, sizeof(typname), "t%d.typname", i);
866  snprintf(ft, sizeof(ft),
867  "pg_catalog.format_type(t%d.oid, NULL)", i);
868  snprintf(tiv, sizeof(tiv),
869  "pg_catalog.pg_type_is_visible(t%d.oid)", i);
871  map_typename_pattern(arg_patterns[i]),
872  true, false,
873  nspname, typname, ft, tiv,
874  NULL, 3))
875  goto error_return;
876  }
877  else
878  {
879  /* "-" pattern specifies no such parameter */
880  appendPQExpBuffer(&buf, " AND t%d.typname IS NULL\n", i);
881  }
882  }
883 
884  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3, 4;");
885 
886  res = PSQLexec(buf.data);
888  if (!res)
889  return false;
890 
891  myopt.title = _("List of operators");
892  myopt.translate_header = true;
893 
894  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
895 
896  PQclear(res);
897  return true;
898 
899 error_return:
901  return false;
902 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, i, initPQExpBuffer(), _psqlSettings::logfile, map_typename_pattern(), _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, snprintf, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, typname, validateSQLNamePattern(), and verbose.

Referenced by exec_command_dfo().

◆ describePublications()

bool describePublications ( const char *  pattern)

Definition at line 6391 of file describe.c.

6392 {
6394  int i;
6395  PGresult *res;
6396  bool has_pubtruncate;
6397  bool has_pubviaroot;
6398 
6399  PQExpBufferData title;
6400  printTableContent cont;
6401 
6402  if (pset.sversion < 100000)
6403  {
6404  char sverbuf[32];
6405 
6406  pg_log_error("The server (version %s) does not support publications.",
6408  sverbuf, sizeof(sverbuf)));
6409  return true;
6410  }
6411 
6412  has_pubtruncate = (pset.sversion >= 110000);
6413  has_pubviaroot = (pset.sversion >= 130000);
6414 
6415  initPQExpBuffer(&buf);
6416 
6418  "SELECT oid, pubname,\n"
6419  " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n"
6420  " puballtables, pubinsert, pubupdate, pubdelete");
6421  if (has_pubtruncate)
6423  ", pubtruncate");
6424  if (has_pubviaroot)
6426  ", pubviaroot");
6428  "\nFROM pg_catalog.pg_publication\n");
6429 
6430  if (!validateSQLNamePattern(&buf, pattern, false, false,
6431  NULL, "pubname", NULL,
6432  NULL,
6433  NULL, 1))
6434  {
6435  termPQExpBuffer(&buf);
6436  return false;
6437  }
6438 
6439  appendPQExpBufferStr(&buf, "ORDER BY 2;");
6440 
6441  res = PSQLexec(buf.data);
6442  if (!res)
6443  {
6444  termPQExpBuffer(&buf);
6445  return false;
6446  }
6447 
6448  if (PQntuples(res) == 0)
6449  {
6450  if (!pset.quiet)
6451  {
6452  if (pattern)
6453  pg_log_error("Did not find any publication named \"%s\".",
6454  pattern);
6455  else
6456  pg_log_error("Did not find any publications.");
6457  }
6458 
6459  termPQExpBuffer(&buf);
6460  PQclear(res);
6461  return false;
6462  }
6463 
6464  for (i = 0; i < PQntuples(res); i++)
6465  {
6466  const char align = 'l';
6467  int ncols = 5;
6468  int nrows = 1;
6469  char *pubid = PQgetvalue(res, i, 0);
6470  char *pubname = PQgetvalue(res, i, 1);
6471  bool puballtables = strcmp(PQgetvalue(res, i, 3), "t") == 0;
6472  printTableOpt myopt = pset.popt.topt;
6473 
6474  if (has_pubtruncate)
6475  ncols++;
6476  if (has_pubviaroot)
6477  ncols++;
6478 
6479  initPQExpBuffer(&title);
6480  printfPQExpBuffer(&title, _("Publication %s"), pubname);
6481  printTableInit(&cont, &myopt, title.data, ncols, nrows);
6482 
6483  printTableAddHeader(&cont, gettext_noop("Owner"), true, align);
6484  printTableAddHeader(&cont, gettext_noop("All tables"), true, align);
6485  printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
6486  printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
6487  printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
6488  if (has_pubtruncate)
6489  printTableAddHeader(&cont, gettext_noop("Truncates"), true, align);
6490  if (has_pubviaroot)
6491  printTableAddHeader(&cont, gettext_noop("Via root"), true, align);
6492 
6493  printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
6494  printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
6495  printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
6496  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
6497  printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
6498  if (has_pubtruncate)
6499  printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
6500  if (has_pubviaroot)
6501  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
6502 
6503  if (!puballtables)
6504  {
6505  /* Get the tables for the specified publication */
6507  "SELECT n.nspname, c.relname");
6508  if (pset.sversion >= 150000)
6509  {
6511  ", pg_get_expr(pr.prqual, c.oid)");
6513  ", (CASE WHEN pr.prattrs IS NOT NULL THEN\n"
6514  " pg_catalog.array_to_string("
6515  " ARRAY(SELECT attname\n"
6516  " FROM\n"
6517  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
6518  " pg_catalog.pg_attribute\n"
6519  " WHERE attrelid = c.oid AND attnum = prattrs[s]), ', ')\n"
6520  " ELSE NULL END)");
6521  }
6522  else
6524  ", NULL, NULL");
6526  "\nFROM pg_catalog.pg_class c,\n"
6527  " pg_catalog.pg_namespace n,\n"
6528  " pg_catalog.pg_publication_rel pr\n"
6529  "WHERE c.relnamespace = n.oid\n"
6530  " AND c.oid = pr.prrelid\n"
6531  " AND pr.prpubid = '%s'\n"
6532  "ORDER BY 1,2", pubid);
6533  if (!addFooterToPublicationDesc(&buf, _("Tables:"), false, &cont))
6534  goto error_return;
6535 
6536  if (pset.sversion >= 150000)
6537  {
6538  /* Get the schemas for the specified publication */
6540  "SELECT n.nspname\n"
6541  "FROM pg_catalog.pg_namespace n\n"
6542  " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n"
6543  "WHERE pn.pnpubid = '%s'\n"
6544  "ORDER BY 1", pubid);
6545  if (!addFooterToPublicationDesc(&buf, _("Tables from schemas:"),
6546  true, &cont))
6547  goto error_return;
6548  }
6549  }
6550 
6551  printTable(&cont, pset.queryFout, false, pset.logfile);
6552  printTableCleanup(&cont);
6553 
6554  termPQExpBuffer(&title);
6555  }
6556 
6557  termPQExpBuffer(&buf);
6558  PQclear(res);
6559 
6560  return true;
6561 
6562 error_return:
6563  printTableCleanup(&cont);
6564  PQclear(res);
6565  termPQExpBuffer(&buf);
6566  termPQExpBuffer(&title);
6567  return false;
6568 }
static bool addFooterToPublicationDesc(PQExpBuffer buf, const char *footermsg, bool as_schema, printTableContent *const cont)
Definition: describe.c:6345
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3481
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3876
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:3172
void printTableCleanup(printTableContent *const content)
Definition: print.c:3353
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3260
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3443
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:3220
printTableOpt topt
Definition: print.h:185

References _, addFooterToPublicationDesc(), appendPQExpBuffer(), appendPQExpBufferStr(), buf, PQExpBufferData::data, formatPGVersionNumber(), gettext_noop, i, initPQExpBuffer(), _psqlSettings::logfile, pg_log_error, _psqlSettings::popt, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), printTable(), printTableAddCell(), printTableAddHeader(), printTableCleanup(), printTableInit(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::topt, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ describeRoleGrants()

bool describeRoleGrants ( const char *  pattern,
bool  showSystem 
)

Definition at line 3882 of file describe.c.

3883 {
3885  PGresult *res;
3886  printQueryOpt myopt = pset.popt;
3887 
3888  initPQExpBuffer(&buf);
3890  "SELECT m.rolname AS \"%s\", r.rolname AS \"%s\",\n"
3891  " pg_catalog.concat_ws(', ',\n",
3892  gettext_noop("Role name"),
3893  gettext_noop("Member of"));
3894 
3895  if (pset.sversion >= 160000)
3897  " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3898  " CASE WHEN pam.inherit_option THEN 'INHERIT' END,\n"
3899  " CASE WHEN pam.set_option THEN 'SET' END\n");
3900  else
3902  " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3903  " CASE WHEN m.rolinherit THEN 'INHERIT' END,\n"
3904  " 'SET'\n");
3905 
3907  " ) AS \"%s\",\n"
3908  " g.rolname AS \"%s\"\n",
3909  gettext_noop("Options"),
3910  gettext_noop("Grantor"));
3911 
3913  "FROM pg_catalog.pg_roles m\n"
3914  " JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)\n"
3915  " LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)\n"
3916  " LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)\n");
3917 
3918  if (!showSystem && !pattern)
3919  appendPQExpBufferStr(&buf, "WHERE m.rolname !~ '^pg_'\n");
3920 
3921  if (!validateSQLNamePattern(&buf, pattern, false, false,
3922  NULL, "m.rolname", NULL, NULL,
3923  NULL, 1))
3924  {
3925  termPQExpBuffer(&buf);
3926  return false;
3927  }
3928 
3929  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;\n");
3930 
3931  res = PSQLexec(buf.data);
3932  termPQExpBuffer(&buf);
3933  if (!res)
3934  return false;
3935 
3936  myopt.title = _("List of role grants");
3937  myopt.translate_header = true;
3938 
3939  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3940 
3941  PQclear(res);
3942  return true;
3943 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ describeRoles()

bool describeRoles ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3666 of file describe.c.

3667 {
3669  PGresult *res;
3670  printTableContent cont;
3671  printTableOpt myopt = pset.popt.topt;
3672  int ncols = 2;
3673  int nrows = 0;
3674  int i;
3675  int conns;
3676  const char align = 'l';
3677  char **attr;
3678 
3679  myopt.default_footer = false;
3680 
3681  initPQExpBuffer(&buf);
3682 
3684  "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
3685  " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
3686  " r.rolconnlimit, r.rolvaliduntil");
3687 
3688  if (verbose)
3689  {
3690  appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
3691  ncols++;
3692  }
3693  appendPQExpBufferStr(&buf, "\n, r.rolreplication");
3694 
3695  if (pset.sversion >= 90500)
3696  {
3697  appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
3698  }
3699 
3700  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
3701 
3702  if (!showSystem && !pattern)
3703  appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
3704 
3705  if (!validateSQLNamePattern(&buf, pattern, false, false,
3706  NULL, "r.rolname", NULL, NULL,
3707  NULL, 1))
3708  {
3709  termPQExpBuffer(&buf);
3710  return false;
3711  }
3712 
3713  appendPQExpBufferStr(&buf, "ORDER BY 1;");
3714 
3715  res = PSQLexec(buf.data);
3716  if (!res)
3717  return false;
3718 
3719  nrows = PQntuples(res);
3720  attr = pg_malloc0((nrows + 1) * sizeof(*attr));
3721 
3722  printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
3723 
3724  printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
3725  printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
3726 
3727  if (verbose)
3728  printTableAddHeader(&cont, gettext_noop("Description"), true, align);
3729 
3730  for (i = 0; i < nrows; i++)
3731  {
3732  printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
3733 
3735  if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
3736  add_role_attribute(&buf, _("Superuser"));
3737 
3738  if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
3739  add_role_attribute(&buf, _("No inheritance"));
3740 
3741  if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
3742  add_role_attribute(&buf, _("Create role"));
3743 
3744  if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
3745  add_role_attribute(&buf, _("Create DB"));
3746 
3747  if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
3748  add_role_attribute(&buf, _("Cannot login"));
3749 
3750  if (strcmp(PQgetvalue(res, i, (verbose ? 9 : 8)), "t") == 0)
3751  add_role_attribute(&buf, _("Replication"));
3752 
3753  if (pset.sversion >= 90500)
3754  if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3755  add_role_attribute(&buf, _("Bypass RLS"));
3756 
3757  conns = atoi(PQgetvalue(res, i, 6));
3758  if (conns >= 0)
3759  {
3760  if (buf.len > 0)
3761  appendPQExpBufferChar(&buf, '\n');
3762 
3763  if (conns == 0)
3764  appendPQExpBufferStr(&buf, _("No connections"));
3765  else
3766  appendPQExpBuffer(&buf, ngettext("%d connection",
3767  "%d connections",
3768  conns),
3769  conns);
3770  }
3771 
3772  if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3773  {
3774  if (buf.len > 0)
3775  appendPQExpBufferChar(&buf, '\n');
3776  appendPQExpBufferStr(&buf, _("Password valid until "));
3778  }
3779 
3780  attr[i] = pg_strdup(buf.data);
3781 
3782  printTableAddCell(&cont, attr[i], false, false);
3783 
3784  if (verbose)
3785  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3786  }
3787  termPQExpBuffer(&buf);
3788 
3789  printTable(&cont, pset.queryFout, false, pset.logfile);
3790  printTableCleanup(&cont);
3791 
3792  for (i = 0; i < nrows; i++)
3793  free(attr[i]);
3794  free(attr);
3795 
3796  PQclear(res);
3797  return true;
3798 }
#define ngettext(s, p, n)
Definition: c.h:1181
static void add_role_attribute(PQExpBuffer buf, const char *const str)
Definition: describe.c:3801
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define free(a)
Definition: header.h:65
static IsoConnInfo * conns
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:146
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
bool default_footer
Definition: print.h:129

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

Referenced by exec_command_d().

◆ describeSubscriptions()

bool describeSubscriptions ( const char *  pattern,
bool  verbose 
)

Definition at line 6577 of file describe.c.

6578 {
6580  PGresult *res;
6581  printQueryOpt myopt = pset.popt;
6582  static const bool translate_columns[] = {false, false, false, false,
6583  false, false, false, false, false, false, false, false, false, false,
6584  false};
6585 
6586  if (pset.sversion < 100000)
6587  {
6588  char sverbuf[32];
6589 
6590  pg_log_error("The server (version %s) does not support subscriptions.",
6592  sverbuf, sizeof(sverbuf)));
6593  return true;
6594  }
6595 
6596  initPQExpBuffer(&buf);
6597 
6599  "SELECT subname AS \"%s\"\n"
6600  ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
6601  ", subenabled AS \"%s\"\n"
6602  ", subpublications AS \"%s\"\n",
6603  gettext_noop("Name"),
6604  gettext_noop("Owner"),
6605  gettext_noop("Enabled"),
6606  gettext_noop("Publication"));
6607 
6608  if (verbose)
6609  {
6610  /* Binary mode and streaming are only supported in v14 and higher */
6611  if (pset.sversion >= 140000)
6612  {
6614  ", subbinary AS \"%s\"\n",
6615  gettext_noop("Binary"));
6616 
6617  if (pset.sversion >= 160000)
6619  ", (CASE substream\n"
6620  " WHEN 'f' THEN 'off'\n"
6621  " WHEN 't' THEN 'on'\n"
6622  " WHEN 'p' THEN 'parallel'\n"
6623  " END) AS \"%s\"\n",
6624  gettext_noop("Streaming"));
6625  else
6627  ", substream AS \"%s\"\n",
6628  gettext_noop("Streaming"));
6629  }
6630 
6631  /* Two_phase and disable_on_error are only supported in v15 and higher */
6632  if (pset.sversion >= 150000)
6634  ", subtwophasestate AS \"%s\"\n"
6635  ", subdisableonerr AS \"%s\"\n",
6636  gettext_noop("Two-phase commit"),
6637  gettext_noop("Disable on error"));
6638 
6639  if (pset.sversion >= 160000)
6641  ", suborigin AS \"%s\"\n"
6642  ", subpasswordrequired AS \"%s\"\n"
6643  ", subrunasowner AS \"%s\"\n",
6644  gettext_noop("Origin"),
6645  gettext_noop("Password required"),
6646  gettext_noop("Run as owner?"));
6647 
6648  if (pset.sversion >= 170000)
6650  ", subfailover AS \"%s\"\n",
6651  gettext_noop("Failover"));
6652 
6654  ", subsynccommit AS \"%s\"\n"
6655  ", subconninfo AS \"%s\"\n",
6656  gettext_noop("Synchronous commit"),
6657  gettext_noop("Conninfo"));
6658 
6659  /* Skip LSN is only supported in v15 and higher */
6660  if (pset.sversion >= 150000)
6662  ", subskiplsn AS \"%s\"\n",
6663  gettext_noop("Skip LSN"));
6664  }
6665 
6666  /* Only display subscriptions in current database. */
6668  "FROM pg_catalog.pg_subscription\n"
6669  "WHERE subdbid = (SELECT oid\n"
6670  " FROM pg_catalog.pg_database\n"
6671  " WHERE datname = pg_catalog.current_database())");
6672 
6673  if (!validateSQLNamePattern(&buf, pattern, true, false,
6674  NULL, "subname", NULL,
6675  NULL,
6676  NULL, 1))
6677  {
6678  termPQExpBuffer(&buf);
6679  return false;
6680  }
6681 
6682  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6683 
6684  res = PSQLexec(buf.data);
6685  termPQExpBuffer(&buf);
6686  if (!res)
6687  return false;
6688 
6689  myopt.title = _("List of subscriptions");
6690  myopt.translate_header = true;
6691  myopt.translate_columns = translate_columns;
6692  myopt.n_translate_columns = lengthof(translate_columns);
6693 
6694  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6695 
6696  PQclear(res);
6697  return true;
6698 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ describeTableDetails()

bool describeTableDetails ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 1445 of file describe.c.

1446 {
1448  PGresult *res;
1449  int i;
1450 
1451  initPQExpBuffer(&buf);
1452 
1454  "SELECT c.oid,\n"
1455  " n.nspname,\n"
1456  " c.relname\n"
1457  "FROM pg_catalog.pg_class c\n"
1458  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n");
1459 
1460  if (!showSystem && !pattern)
1461  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1462  " AND n.nspname <> 'information_schema'\n");
1463 
1464  if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
1465  "n.nspname", "c.relname", NULL,
1466  "pg_catalog.pg_table_is_visible(c.oid)",
1467  NULL, 3))
1468  {
1469  termPQExpBuffer(&buf);
1470  return false;
1471  }
1472 
1473  appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
1474 
1475  res = PSQLexec(buf.data);
1476  termPQExpBuffer(&buf);
1477  if (!res)
1478  return false;
1479 
1480  if (PQntuples(res) == 0)
1481  {
1482  if (!pset.quiet)
1483  {
1484  if (pattern)
1485  pg_log_error("Did not find any relation named \"%s\".",
1486  pattern);
1487  else
1488  pg_log_error("Did not find any relations.");
1489  }
1490  PQclear(res);
1491  return false;
1492  }
1493 
1494  for (i = 0; i < PQntuples(res); i++)
1495  {
1496  const char *oid;
1497  const char *nspname;
1498  const char *relname;
1499 
1500  oid = PQgetvalue(res, i, 0);
1501  nspname = PQgetvalue(res, i, 1);
1502  relname = PQgetvalue(res, i, 2);
1503 
1504  if (!describeOneTableDetails(nspname, relname, oid, verbose))
1505  {
1506  PQclear(res);
1507  return false;
1508  }
1509  if (cancel_pressed)
1510  {
1511  PQclear(res);
1512  return false;
1513  }
1514  }
1515 
1516  PQclear(res);
1517  return true;
1518 }
static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, bool verbose)
Definition: describe.c:1528
volatile sig_atomic_t cancel_pressed
Definition: print.c:43
NameData relname
Definition: pg_class.h:38

References appendPQExpBufferStr(), buf, cancel_pressed, describeOneTableDetails(), i, initPQExpBuffer(), pg_log_error, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), pset, PSQLexec(), _psqlSettings::quiet, relname, res, termPQExpBuffer(), validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ describeTablespaces()

bool describeTablespaces ( const char *  pattern,
bool  verbose 
)

Definition at line 215 of file describe.c.

216 {
218  PGresult *res;
219  printQueryOpt myopt = pset.popt;
220 
222 
224  "SELECT spcname AS \"%s\",\n"
225  " pg_catalog.pg_get_userbyid(spcowner) AS \"%s\",\n"
226  " pg_catalog.pg_tablespace_location(oid) AS \"%s\"",
227  gettext_noop("Name"),
228  gettext_noop("Owner"),
229  gettext_noop("Location"));
230 
231  if (verbose)
232  {
233  appendPQExpBufferStr(&buf, ",\n ");
234  printACLColumn(&buf, "spcacl");
236  ",\n spcoptions AS \"%s\""
237  ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \"%s\""
238  ",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
239  gettext_noop("Options"),
240  gettext_noop("Size"),
241  gettext_noop("Description"));
242  }
243 
245  "\nFROM pg_catalog.pg_tablespace\n");
246 
247  if (!validateSQLNamePattern(&buf, pattern, false, false,
248  NULL, "spcname", NULL,
249  NULL,
250  NULL, 1))
251  {
253  return false;
254  }
255 
256  appendPQExpBufferStr(&buf, "ORDER BY 1;");
257 
258  res = PSQLexec(buf.data);
260  if (!res)
261  return false;
262 
263  myopt.title = _("List of tablespaces");
264  myopt.translate_header = true;
265 
266  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
267 
268  PQclear(res);
269  return true;
270 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ describeTypes()

bool describeTypes ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 615 of file describe.c.

616 {
618  PGresult *res;
619  printQueryOpt myopt = pset.popt;
620 
622 
624  "SELECT n.nspname as \"%s\",\n"
625  " pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
626  gettext_noop("Schema"),
627  gettext_noop("Name"));
628  if (verbose)
629  {
631  " t.typname AS \"%s\",\n"
632  " CASE WHEN t.typrelid != 0\n"
633  " THEN CAST('tuple' AS pg_catalog.text)\n"
634  " WHEN t.typlen < 0\n"
635  " THEN CAST('var' AS pg_catalog.text)\n"
636  " ELSE CAST(t.typlen AS pg_catalog.text)\n"
637  " END AS \"%s\",\n"
638  " pg_catalog.array_to_string(\n"
639  " ARRAY(\n"
640  " SELECT e.enumlabel\n"
641  " FROM pg_catalog.pg_enum e\n"
642  " WHERE e.enumtypid = t.oid\n"
643  " ORDER BY e.enumsortorder\n"
644  " ),\n"
645  " E'\\n'\n"
646  " ) AS \"%s\",\n"
647  " pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
648  gettext_noop("Internal name"),
649  gettext_noop("Size"),
650  gettext_noop("Elements"),
651  gettext_noop("Owner"));
652  printACLColumn(&buf, "t.typacl");
653  appendPQExpBufferStr(&buf, ",\n ");
654  }
655 
657  " pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n",
658  gettext_noop("Description"));
659 
660  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_type t\n"
661  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
662 
663  /*
664  * do not include complex types (typrelid!=0) unless they are standalone
665  * composite types
666  */
667  appendPQExpBufferStr(&buf, "WHERE (t.typrelid = 0 ");
668  appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
669  " FROM pg_catalog.pg_class c "
670  "WHERE c.oid = t.typrelid))\n");
671 
672  /*
673  * do not include array types unless the pattern contains []
674  */
675  if (pattern == NULL || strstr(pattern, "[]") == NULL)
676  appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n");
677 
678  if (!showSystem && !pattern)
679  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
680  " AND n.nspname <> 'information_schema'\n");
681 
682  /* Match name pattern against either internal or external name */
684  true, false,
685  "n.nspname", "t.typname",
686  "pg_catalog.format_type(t.oid, NULL)",
687  "pg_catalog.pg_type_is_visible(t.oid)",
688  NULL, 3))
689  {
691  return false;
692  }
693 
694  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
695 
696  res = PSQLexec(buf.data);
698  if (!res)
699  return false;
700 
701  myopt.title = _("List of data types");
702  myopt.translate_header = true;
703 
704  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
705 
706  PQclear(res);
707  return true;
708 }
#define CppAsString2(x)
Definition: c.h:327

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, map_typename_pattern(), _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listAllDbs()

bool listAllDbs ( const char *  pattern,
bool  verbose 
)

Definition at line 911 of file describe.c.

912 {
913  PGresult *res;
915  printQueryOpt myopt = pset.popt;
916 
918 
920  "SELECT\n"
921  " d.datname as \"%s\",\n"
922  " pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
923  " pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n",
924  gettext_noop("Name"),
925  gettext_noop("Owner"),
926  gettext_noop("Encoding"));
927  if (pset.sversion >= 150000)
929  " CASE d.datlocprovider WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
930  gettext_noop("Locale Provider"));
931  else
933  " 'libc' AS \"%s\",\n",
934  gettext_noop("Locale Provider"));
936  " d.datcollate as \"%s\",\n"
937  " d.datctype as \"%s\",\n",
938  gettext_noop("Collate"),
939  gettext_noop("Ctype"));
940  if (pset.sversion >= 170000)
942  " d.datlocale as \"%s\",\n",
943  gettext_noop("Locale"));
944  else if (pset.sversion >= 150000)
946  " d.daticulocale as \"%s\",\n",
947  gettext_noop("Locale"));
948  else
950  " NULL as \"%s\",\n",
951  gettext_noop("Locale"));
952  if (pset.sversion >= 160000)
954  " d.daticurules as \"%s\",\n",
955  gettext_noop("ICU Rules"));
956  else
958  " NULL as \"%s\",\n",
959  gettext_noop("ICU Rules"));
960  appendPQExpBufferStr(&buf, " ");
961  printACLColumn(&buf, "d.datacl");
962  if (verbose)
964  ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
965  " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
966  " ELSE 'No Access'\n"
967  " END as \"%s\""
968  ",\n t.spcname as \"%s\""
969  ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
970  gettext_noop("Size"),
971  gettext_noop("Tablespace"),
972  gettext_noop("Description"));
974  "\nFROM pg_catalog.pg_database d\n");
975  if (verbose)
977  " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
978 
979  if (pattern)
980  {
981  if (!validateSQLNamePattern(&buf, pattern, false, false,
982  NULL, "d.datname", NULL, NULL,
983  NULL, 1))
984  {
986  return false;
987  }
988  }
989 
990  appendPQExpBufferStr(&buf, "ORDER BY 1;");
991  res = PSQLexec(buf.data);
993  if (!res)
994  return false;
995 
996  myopt.title = _("List of databases");
997  myopt.translate_header = true;
998 
999  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1000 
1001  PQclear(res);
1002  return true;
1003 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_list(), and main().

◆ listCasts()

bool listCasts ( const char *  pattern,
bool  verbose 
)

Definition at line 4842 of file describe.c.

4843 {
4845  PGresult *res;
4846  printQueryOpt myopt = pset.popt;
4847  static const bool translate_columns[] = {false, false, false, true, false};
4848 
4849  initPQExpBuffer(&buf);
4850 
4852  "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n"
4853  " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n",
4854  gettext_noop("Source type"),
4855  gettext_noop("Target type"));
4856 
4857  /*
4858  * We don't attempt to localize '(binary coercible)' or '(with inout)',
4859  * because there's too much risk of gettext translating a function name
4860  * that happens to match some string in the PO database.
4861  */
4863  " CASE WHEN c.castmethod = '%c' THEN '(binary coercible)'\n"
4864  " WHEN c.castmethod = '%c' THEN '(with inout)'\n"
4865  " ELSE p.proname\n"
4866  " END AS \"%s\",\n",
4867  COERCION_METHOD_BINARY,
4868  COERCION_METHOD_INOUT,
4869  gettext_noop("Function"));
4870 
4872  " CASE WHEN c.castcontext = '%c' THEN '%s'\n"
4873  " WHEN c.castcontext = '%c' THEN '%s'\n"
4874  " ELSE '%s'\n"
4875  " END AS \"%s\"",
4876  COERCION_CODE_EXPLICIT,
4877  gettext_noop("no"),
4878  COERCION_CODE_ASSIGNMENT,
4879  gettext_noop("in assignment"),
4880  gettext_noop("yes"),
4881  gettext_noop("Implicit?"));
4882 
4883  if (verbose)
4885  ",\n d.description AS \"%s\"",
4886  gettext_noop("Description"));
4887 
4888  /*
4889  * We need a left join to pg_proc for binary casts; the others are just
4890  * paranoia.
4891  */
4893  "\nFROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
4894  " ON c.castfunc = p.oid\n"
4895  " LEFT JOIN pg_catalog.pg_type ts\n"
4896  " ON c.castsource = ts.oid\n"
4897  " LEFT JOIN pg_catalog.pg_namespace ns\n"
4898  " ON ns.oid = ts.typnamespace\n"
4899  " LEFT JOIN pg_catalog.pg_type tt\n"
4900  " ON c.casttarget = tt.oid\n"
4901  " LEFT JOIN pg_catalog.pg_namespace nt\n"
4902  " ON nt.oid = tt.typnamespace\n");
4903 
4904  if (verbose)
4906  " LEFT JOIN pg_catalog.pg_description d\n"
4907  " ON d.classoid = c.tableoid AND d.objoid = "
4908  "c.oid AND d.objsubid = 0\n");
4909 
4910  appendPQExpBufferStr(&buf, "WHERE ( (true");
4911 
4912  /*
4913  * Match name pattern against either internal or external name of either
4914  * castsource or casttarget
4915  */
4916  if (!validateSQLNamePattern(&buf, pattern, true, false,
4917  "ns.nspname", "ts.typname",
4918  "pg_catalog.format_type(ts.oid, NULL)",
4919  "pg_catalog.pg_type_is_visible(ts.oid)",
4920  NULL, 3))
4921  goto error_return;
4922 
4923  appendPQExpBufferStr(&buf, ") OR (true");
4924 
4925  if (!validateSQLNamePattern(&buf, pattern, true, false,
4926  "nt.nspname", "tt.typname",
4927  "pg_catalog.format_type(tt.oid, NULL)",
4928  "pg_catalog.pg_type_is_visible(tt.oid)",
4929  NULL, 3))
4930  goto error_return;
4931 
4932  appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
4933 
4934  res = PSQLexec(buf.data);
4935  termPQExpBuffer(&buf);
4936  if (!res)
4937  return false;
4938 
4939  myopt.title = _("List of casts");
4940  myopt.translate_header = true;
4941  myopt.translate_columns = translate_columns;
4942  myopt.n_translate_columns = lengthof(translate_columns);
4943 
4944  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4945 
4946  PQclear(res);
4947  return true;
4948 
4949 error_return:
4950  termPQExpBuffer(&buf);
4951  return false;
4952 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listCollations()

bool listCollations ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 4960 of file describe.c.

4961 {
4963  PGresult *res;
4964  printQueryOpt myopt = pset.popt;
4965  static const bool translate_columns[] = {false, false, false, false, false, false, false, true, false};
4966 
4967  initPQExpBuffer(&buf);
4968 
4970  "SELECT\n"
4971  " n.nspname AS \"%s\",\n"
4972  " c.collname AS \"%s\",\n",
4973  gettext_noop("Schema"),
4974  gettext_noop("Name"));
4975 
4976  if (pset.sversion >= 100000)
4978  " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'b' THEN 'builtin' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
4979  gettext_noop("Provider"));
4980  else
4982  " 'libc' AS \"%s\",\n",
4983  gettext_noop("Provider"));
4984 
4986  " c.collcollate AS \"%s\",\n"
4987  " c.collctype AS \"%s\",\n",
4988  gettext_noop("Collate"),
4989  gettext_noop("Ctype"));
4990 
4991  if (pset.sversion >= 170000)
4993  " c.colllocale AS \"%s\",\n",
4994  gettext_noop("Locale"));
4995  else if (pset.sversion >= 150000)
4997  " c.colliculocale AS \"%s\",\n",
4998  gettext_noop("Locale"));
4999  else
5001  " c.collcollate AS \"%s\",\n",
5002  gettext_noop("Locale"));
5003 
5004  if (pset.sversion >= 160000)
5006  " c.collicurules AS \"%s\",\n",
5007  gettext_noop("ICU Rules"));
5008  else
5010  " NULL AS \"%s\",\n",
5011  gettext_noop("ICU Rules"));
5012 
5013  if (pset.sversion >= 120000)
5015  " CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \"%s\"",
5016  gettext_noop("yes"), gettext_noop("no"),
5017  gettext_noop("Deterministic?"));
5018  else
5020  " '%s' AS \"%s\"",
5021  gettext_noop("yes"),
5022  gettext_noop("Deterministic?"));
5023 
5024  if (verbose)
5026  ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
5027  gettext_noop("Description"));
5028 
5030  "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
5031  "WHERE n.oid = c.collnamespace\n");
5032 
5033  if (!showSystem && !pattern)
5034  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
5035  " AND n.nspname <> 'information_schema'\n");
5036 
5037  /*
5038  * Hide collations that aren't usable in the current database's encoding.
5039  * If you think to change this, note that pg_collation_is_visible rejects
5040  * unusable collations, so you will need to hack name pattern processing
5041  * somehow to avoid inconsistent behavior.
5042  */
5043  appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
5044 
5045  if (!validateSQLNamePattern(&buf, pattern, true, false,
5046  "n.nspname", "c.collname", NULL,
5047  "pg_catalog.pg_collation_is_visible(c.oid)",
5048  NULL, 3))
5049  {
5050  termPQExpBuffer(&buf);
5051  return false;
5052  }
5053 
5054  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5055 
5056  res = PSQLexec(buf.data);
5057  termPQExpBuffer(&buf);
5058  if (!res)
5059  return false;
5060 
5061  myopt.title = _("List of collations");
5062  myopt.translate_header = true;
5063  myopt.translate_columns = translate_columns;
5064  myopt.n_translate_columns = lengthof(translate_columns);
5065 
5066  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5067 
5068  PQclear(res);
5069  return true;
5070 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listConversions()

bool listConversions ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 4518 of file describe.c.

4519 {
4521  PGresult *res;
4522  printQueryOpt myopt = pset.popt;
4523  static const bool translate_columns[] =
4524  {false, false, false, false, true, false};
4525 
4526  initPQExpBuffer(&buf);
4527 
4529  "SELECT n.nspname AS \"%s\",\n"
4530  " c.conname AS \"%s\",\n"
4531  " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
4532  " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
4533  " CASE WHEN c.condefault THEN '%s'\n"
4534  " ELSE '%s' END AS \"%s\"",
4535  gettext_noop("Schema"),
4536  gettext_noop("Name"),
4537  gettext_noop("Source"),
4538  gettext_noop("Destination"),
4539  gettext_noop("yes"), gettext_noop("no"),
4540  gettext_noop("Default?"));
4541 
4542  if (verbose)
4544  ",\n d.description AS \"%s\"",
4545  gettext_noop("Description"));
4546 
4548  "\nFROM pg_catalog.pg_conversion c\n"
4549  " JOIN pg_catalog.pg_namespace n "
4550  "ON n.oid = c.connamespace\n");
4551 
4552  if (verbose)
4554  "LEFT JOIN pg_catalog.pg_description d "
4555  "ON d.classoid = c.tableoid\n"
4556  " AND d.objoid = c.oid "
4557  "AND d.objsubid = 0\n");
4558 
4559  appendPQExpBufferStr(&buf, "WHERE true\n");
4560 
4561  if (!showSystem && !pattern)
4562  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4563  " AND n.nspname <> 'information_schema'\n");
4564 
4565  if (!validateSQLNamePattern(&buf, pattern, true, false,
4566  "n.nspname", "c.conname", NULL,
4567  "pg_catalog.pg_conversion_is_visible(c.oid)",
4568  NULL, 3))
4569  {
4570  termPQExpBuffer(&buf);
4571  return false;
4572  }
4573 
4574  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4575 
4576  res = PSQLexec(buf.data);
4577  termPQExpBuffer(&buf);
4578  if (!res)
4579  return false;
4580 
4581  myopt.title = _("List of conversions");
4582  myopt.translate_header = true;
4583  myopt.translate_columns = translate_columns;
4584  myopt.n_translate_columns = lengthof(translate_columns);
4585 
4586  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4587 
4588  PQclear(res);
4589  return true;
4590 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listDbRoleSettings()

bool listDbRoleSettings ( const char *  pattern,
const char *  pattern2 
)

Definition at line 3813 of file describe.c.

3814 {
3816  PGresult *res;
3817  printQueryOpt myopt = pset.popt;
3818  bool havewhere;
3819 
3820  initPQExpBuffer(&buf);
3821 
3822  printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
3823  "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
3824  "FROM pg_catalog.pg_db_role_setting s\n"
3825  "LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase\n"
3826  "LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole\n",
3827  gettext_noop("Role"),
3828  gettext_noop("Database"),
3829  gettext_noop("Settings"));
3830  if (!validateSQLNamePattern(&buf, pattern, false, false,
3831  NULL, "r.rolname", NULL, NULL, &havewhere, 1))
3832  goto error_return;
3833  if (!validateSQLNamePattern(&buf, pattern2, havewhere, false,
3834  NULL, "d.datname", NULL, NULL,
3835  NULL, 1))
3836  goto error_return;
3837  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3838 
3839  res = PSQLexec(buf.data);
3840  termPQExpBuffer(&buf);
3841  if (!res)
3842  return false;
3843 
3844  /*
3845  * Most functions in this file are content to print an empty table when
3846  * there are no matching objects. We intentionally deviate from that
3847  * here, but only in !quiet mode, because of the possibility that the user
3848  * is confused about what the two pattern arguments mean.
3849  */
3850  if (PQntuples(res) == 0 && !pset.quiet)
3851  {
3852  if (pattern && pattern2)
3853  pg_log_error("Did not find any settings for role \"%s\" and database \"%s\".",
3854  pattern, pattern2);
3855  else if (pattern)
3856  pg_log_error("Did not find any settings for role \"%s\".",
3857  pattern);
3858  else
3859  pg_log_error("Did not find any settings.");
3860  }
3861  else
3862  {
3863  myopt.title = _("List of settings");
3864  myopt.translate_header = true;
3865 
3866  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3867  }
3868 
3869  PQclear(res);
3870  return true;
3871 
3872 error_return:
3873  termPQExpBuffer(&buf);
3874  return false;
3875 }

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, pg_log_error, _psqlSettings::popt, PQclear(), PQntuples(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listDefaultACLs()

bool listDefaultACLs ( const char *  pattern)

Definition at line 1175 of file describe.c.

1176 {
1178  PGresult *res;
1179  printQueryOpt myopt = pset.popt;
1180  static const bool translate_columns[] = {false, false, true, false};
1181 
1182  initPQExpBuffer(&buf);
1183 
1185  "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
1186  " n.nspname AS \"%s\",\n"
1187  " 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"
1188  " ",
1189  gettext_noop("Owner"),
1190  gettext_noop("Schema"),
1191  DEFACLOBJ_RELATION,
1192  gettext_noop("table"),
1193  DEFACLOBJ_SEQUENCE,
1194  gettext_noop("sequence"),
1195  DEFACLOBJ_FUNCTION,
1196  gettext_noop("function"),
1197  DEFACLOBJ_TYPE,
1198  gettext_noop("type"),
1199  DEFACLOBJ_NAMESPACE,
1200  gettext_noop("schema"),
1201  gettext_noop("Type"));
1202 
1203  printACLColumn(&buf, "d.defaclacl");
1204 
1205  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
1206  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
1207 
1208  if (!validateSQLNamePattern(&buf, pattern, false, false,
1209  NULL,
1210  "n.nspname",
1211  "pg_catalog.pg_get_userbyid(d.defaclrole)",
1212  NULL,
1213  NULL, 3))
1214  goto error_return;
1215 
1216  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1217 
1218  res = PSQLexec(buf.data);
1219  if (!res)
1220  goto error_return;
1221 
1222  printfPQExpBuffer(&buf, _("Default access privileges"));
1223  myopt.title = buf.data;
1224  myopt.translate_header = true;
1225  myopt.translate_columns = translate_columns;
1226  myopt.n_translate_columns = lengthof(translate_columns);
1227 
1228  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1229 
1230  termPQExpBuffer(&buf);
1231  PQclear(res);
1232  return true;
1233 
1234 error_return:
1235  termPQExpBuffer(&buf);
1236  return false;
1237 }

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listDomains()

bool listDomains ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 4435 of file describe.c.

4436 {
4438  PGresult *res;
4439  printQueryOpt myopt = pset.popt;
4440 
4441  initPQExpBuffer(&buf);
4442 
4444  "SELECT n.nspname as \"%s\",\n"
4445  " t.typname as \"%s\",\n"
4446  " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n"
4447  " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
4448  " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n"
4449  " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
4450  " t.typdefault as \"%s\",\n"
4451  " pg_catalog.array_to_string(ARRAY(\n"
4452  " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid AND r.contype = 'c' ORDER BY r.conname\n"
4453  " ), ' ') as \"%s\"",
4454  gettext_noop("Schema"),
4455  gettext_noop("Name"),
4456  gettext_noop("Type"),
4457  gettext_noop("Collation"),
4458  gettext_noop("Nullable"),
4459  gettext_noop("Default"),
4460  gettext_noop("Check"));
4461 
4462  if (verbose)
4463  {
4464  appendPQExpBufferStr(&buf, ",\n ");
4465  printACLColumn(&buf, "t.typacl");
4467  ",\n d.description as \"%s\"",
4468  gettext_noop("Description"));
4469  }
4470 
4472  "\nFROM pg_catalog.pg_type t\n"
4473  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
4474 
4475  if (verbose)
4477  " LEFT JOIN pg_catalog.pg_description d "
4478  "ON d.classoid = t.tableoid AND d.objoid = t.oid "
4479  "AND d.objsubid = 0\n");
4480 
4481  appendPQExpBufferStr(&buf, "WHERE t.typtype = 'd'\n");
4482 
4483  if (!showSystem && !pattern)
4484  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4485  " AND n.nspname <> 'information_schema'\n");
4486 
4487  if (!validateSQLNamePattern(&buf, pattern, true, false,
4488  "n.nspname", "t.typname", NULL,
4489  "pg_catalog.pg_type_is_visible(t.oid)",
4490  NULL, 3))
4491  {
4492  termPQExpBuffer(&buf);
4493  return false;
4494  }
4495 
4496  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4497 
4498  res = PSQLexec(buf.data);
4499  termPQExpBuffer(&buf);
4500  if (!res)
4501  return false;
4502 
4503  myopt.title = _("List of domains");
4504  myopt.translate_header = true;
4505 
4506  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4507 
4508  PQclear(res);
4509  return true;
4510 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listEventTriggers()

bool listEventTriggers ( const char *  pattern,
bool  verbose 
)

Definition at line 4666 of file describe.c.

4667 {
4669  PGresult *res;
4670  printQueryOpt myopt = pset.popt;
4671  static const bool translate_columns[] =
4672  {false, false, false, true, false, false, false};
4673 
4674  if (pset.sversion < 90300)
4675  {
4676  char sverbuf[32];
4677 
4678  pg_log_error("The server (version %s) does not support event triggers.",
4680  sverbuf, sizeof(sverbuf)));
4681  return true;
4682  }
4683 
4684  initPQExpBuffer(&buf);
4685 
4687  "SELECT evtname as \"%s\", "
4688  "evtevent as \"%s\", "
4689  "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n"
4690  " case evtenabled when 'O' then '%s'"
4691  " when 'R' then '%s'"
4692  " when 'A' then '%s'"
4693  " when 'D' then '%s' end as \"%s\",\n"
4694  " e.evtfoid::pg_catalog.regproc as \"%s\", "
4695  "pg_catalog.array_to_string(array(select x"
4696  " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
4697  gettext_noop("Name"),
4698  gettext_noop("Event"),
4699  gettext_noop("Owner"),
4700  gettext_noop("enabled"),
4701  gettext_noop("replica"),
4702  gettext_noop("always"),
4703  gettext_noop("disabled"),
4704  gettext_noop("Enabled"),
4705  gettext_noop("Function"),
4706  gettext_noop("Tags"));
4707  if (verbose)
4709  ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
4710  gettext_noop("Description"));
4712  "\nFROM pg_catalog.pg_event_trigger e ");
4713 
4714  if (!validateSQLNamePattern(&buf, pattern, false, false,
4715  NULL, "evtname", NULL, NULL,
4716  NULL, 1))
4717  {
4718  termPQExpBuffer(&buf);
4719  return false;
4720  }
4721 
4722  appendPQExpBufferStr(&buf, "ORDER BY 1");
4723 
4724  res = PSQLexec(buf.data);
4725  termPQExpBuffer(&buf);
4726  if (!res)
4727  return false;
4728 
4729  myopt.title = _("List of event triggers");
4730  myopt.translate_header = true;
4731  myopt.translate_columns = translate_columns;
4732  myopt.n_translate_columns = lengthof(translate_columns);
4733 
4734  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4735 
4736  PQclear(res);
4737  return true;
4738 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listExtendedStats()

bool listExtendedStats ( const char *  pattern)

Definition at line 4746 of file describe.c.

4747 {
4749  PGresult *res;
4750  printQueryOpt myopt = pset.popt;
4751 
4752  if (pset.sversion < 100000)
4753  {
4754  char sverbuf[32];
4755 
4756  pg_log_error("The server (version %s) does not support extended statistics.",
4758  sverbuf, sizeof(sverbuf)));
4759  return true;
4760  }
4761 
4762  initPQExpBuffer(&buf);
4764  "SELECT \n"
4765  "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text AS \"%s\", \n"
4766  "es.stxname AS \"%s\", \n",
4767  gettext_noop("Schema"),
4768  gettext_noop("Name"));
4769 
4770  if (pset.sversion >= 140000)
4772  "pg_catalog.format('%%s FROM %%s', \n"
4773  " pg_catalog.pg_get_statisticsobjdef_columns(es.oid), \n"
4774  " es.stxrelid::pg_catalog.regclass) AS \"%s\"",
4775  gettext_noop("Definition"));
4776  else
4778  "pg_catalog.format('%%s FROM %%s', \n"
4779  " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(a.attname),', ') \n"
4780  " FROM pg_catalog.unnest(es.stxkeys) s(attnum) \n"
4781  " JOIN pg_catalog.pg_attribute a \n"
4782  " ON (es.stxrelid = a.attrelid \n"
4783  " AND a.attnum = s.attnum \n"
4784  " AND NOT a.attisdropped)), \n"
4785  "es.stxrelid::pg_catalog.regclass) AS \"%s\"",
4786  gettext_noop("Definition"));
4787 
4789  ",\nCASE WHEN 'd' = any(es.stxkind) THEN 'defined' \n"
4790  "END AS \"%s\", \n"
4791  "CASE WHEN 'f' = any(es.stxkind) THEN 'defined' \n"
4792  "END AS \"%s\"",
4793  gettext_noop("Ndistinct"),
4794  gettext_noop("Dependencies"));
4795 
4796  /*
4797  * Include the MCV statistics kind.
4798  */
4799  if (pset.sversion >= 120000)
4800  {
4802  ",\nCASE WHEN 'm' = any(es.stxkind) THEN 'defined' \n"
4803  "END AS \"%s\" ",
4804  gettext_noop("MCV"));
4805  }
4806 
4808  " \nFROM pg_catalog.pg_statistic_ext es \n");
4809 
4810  if (!validateSQLNamePattern(&buf, pattern,
4811  false, false,
4812  "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname",
4813  NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)",
4814  NULL, 3))
4815  {
4816  termPQExpBuffer(&buf);
4817  return false;
4818  }
4819 
4820  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4821 
4822  res = PSQLexec(buf.data);
4823  termPQExpBuffer(&buf);
4824  if (!res)
4825  return false;
4826 
4827  myopt.title = _("List of extended statistics");
4828  myopt.translate_header = true;
4829 
4830  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4831 
4832  PQclear(res);
4833  return true;
4834 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listExtensionContents()

bool listExtensionContents ( const char *  pattern)

Definition at line 6105 of file describe.c.

6106 {
6108  PGresult *res;
6109  int i;
6110 
6111  initPQExpBuffer(&buf);
6113  "SELECT e.extname, e.oid\n"
6114  "FROM pg_catalog.pg_extension e\n");
6115 
6116  if (!validateSQLNamePattern(&buf, pattern,
6117  false, false,
6118  NULL, "e.extname", NULL,
6119  NULL,
6120  NULL, 1))
6121  {
6122  termPQExpBuffer(&buf);
6123  return false;
6124  }
6125 
6126  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6127 
6128  res = PSQLexec(buf.data);
6129  termPQExpBuffer(&buf);
6130  if (!res)
6131  return false;
6132 
6133  if (PQntuples(res) == 0)
6134  {
6135  if (!pset.quiet)
6136  {
6137  if (pattern)
6138  pg_log_error("Did not find any extension named \"%s\".",
6139  pattern);
6140  else
6141  pg_log_error("Did not find any extensions.");
6142  }
6143  PQclear(res);
6144  return false;
6145  }
6146 
6147  for (i = 0; i < PQntuples(res); i++)
6148  {
6149  const char *extname;
6150  const char *oid;
6151 
6152  extname = PQgetvalue(res, i, 0);
6153  oid = PQgetvalue(res, i, 1);
6154 
6155  if (!listOneExtensionContents(extname, oid))
6156  {
6157  PQclear(res);
6158  return false;
6159  }
6160  if (cancel_pressed)
6161  {
6162  PQclear(res);
6163  return false;
6164  }
6165  }
6166 
6167  PQclear(res);
6168  return true;
6169 }
static bool listOneExtensionContents(const char *extname, const char *oid)
Definition: describe.c:6172

References appendPQExpBufferStr(), buf, cancel_pressed, i, initPQExpBuffer(), listOneExtensionContents(), pg_log_error, PQclear(), PQgetvalue(), PQntuples(), printfPQExpBuffer(), pset, PSQLexec(), _psqlSettings::quiet, res, termPQExpBuffer(), and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listExtensions()

bool listExtensions ( const char *  pattern)

Definition at line 6054 of file describe.c.

6055 {
6057  PGresult *res;
6058  printQueryOpt myopt = pset.popt;
6059 
6060  initPQExpBuffer(&buf);
6062  "SELECT e.extname AS \"%s\", "
6063  "e.extversion AS \"%s\", n.nspname AS \"%s\", c.description AS \"%s\"\n"
6064  "FROM pg_catalog.pg_extension e "
6065  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
6066  "LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid "
6067  "AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n",
6068  gettext_noop("Name"),
6069  gettext_noop("Version"),
6070  gettext_noop("Schema"),
6071  gettext_noop("Description"));
6072 
6073  if (!validateSQLNamePattern(&buf, pattern,
6074  false, false,
6075  NULL, "e.extname", NULL,
6076  NULL,
6077  NULL, 1))
6078  {
6079  termPQExpBuffer(&buf);
6080  return false;
6081  }
6082 
6083  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6084 
6085  res = PSQLexec(buf.data);
6086  termPQExpBuffer(&buf);
6087  if (!res)
6088  return false;
6089 
6090  myopt.title = _("List of installed extensions");
6091  myopt.translate_header = true;
6092 
6093  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6094 
6095  PQclear(res);
6096  return true;
6097 }

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listForeignDataWrappers()

bool listForeignDataWrappers ( const char *  pattern,
bool  verbose 
)

Definition at line 5780 of file describe.c.

5781 {
5783  PGresult *res;
5784  printQueryOpt myopt = pset.popt;
5785 
5786  initPQExpBuffer(&buf);
5788  "SELECT fdw.fdwname AS \"%s\",\n"
5789  " pg_catalog.pg_get_userbyid(fdw.fdwowner) AS \"%s\",\n"
5790  " fdw.fdwhandler::pg_catalog.regproc AS \"%s\",\n"
5791  " fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
5792  gettext_noop("Name"),
5793  gettext_noop("Owner"),
5794  gettext_noop("Handler"),
5795  gettext_noop("Validator"));
5796 
5797  if (verbose)
5798  {
5799  appendPQExpBufferStr(&buf, ",\n ");
5800  printACLColumn(&buf, "fdwacl");
5802  ",\n CASE WHEN fdwoptions IS NULL THEN '' ELSE "
5803  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5804  " pg_catalog.quote_ident(option_name) || ' ' || "
5805  " pg_catalog.quote_literal(option_value) FROM "
5806  " pg_catalog.pg_options_to_table(fdwoptions)), ', ') || ')' "
5807  " END AS \"%s\""
5808  ",\n d.description AS \"%s\" ",
5809  gettext_noop("FDW options"),
5810  gettext_noop("Description"));
5811  }
5812 
5813  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
5814 
5815  if (verbose)
5817  "LEFT JOIN pg_catalog.pg_description d\n"
5818  " ON d.classoid = fdw.tableoid "
5819  "AND d.objoid = fdw.oid AND d.objsubid = 0\n");
5820 
5821  if (!validateSQLNamePattern(&buf, pattern, false, false,
5822  NULL, "fdwname", NULL, NULL,
5823  NULL, 1))
5824  {
5825  termPQExpBuffer(&buf);
5826  return false;
5827  }
5828 
5829  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5830 
5831  res = PSQLexec(buf.data);
5832  termPQExpBuffer(&buf);
5833  if (!res)
5834  return false;
5835 
5836  myopt.title = _("List of foreign-data wrappers");
5837  myopt.translate_header = true;
5838 
5839  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5840 
5841  PQclear(res);
5842  return true;
5843 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listForeignServers()

bool listForeignServers ( const char *  pattern,
bool  verbose 
)

Definition at line 5851 of file describe.c.

5852 {
5854  PGresult *res;
5855  printQueryOpt myopt = pset.popt;
5856 
5857  initPQExpBuffer(&buf);
5859  "SELECT s.srvname AS \"%s\",\n"
5860  " pg_catalog.pg_get_userbyid(s.srvowner) AS \"%s\",\n"
5861  " f.fdwname AS \"%s\"",
5862  gettext_noop("Name"),
5863  gettext_noop("Owner"),
5864  gettext_noop("Foreign-data wrapper"));
5865 
5866  if (verbose)
5867  {
5868  appendPQExpBufferStr(&buf, ",\n ");
5869  printACLColumn(&buf, "s.srvacl");
5871  ",\n"
5872  " s.srvtype AS \"%s\",\n"
5873  " s.srvversion AS \"%s\",\n"
5874  " CASE WHEN srvoptions IS NULL THEN '' ELSE "
5875  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5876  " pg_catalog.quote_ident(option_name) || ' ' || "
5877  " pg_catalog.quote_literal(option_value) FROM "
5878  " pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')' "
5879  " END AS \"%s\",\n"
5880  " d.description AS \"%s\"",
5881  gettext_noop("Type"),
5882  gettext_noop("Version"),
5883  gettext_noop("FDW options"),
5884  gettext_noop("Description"));
5885  }
5886 
5888  "\nFROM pg_catalog.pg_foreign_server s\n"
5889  " JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
5890 
5891  if (verbose)
5893  "LEFT JOIN pg_catalog.pg_description d\n "
5894  "ON d.classoid = s.tableoid AND d.objoid = s.oid "
5895  "AND d.objsubid = 0\n");
5896 
5897  if (!validateSQLNamePattern(&buf, pattern, false, false,
5898  NULL, "s.srvname", NULL, NULL,
5899  NULL, 1))
5900  {
5901  termPQExpBuffer(&buf);
5902  return false;
5903  }
5904 
5905  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5906 
5907  res = PSQLexec(buf.data);
5908  termPQExpBuffer(&buf);
5909  if (!res)
5910  return false;
5911 
5912  myopt.title = _("List of foreign servers");
5913  myopt.translate_header = true;
5914 
5915  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5916 
5917  PQclear(res);
5918  return true;
5919 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listForeignTables()

bool listForeignTables ( const char *  pattern,
bool  verbose 
)

Definition at line 5982 of file describe.c.

5983 {
5985  PGresult *res;
5986  printQueryOpt myopt = pset.popt;
5987 
5988  initPQExpBuffer(&buf);
5990  "SELECT n.nspname AS \"%s\",\n"
5991  " c.relname AS \"%s\",\n"
5992  " s.srvname AS \"%s\"",
5993  gettext_noop("Schema"),
5994  gettext_noop("Table"),
5995  gettext_noop("Server"));
5996 
5997  if (verbose)
5999  ",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
6000  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
6001  " pg_catalog.quote_ident(option_name) || ' ' || "
6002  " pg_catalog.quote_literal(option_value) FROM "
6003  " pg_catalog.pg_options_to_table(ftoptions)), ', ') || ')' "
6004  " END AS \"%s\",\n"
6005  " d.description AS \"%s\"",
6006  gettext_noop("FDW options"),
6007  gettext_noop("Description"));
6008 
6010  "\nFROM pg_catalog.pg_foreign_table ft\n"
6011  " INNER JOIN pg_catalog.pg_class c"
6012  " ON c.oid = ft.ftrelid\n"
6013  " INNER JOIN pg_catalog.pg_namespace n"
6014  " ON n.oid = c.relnamespace\n"
6015  " INNER JOIN pg_catalog.pg_foreign_server s"
6016  " ON s.oid = ft.ftserver\n");
6017  if (verbose)
6019  " LEFT JOIN pg_catalog.pg_description d\n"
6020  " ON d.classoid = c.tableoid AND "
6021  "d.objoid = c.oid AND d.objsubid = 0\n");
6022 
6023  if (!validateSQLNamePattern(&buf, pattern, false, false,
6024  "n.nspname", "c.relname", NULL,
6025  "pg_catalog.pg_table_is_visible(c.oid)",
6026  NULL, 3))
6027  {
6028  termPQExpBuffer(&buf);
6029  return false;
6030  }
6031 
6032  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6033 
6034  res = PSQLexec(buf.data);
6035  termPQExpBuffer(&buf);
6036  if (!res)
6037  return false;
6038 
6039  myopt.title = _("List of foreign tables");
6040  myopt.translate_header = true;
6041 
6042  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6043 
6044  PQclear(res);
6045  return true;
6046 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listLanguages()

bool listLanguages ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 4359 of file describe.c.

4360 {
4362  PGresult *res;
4363  printQueryOpt myopt = pset.popt;
4364 
4365  initPQExpBuffer(&buf);
4366 
4368  "SELECT l.lanname AS \"%s\",\n"
4369  " pg_catalog.pg_get_userbyid(l.lanowner) as \"%s\",\n"
4370  " l.lanpltrusted AS \"%s\"",
4371  gettext_noop("Name"),
4372  gettext_noop("Owner"),
4373  gettext_noop("Trusted"));
4374 
4375  if (verbose)
4376  {
4378  ",\n NOT l.lanispl AS \"%s\",\n"
4379  " l.lanplcallfoid::pg_catalog.regprocedure AS \"%s\",\n"
4380  " l.lanvalidator::pg_catalog.regprocedure AS \"%s\",\n "
4381  "l.laninline::pg_catalog.regprocedure AS \"%s\",\n ",
4382  gettext_noop("Internal language"),
4383  gettext_noop("Call handler"),
4384  gettext_noop("Validator"),
4385  gettext_noop("Inline handler"));
4386  printACLColumn(&buf, "l.lanacl");
4387  }
4388 
4390  ",\n d.description AS \"%s\""
4391  "\nFROM pg_catalog.pg_language l\n"
4392  "LEFT JOIN pg_catalog.pg_description d\n"
4393  " ON d.classoid = l.tableoid AND d.objoid = l.oid\n"
4394  " AND d.objsubid = 0\n",
4395  gettext_noop("Description"));
4396 
4397  if (pattern)
4398  {
4399  if (!validateSQLNamePattern(&buf, pattern, false, false,
4400  NULL, "l.lanname", NULL, NULL,
4401  NULL, 2))
4402  {
4403  termPQExpBuffer(&buf);
4404  return false;
4405  }
4406  }
4407 
4408  if (!showSystem && !pattern)
4409  appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n");
4410 
4411 
4412  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4413 
4414  res = PSQLexec(buf.data);
4415  termPQExpBuffer(&buf);
4416  if (!res)
4417  return false;
4418 
4419  myopt.title = _("List of languages");
4420  myopt.translate_header = true;
4421 
4422  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4423 
4424  PQclear(res);
4425  return true;
4426 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listLargeObjects()

bool listLargeObjects ( bool  verbose)

Definition at line 7106 of file describe.c.

7107 {
7109  PGresult *res;
7110  printQueryOpt myopt = pset.popt;
7111 
7112  initPQExpBuffer(&buf);
7113 
7115  "SELECT oid as \"%s\",\n"
7116  " pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n ",
7117  gettext_noop("ID"),
7118  gettext_noop("Owner"));
7119 
7120  if (verbose)
7121  {
7122  printACLColumn(&buf, "lomacl");
7123  appendPQExpBufferStr(&buf, ",\n ");
7124  }
7125 
7127  "pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
7128  "FROM pg_catalog.pg_largeobject_metadata\n"
7129  "ORDER BY oid",
7130  gettext_noop("Description"));
7131 
7132  res = PSQLexec(buf.data);
7133  termPQExpBuffer(&buf);
7134  if (!res)
7135  return false;
7136 
7137  myopt.title = _("Large objects");
7138  myopt.translate_header = true;
7139 
7140  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7141 
7142  PQclear(res);
7143  return true;
7144 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, and verbose.

Referenced by exec_command_d(), and exec_command_lo().

◆ listOperatorClasses()

bool listOperatorClasses ( const char *  access_method_pattern,
const char *  type_pattern,
bool  verbose 
)

Definition at line 6729 of file describe.c.

6731 {
6733  PGresult *res;
6734  printQueryOpt myopt = pset.popt;
6735  bool have_where = false;
6736  static const bool translate_columns[] = {false, false, false, false, false, false, false};
6737 
6738  initPQExpBuffer(&buf);
6739 
6741  "SELECT\n"
6742  " am.amname AS \"%s\",\n"
6743  " pg_catalog.format_type(c.opcintype, NULL) AS \"%s\",\n"
6744  " CASE\n"
6745  " WHEN c.opckeytype <> 0 AND c.opckeytype <> c.opcintype\n"
6746  " THEN pg_catalog.format_type(c.opckeytype, NULL)\n"
6747  " ELSE NULL\n"
6748  " END AS \"%s\",\n"
6749  " CASE\n"
6750  " WHEN pg_catalog.pg_opclass_is_visible(c.oid)\n"
6751  " THEN pg_catalog.format('%%I', c.opcname)\n"
6752  " ELSE pg_catalog.format('%%I.%%I', n.nspname, c.opcname)\n"
6753  " END AS \"%s\",\n"
6754  " (CASE WHEN c.opcdefault\n"
6755  " THEN '%s'\n"
6756  " ELSE '%s'\n"
6757  " END) AS \"%s\"",
6758  gettext_noop("AM"),
6759  gettext_noop("Input type"),
6760  gettext_noop("Storage type"),
6761  gettext_noop("Operator class"),
6762  gettext_noop("yes"),
6763  gettext_noop("no"),
6764  gettext_noop("Default?"));
6765  if (verbose)
6767  ",\n CASE\n"
6768  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
6769  " THEN pg_catalog.format('%%I', of.opfname)\n"
6770  " ELSE pg_catalog.format('%%I.%%I', ofn.nspname, of.opfname)\n"
6771  " END AS \"%s\",\n"
6772  " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n",
6773  gettext_noop("Operator family"),
6774  gettext_noop("Owner"));
6776  "\nFROM pg_catalog.pg_opclass c\n"
6777  " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n"
6778  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
6779  " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
6780  " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
6781  if (verbose)
6783  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
6784  " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
6785 
6786  if (access_method_pattern)
6787  if (!validateSQLNamePattern(&buf, access_method_pattern,
6788  false, false, NULL, "am.amname", NULL, NULL,
6789  &have_where, 1))
6790  goto error_return;
6791  if (type_pattern)
6792  {
6793  /* Match type name pattern against either internal or external name */
6794  if (!validateSQLNamePattern(&buf, type_pattern, have_where, false,
6795  "tn.nspname", "t.typname",
6796  "pg_catalog.format_type(t.oid, NULL)",
6797  "pg_catalog.pg_type_is_visible(t.oid)",
6798  NULL, 3))
6799  goto error_return;
6800  }
6801 
6802  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
6803  res = PSQLexec(buf.data);
6804  termPQExpBuffer(&buf);
6805  if (!res)
6806  return false;
6807 
6808  myopt.title = _("List of operator classes");
6809  myopt.translate_header = true;
6810  myopt.translate_columns = translate_columns;
6811  myopt.n_translate_columns = lengthof(translate_columns);
6812 
6813  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6814 
6815  PQclear(res);
6816  return true;
6817 
6818 error_return:
6819  termPQExpBuffer(&buf);
6820  return false;
6821 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listOperatorFamilies()

bool listOperatorFamilies ( const char *  access_method_pattern,
const char *  type_pattern,
bool  verbose 
)

Definition at line 6830 of file describe.c.

6832 {
6834  PGresult *res;
6835  printQueryOpt myopt = pset.popt;
6836  bool have_where = false;
6837  static const bool translate_columns[] = {false, false, false, false};
6838 
6839  initPQExpBuffer(&buf);
6840 
6842  "SELECT\n"
6843  " am.amname AS \"%s\",\n"
6844  " CASE\n"
6845  " WHEN pg_catalog.pg_opfamily_is_visible(f.oid)\n"
6846  " THEN pg_catalog.format('%%I', f.opfname)\n"
6847  " ELSE pg_catalog.format('%%I.%%I', n.nspname, f.opfname)\n"
6848  " END AS \"%s\",\n"
6849  " (SELECT\n"
6850  " pg_catalog.string_agg(pg_catalog.format_type(oc.opcintype, NULL), ', ')\n"
6851  " FROM pg_catalog.pg_opclass oc\n"
6852  " WHERE oc.opcfamily = f.oid) \"%s\"",
6853  gettext_noop("AM"),
6854  gettext_noop("Operator family"),
6855  gettext_noop("Applicable types"));
6856  if (verbose)
6858  ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
6859  gettext_noop("Owner"));
6861  "\nFROM pg_catalog.pg_opfamily f\n"
6862  " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n"
6863  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n");
6864 
6865  if (access_method_pattern)
6866  if (!validateSQLNamePattern(&buf, access_method_pattern,
6867  false, false, NULL, "am.amname", NULL, NULL,
6868  &have_where, 1))
6869  goto error_return;
6870  if (type_pattern)
6871  {
6873  " %s EXISTS (\n"
6874  " SELECT 1\n"
6875  " FROM pg_catalog.pg_type t\n"
6876  " JOIN pg_catalog.pg_opclass oc ON oc.opcintype = t.oid\n"
6877  " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"
6878  " WHERE oc.opcfamily = f.oid\n",
6879  have_where ? "AND" : "WHERE");
6880  /* Match type name pattern against either internal or external name */
6881  if (!validateSQLNamePattern(&buf, type_pattern, true, false,
6882  "tn.nspname", "t.typname",
6883  "pg_catalog.format_type(t.oid, NULL)",
6884  "pg_catalog.pg_type_is_visible(t.oid)",
6885  NULL, 3))
6886  goto error_return;
6887  appendPQExpBufferStr(&buf, " )\n");
6888  }
6889 
6890  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6891  res = PSQLexec(buf.data);
6892  termPQExpBuffer(&buf);
6893  if (!res)
6894  return false;
6895 
6896  myopt.title = _("List of operator families");
6897  myopt.translate_header = true;
6898  myopt.translate_columns = translate_columns;
6899  myopt.n_translate_columns = lengthof(translate_columns);
6900 
6901  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6902 
6903  PQclear(res);
6904  return true;
6905 
6906 error_return:
6907  termPQExpBuffer(&buf);
6908  return false;
6909 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listOpFamilyFunctions()

bool listOpFamilyFunctions ( const char *  access_method_pattern,
const char *  family_pattern,
bool  verbose 
)

Definition at line 7017 of file describe.c.

7019 {
7021  PGresult *res;
7022  printQueryOpt myopt = pset.popt;
7023  bool have_where = false;
7024  static const bool translate_columns[] = {false, false, false, false, false, false};
7025 
7026  initPQExpBuffer(&buf);
7027 
7029  "SELECT\n"
7030  " am.amname AS \"%s\",\n"
7031  " CASE\n"
7032  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7033  " THEN pg_catalog.format('%%I', of.opfname)\n"
7034  " ELSE pg_catalog.format('%%I.%%I', ns.nspname, of.opfname)\n"
7035  " END AS \"%s\",\n"
7036  " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n"
7037  " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n"
7038  " ap.amprocnum AS \"%s\"\n",
7039  gettext_noop("AM"),
7040  gettext_noop("Operator family"),
7041  gettext_noop("Registered left type"),
7042  gettext_noop("Registered right type"),
7043  gettext_noop("Number"));
7044 
7045  if (!verbose)
7047  ", p.proname AS \"%s\"\n",
7048  gettext_noop("Function"));
7049  else
7051  ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n",
7052  gettext_noop("Function"));
7053 
7055  "FROM pg_catalog.pg_amproc ap\n"
7056  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n"
7057  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n"
7058  " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n"
7059  " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
7060 
7061  if (access_method_pattern)
7062  {
7063  if (!validateSQLNamePattern(&buf, access_method_pattern,
7064  false, false, NULL, "am.amname",
7065  NULL, NULL,
7066  &have_where, 1))
7067  goto error_return;
7068  }
7069  if (family_pattern)
7070  {
7071  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
7072  "ns.nspname", "of.opfname", NULL, NULL,
7073  NULL, 3))
7074  goto error_return;
7075  }
7076 
7077  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7078  " ap.amproclefttype = ap.amprocrighttype DESC,\n"
7079  " 3, 4, 5;");
7080 
7081  res = PSQLexec(buf.data);
7082  termPQExpBuffer(&buf);
7083  if (!res)
7084  return false;
7085 
7086  myopt.title = _("List of support functions of operator families");
7087  myopt.translate_header = true;
7088  myopt.translate_columns = translate_columns;
7089  myopt.n_translate_columns = lengthof(translate_columns);
7090 
7091  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7092 
7093  PQclear(res);
7094  return true;
7095 
7096 error_return:
7097  termPQExpBuffer(&buf);
7098  return false;
7099 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listOpFamilyOperators()

bool listOpFamilyOperators ( const char *  access_method_pattern,
const char *  family_pattern,
bool  verbose 
)

Definition at line 6919 of file describe.c.

6921 {
6923  PGresult *res;
6924  printQueryOpt myopt = pset.popt;
6925  bool have_where = false;
6926 
6927  static const bool translate_columns[] = {false, false, false, false, false, false};
6928 
6929  initPQExpBuffer(&buf);
6930 
6932  "SELECT\n"
6933  " am.amname AS \"%s\",\n"
6934  " CASE\n"
6935  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
6936  " THEN pg_catalog.format('%%I', of.opfname)\n"
6937  " ELSE pg_catalog.format('%%I.%%I', nsf.nspname, of.opfname)\n"
6938  " END AS \"%s\",\n"
6939  " o.amopopr::pg_catalog.regoperator AS \"%s\"\n,"
6940  " o.amopstrategy AS \"%s\",\n"
6941  " CASE o.amoppurpose\n"
6942  " WHEN 'o' THEN '%s'\n"
6943  " WHEN 's' THEN '%s'\n"
6944  " END AS \"%s\"\n",
6945  gettext_noop("AM"),
6946  gettext_noop("Operator family"),
6947  gettext_noop("Operator"),
6948  gettext_noop("Strategy"),
6949  gettext_noop("ordering"),
6950  gettext_noop("search"),
6951  gettext_noop("Purpose"));
6952 
6953  if (verbose)
6955  ", ofs.opfname AS \"%s\"\n",
6956  gettext_noop("Sort opfamily"));
6958  "FROM pg_catalog.pg_amop o\n"
6959  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
6960  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
6961  " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
6962  if (verbose)
6964  " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
6965 
6966  if (access_method_pattern)
6967  {
6968  if (!validateSQLNamePattern(&buf, access_method_pattern,
6969  false, false, NULL, "am.amname",
6970  NULL, NULL,
6971  &have_where, 1))
6972  goto error_return;
6973  }
6974 
6975  if (family_pattern)
6976  {
6977  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
6978  "nsf.nspname", "of.opfname", NULL, NULL,
6979  NULL, 3))
6980  goto error_return;
6981  }
6982 
6983  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
6984  " o.amoplefttype = o.amoprighttype DESC,\n"
6985  " pg_catalog.format_type(o.amoplefttype, NULL),\n"
6986  " pg_catalog.format_type(o.amoprighttype, NULL),\n"
6987  " o.amopstrategy;");
6988 
6989  res = PSQLexec(buf.data);
6990  termPQExpBuffer(&buf);
6991  if (!res)
6992  return false;
6993 
6994  myopt.title = _("List of operators of operator families");
6995  myopt.translate_header = true;
6996  myopt.translate_columns = translate_columns;
6997  myopt.n_translate_columns = lengthof(translate_columns);
6998 
6999  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7000 
7001  PQclear(res);
7002  return true;
7003 
7004 error_return:
7005  termPQExpBuffer(&buf);
7006  return false;
7007 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listPartitionedTables()

bool listPartitionedTables ( const char *  reltypes,
const char *  pattern,
bool  verbose 
)

Definition at line 4159 of file describe.c.

4160 {
4161  bool showTables = strchr(reltypes, 't') != NULL;
4162  bool showIndexes = strchr(reltypes, 'i') != NULL;
4163  bool showNested = strchr(reltypes, 'n') != NULL;
4165  PQExpBufferData title;
4166  PGresult *res;
4167  printQueryOpt myopt = pset.popt;
4168  bool translate_columns[] = {false, false, false, false, false, false, false, false, false};
4169  const char *tabletitle;
4170  bool mixed_output = false;
4171 
4172  /*
4173  * Note: Declarative table partitioning is only supported as of Pg 10.0.
4174  */
4175  if (pset.sversion < 100000)
4176  {
4177  char sverbuf[32];
4178 
4179  pg_log_error("The server (version %s) does not support declarative table partitioning.",
4181  sverbuf, sizeof(sverbuf)));
4182  return true;
4183  }
4184 
4185  /* If no relation kind was selected, show them all */
4186  if (!showTables && !showIndexes)
4187  showTables = showIndexes = true;
4188 
4189  if (showIndexes && !showTables)
4190  tabletitle = _("List of partitioned indexes"); /* \dPi */
4191  else if (showTables && !showIndexes)
4192  tabletitle = _("List of partitioned tables"); /* \dPt */
4193  else
4194  {
4195  /* show all kinds */
4196  tabletitle = _("List of partitioned relations");
4197  mixed_output = true;
4198  }
4199 
4200  initPQExpBuffer(&buf);
4201 
4203  "SELECT n.nspname as \"%s\",\n"
4204  " c.relname as \"%s\",\n"
4205  " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
4206  gettext_noop("Schema"),
4207  gettext_noop("Name"),
4208  gettext_noop("Owner"));
4209 
4210  if (mixed_output)
4211  {
4213  ",\n CASE c.relkind"
4214  " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
4215  " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
4216  " END as \"%s\"",
4217  gettext_noop("partitioned table"),
4218  gettext_noop("partitioned index"),
4219  gettext_noop("Type"));
4220 
4221  translate_columns[3] = true;
4222  }
4223 
4224  if (showNested || pattern)
4226  ",\n inh.inhparent::pg_catalog.regclass as \"%s\"",
4227  gettext_noop("Parent name"));
4228 
4229  if (showIndexes)
4231  ",\n c2.oid::pg_catalog.regclass as \"%s\"",
4232  gettext_noop("Table"));
4233 
4234  if (verbose)
4235  {
4236  if (showNested)
4237  {
4239  ",\n s.dps as \"%s\"",
4240  gettext_noop("Leaf partition size"));
4242  ",\n s.tps as \"%s\"",
4243  gettext_noop("Total size"));
4244  }
4245  else
4246  /* Sizes of all partitions are considered in this case. */
4248  ",\n s.tps as \"%s\"",
4249  gettext_noop("Total size"));
4250 
4252  ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
4253  gettext_noop("Description"));
4254  }
4255 
4257  "\nFROM pg_catalog.pg_class c"
4258  "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
4259 
4260  if (showIndexes)
4262  "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid"
4263  "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
4264 
4265  if (showNested || pattern)
4267  "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
4268 
4269  if (verbose)
4270  {
4271  if (pset.sversion < 120000)
4272  {
4274  ",\n LATERAL (WITH RECURSIVE d\n"
4275  " AS (SELECT inhrelid AS oid, 1 AS level\n"
4276  " FROM pg_catalog.pg_inherits\n"
4277  " WHERE inhparent = c.oid\n"
4278  " UNION ALL\n"
4279  " SELECT inhrelid, level + 1\n"
4280  " FROM pg_catalog.pg_inherits i\n"
4281  " JOIN d ON i.inhparent = d.oid)\n"
4282  " SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.pg_table_size("
4283  "d.oid))) AS tps,\n"
4284  " pg_catalog.pg_size_pretty(sum("
4285  "\n CASE WHEN d.level = 1"
4286  " THEN pg_catalog.pg_table_size(d.oid) ELSE 0 END)) AS dps\n"
4287  " FROM d) s");
4288  }
4289  else
4290  {
4291  /* PostgreSQL 12 has pg_partition_tree function */
4293  ",\n LATERAL (SELECT pg_catalog.pg_size_pretty(sum("
4294  "\n CASE WHEN ppt.isleaf AND ppt.level = 1"
4295  "\n THEN pg_catalog.pg_table_size(ppt.relid)"
4296  " ELSE 0 END)) AS dps"
4297  ",\n pg_catalog.pg_size_pretty(sum("
4298  "pg_catalog.pg_table_size(ppt.relid))) AS tps"
4299  "\n FROM pg_catalog.pg_partition_tree(c.oid) ppt) s");
4300  }
4301  }
4302 
4303  appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
4304  if (showTables)
4305  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
4306  if (showIndexes)
4307  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
4308  appendPQExpBufferStr(&buf, "''"); /* dummy */
4309  appendPQExpBufferStr(&buf, ")\n");
4310 
4311  appendPQExpBufferStr(&buf, !showNested && !pattern ?
4312  " AND NOT c.relispartition\n" : "");
4313 
4314  if (!pattern)
4315  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4316  " AND n.nspname !~ '^pg_toast'\n"
4317  " AND n.nspname <> 'information_schema'\n");
4318 
4319  if (!validateSQLNamePattern(&buf, pattern, true, false,
4320  "n.nspname", "c.relname", NULL,
4321  "pg_catalog.pg_table_is_visible(c.oid)",
4322  NULL, 3))
4323  {
4324  termPQExpBuffer(&buf);
4325  return false;
4326  }
4327 
4328  appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";",
4329  mixed_output ? "\"Type\" DESC, " : "",
4330  showNested || pattern ? "\"Parent name\" NULLS FIRST, " : "");
4331 
4332  res = PSQLexec(buf.data);
4333  termPQExpBuffer(&buf);
4334  if (!res)
4335  return false;
4336 
4337  initPQExpBuffer(&title);
4338  appendPQExpBufferStr(&title, tabletitle);
4339 
4340  myopt.title = title.data;
4341  myopt.translate_header = true;
4342  myopt.translate_columns = translate_columns;
4343  myopt.n_translate_columns = lengthof(translate_columns);
4344 
4345  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4346 
4347  termPQExpBuffer(&title);
4348 
4349  PQclear(res);
4350  return true;
4351 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, PQExpBufferData::data, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listPublications()

bool listPublications ( const char *  pattern)

Definition at line 6269 of file describe.c.

6270 {
6272  PGresult *res;
6273  printQueryOpt myopt = pset.popt;
6274  static const bool translate_columns[] = {false, false, false, false, false, false, false, false};
6275 
6276  if (pset.sversion < 100000)
6277  {
6278  char sverbuf[32];
6279 
6280  pg_log_error("The server (version %s) does not support publications.",
6282  sverbuf, sizeof(sverbuf)));
6283  return true;
6284  }
6285 
6286  initPQExpBuffer(&buf);
6287 
6289  "SELECT pubname AS \"%s\",\n"
6290  " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n"
6291  " puballtables AS \"%s\",\n"
6292  " pubinsert AS \"%s\",\n"
6293  " pubupdate AS \"%s\",\n"
6294  " pubdelete AS \"%s\"",
6295  gettext_noop("Name"),
6296  gettext_noop("Owner"),
6297  gettext_noop("All tables"),
6298  gettext_noop("Inserts"),
6299  gettext_noop("Updates"),
6300  gettext_noop("Deletes"));
6301  if (pset.sversion >= 110000)
6303  ",\n pubtruncate AS \"%s\"",
6304  gettext_noop("Truncates"));
6305  if (pset.sversion >= 130000)
6307  ",\n pubviaroot AS \"%s\"",
6308  gettext_noop("Via root"));
6309 
6311  "\nFROM pg_catalog.pg_publication\n");
6312 
6313  if (!validateSQLNamePattern(&buf, pattern, false, false,
6314  NULL, "pubname", NULL,
6315  NULL,
6316  NULL, 1))
6317  {
6318  termPQExpBuffer(&buf);
6319  return false;
6320  }
6321 
6322  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6323 
6324  res = PSQLexec(buf.data);
6325  termPQExpBuffer(&buf);
6326  if (!res)
6327  return false;
6328 
6329  myopt.title = _("List of publications");
6330  myopt.translate_header = true;
6331  myopt.translate_columns = translate_columns;
6332  myopt.n_translate_columns = lengthof(translate_columns);
6333 
6334  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6335 
6336  PQclear(res);
6337 
6338  return true;
6339 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ listSchemas()

bool listSchemas ( const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 5078 of file describe.c.

5079 {
5081  PGresult *res;
5082  printQueryOpt myopt = pset.popt;
5083  int pub_schema_tuples = 0;
5084  char **footers = NULL;
5085 
5086  initPQExpBuffer(&buf);
5088  "SELECT n.nspname AS \"%s\",\n"
5089  " pg_catalog.pg_get_userbyid(n.nspowner) AS \"%s\"",
5090  gettext_noop("Name"),
5091  gettext_noop("Owner"));
5092 
5093  if (verbose)
5094  {
5095  appendPQExpBufferStr(&buf, ",\n ");
5096  printACLColumn(&buf, "n.nspacl");
5098  ",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
5099  gettext_noop("Description"));
5100  }
5101 
5103  "\nFROM pg_catalog.pg_namespace n\n");
5104 
5105  if (!showSystem && !pattern)
5107  "WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'\n");
5108 
5109  if (!validateSQLNamePattern(&buf, pattern,
5110  !showSystem && !pattern, false,
5111  NULL, "n.nspname", NULL,
5112  NULL,
5113  NULL, 2))
5114  goto error_return;
5115 
5116  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5117 
5118  res = PSQLexec(buf.data);
5119  if (!res)
5120  goto error_return;
5121 
5122  myopt.title = _("List of schemas");
5123  myopt.translate_header = true;
5124 
5125  if (pattern && pset.sversion >= 150000)
5126  {
5127  PGresult *result;
5128  int i;
5129 
5131  "SELECT pubname \n"
5132  "FROM pg_catalog.pg_publication p\n"
5133  " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n"
5134  " JOIN pg_catalog.pg_namespace n ON n.oid = pn.pnnspid \n"
5135  "WHERE n.nspname = '%s'\n"
5136  "ORDER BY 1",
5137  pattern);
5138  result = PSQLexec(buf.data);
5139  if (!result)
5140  goto error_return;
5141  else
5142  pub_schema_tuples = PQntuples(result);
5143 
5144  if (pub_schema_tuples > 0)
5145  {
5146  /*
5147  * Allocate memory for footers. Size of footers will be 1 (for
5148  * storing "Publications:" string) + publication schema mapping
5149  * count + 1 (for storing NULL).
5150  */
5151  footers = (char **) pg_malloc((1 + pub_schema_tuples + 1) * sizeof(char *));
5152  footers[0] = pg_strdup(_("Publications:"));
5153 
5154  /* Might be an empty set - that's ok */
5155  for (i = 0; i < pub_schema_tuples; i++)
5156  {
5157  printfPQExpBuffer(&buf, " \"%s\"",
5158  PQgetvalue(result, i, 0));
5159 
5160  footers[i + 1] = pg_strdup(buf.data);
5161  }
5162 
5163  footers[i + 1] = NULL;
5164  myopt.footers = footers;
5165  }
5166 
5167  PQclear(result);
5168  }
5169 
5170  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5171 
5172  termPQExpBuffer(&buf);
5173  PQclear(res);
5174 
5175  /* Free the memory allocated for the footer */
5176  if (footers)
5177  {
5178  char **footer = NULL;
5179 
5180  for (footer = footers; *footer; footer++)
5181  pg_free(*footer);
5182 
5183  pg_free(footers);
5184  }
5185 
5186  return true;
5187 
5188 error_return:
5189  termPQExpBuffer(&buf);
5190  return false;
5191 }
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
char ** footers
Definition: print.h:188

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, printQueryOpt::footers, gettext_noop, i, initPQExpBuffer(), _psqlSettings::logfile, pg_free(), pg_malloc(), pg_strdup(), _psqlSettings::popt, PQclear(), PQgetvalue(), PQntuples(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listTables()

bool listTables ( const char *  tabtypes,
const char *  pattern,
bool  verbose,
bool  showSystem 
)

Definition at line 3961 of file describe.c.

3962 {
3963  bool showTables = strchr(tabtypes, 't') != NULL;
3964  bool showIndexes = strchr(tabtypes, 'i') != NULL;
3965  bool showViews = strchr(tabtypes, 'v') != NULL;
3966  bool showMatViews = strchr(tabtypes, 'm') != NULL;
3967  bool showSeq = strchr(tabtypes, 's') != NULL;
3968  bool showForeign = strchr(tabtypes, 'E') != NULL;
3969 
3971  PGresult *res;
3972  printQueryOpt myopt = pset.popt;
3973  int cols_so_far;
3974  bool translate_columns[] = {false, false, true, false, false, false, false, false, false};
3975 
3976  /* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */
3977  if (!(showTables || showIndexes || showViews || showMatViews || showSeq || showForeign))
3978  showTables = showViews = showMatViews = showSeq = showForeign = true;
3979 
3980  initPQExpBuffer(&buf);
3981 
3983  "SELECT n.nspname as \"%s\",\n"
3984  " c.relname as \"%s\",\n"
3985  " CASE c.relkind"
3986  " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
3987  " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
3988  " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
3989  " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'"
3990  " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
3991  " WHEN " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'"
3992  " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
3993  " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
3994  " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
3995  " END as \"%s\",\n"
3996  " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
3997  gettext_noop("Schema"),
3998  gettext_noop("Name"),
3999  gettext_noop("table"),
4000  gettext_noop("view"),
4001  gettext_noop("materialized view"),
4002  gettext_noop("index"),
4003  gettext_noop("sequence"),
4004  gettext_noop("TOAST table"),
4005  gettext_noop("foreign table"),
4006  gettext_noop("partitioned table"),
4007  gettext_noop("partitioned index"),
4008  gettext_noop("Type"),
4009  gettext_noop("Owner"));
4010  cols_so_far = 4;
4011 
4012  if (showIndexes)
4013  {
4015  ",\n c2.relname as \"%s\"",
4016  gettext_noop("Table"));
4017  cols_so_far++;
4018  }
4019 
4020  if (verbose)
4021  {
4022  /*
4023  * Show whether a relation is permanent, temporary, or unlogged.
4024  */
4026  ",\n CASE c.relpersistence WHEN 'p' THEN '%s' WHEN 't' THEN '%s' WHEN 'u' THEN '%s' END as \"%s\"",
4027  gettext_noop("permanent"),
4028  gettext_noop("temporary"),
4029  gettext_noop("unlogged"),
4030  gettext_noop("Persistence"));
4031  translate_columns[cols_so_far] = true;
4032 
4033  /*
4034  * We don't bother to count cols_so_far below here, as there's no need
4035  * to; this might change with future additions to the output columns.
4036  */
4037 
4038  /*
4039  * Access methods exist for tables, materialized views and indexes.
4040  * This has been introduced in PostgreSQL 12 for tables.
4041  */
4042  if (pset.sversion >= 120000 && !pset.hide_tableam &&
4043  (showTables || showMatViews || showIndexes))
4045  ",\n am.amname as \"%s\"",
4046  gettext_noop("Access method"));
4047 
4049  ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
4050  ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
4051  gettext_noop("Size"),
4052  gettext_noop("Description"));
4053  }
4054 
4056  "\nFROM pg_catalog.pg_class c"
4057  "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
4058 
4059  if (pset.sversion >= 120000 && !pset.hide_tableam &&
4060  (showTables || showMatViews || showIndexes))
4062  "\n LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam");
4063 
4064  if (showIndexes)
4066  "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid"
4067  "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
4068 
4069  appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
4070  if (showTables)
4071  {
4072  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) ","
4073  CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
4074  /* with 'S' or a pattern, allow 't' to match TOAST tables too */
4075  if (showSystem || pattern)
4076  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ",");
4077  }
4078  if (showViews)
4079  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ",");
4080  if (showMatViews)
4081  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ",");
4082  if (showIndexes)
4083  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) ","
4084  CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
4085  if (showSeq)
4086  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ",");
4087  if (showSystem || pattern)
4088  appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */
4089  if (showForeign)
4090  appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ",");
4091 
4092  appendPQExpBufferStr(&buf, "''"); /* dummy */
4093  appendPQExpBufferStr(&buf, ")\n");
4094 
4095  if (!showSystem && !pattern)
4096  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4097  " AND n.nspname !~ '^pg_toast'\n"
4098  " AND n.nspname <> 'information_schema'\n");
4099 
4100  if (!validateSQLNamePattern(&buf, pattern, true, false,
4101  "n.nspname", "c.relname", NULL,
4102  "pg_catalog.pg_table_is_visible(c.oid)",
4103  NULL, 3))
4104  {
4105  termPQExpBuffer(&buf);
4106  return false;
4107  }
4108 
4109  appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
4110 
4111  res = PSQLexec(buf.data);
4112  termPQExpBuffer(&buf);
4113  if (!res)
4114  return false;
4115 
4116  /*
4117  * Most functions in this file are content to print an empty table when
4118  * there are no matching objects. We intentionally deviate from that
4119  * here, but only in !quiet mode, for historical reasons.
4120  */
4121  if (PQntuples(res) == 0 && !pset.quiet)
4122  {
4123  if (pattern)
4124  pg_log_error("Did not find any relation named \"%s\".",
4125  pattern);
4126  else
4127  pg_log_error("Did not find any relations.");
4128  }
4129  else
4130  {
4131  myopt.title = _("List of relations");
4132  myopt.translate_header = true;
4133  myopt.translate_columns = translate_columns;
4134  myopt.n_translate_columns = lengthof(translate_columns);
4135 
4136  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4137  }
4138 
4139  PQclear(res);
4140  return true;
4141 }
bool hide_tableam
Definition: settings.h:142

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, _psqlSettings::hide_tableam, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear(), PQntuples(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listTSConfigs()

bool listTSConfigs ( const char *  pattern,
bool  verbose 
)

Definition at line 5576 of file describe.c.

5577 {
5579  PGresult *res;
5580  printQueryOpt myopt = pset.popt;
5581 
5582  if (verbose)
5583  return listTSConfigsVerbose(pattern);
5584 
5585  initPQExpBuffer(&buf);
5586 
5588  "SELECT\n"
5589  " n.nspname as \"%s\",\n"
5590  " c.cfgname as \"%s\",\n"
5591  " pg_catalog.obj_description(c.oid, 'pg_ts_config') as \"%s\"\n"
5592  "FROM pg_catalog.pg_ts_config c\n"
5593  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace\n",
5594  gettext_noop("Schema"),
5595  gettext_noop("Name"),
5596  gettext_noop("Description")
5597  );
5598 
5599  if (!validateSQLNamePattern(&buf, pattern, false, false,
5600  "n.nspname", "c.cfgname", NULL,
5601  "pg_catalog.pg_ts_config_is_visible(c.oid)",
5602  NULL, 3))
5603  {
5604  termPQExpBuffer(&buf);
5605  return false;
5606  }
5607 
5608  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5609 
5610  res = PSQLexec(buf.data);
5611  termPQExpBuffer(&buf);
5612  if (!res)
5613  return false;
5614 
5615  myopt.title = _("List of text search configurations");
5616  myopt.translate_header = true;
5617 
5618  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5619 
5620  PQclear(res);
5621  return true;
5622 }
static bool listTSConfigsVerbose(const char *pattern)
Definition: describe.c:5625

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), listTSConfigsVerbose(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listTSDictionaries()

bool listTSDictionaries ( const char *  pattern,
bool  verbose 
)

Definition at line 5446 of file describe.c.

5447 {
5449  PGresult *res;
5450  printQueryOpt myopt = pset.popt;
5451 
5452  initPQExpBuffer(&buf);
5453 
5455  "SELECT\n"
5456  " n.nspname as \"%s\",\n"
5457  " d.dictname as \"%s\",\n",
5458  gettext_noop("Schema"),
5459  gettext_noop("Name"));
5460 
5461  if (verbose)
5462  {
5464  " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
5465  " pg_catalog.pg_ts_template t\n"
5466  " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace\n"
5467  " WHERE d.dicttemplate = t.oid ) AS \"%s\",\n"
5468  " d.dictinitoption as \"%s\",\n",
5469  gettext_noop("Template"),
5470  gettext_noop("Init options"));
5471  }
5472 
5474  " pg_catalog.obj_description(d.oid, 'pg_ts_dict') as \"%s\"\n",
5475  gettext_noop("Description"));
5476 
5477  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_dict d\n"
5478  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace\n");
5479 
5480  if (!validateSQLNamePattern(&buf, pattern, false, false,
5481  "n.nspname", "d.dictname", NULL,
5482  "pg_catalog.pg_ts_dict_is_visible(d.oid)",
5483  NULL, 3))
5484  {
5485  termPQExpBuffer(&buf);
5486  return false;
5487  }
5488 
5489  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5490 
5491  res = PSQLexec(buf.data);
5492  termPQExpBuffer(&buf);
5493  if (!res)
5494  return false;
5495 
5496  myopt.title = _("List of text search dictionaries");
5497  myopt.translate_header = true;
5498 
5499  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5500 
5501  PQclear(res);
5502  return true;
5503 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listTSParsers()

bool listTSParsers ( const char *  pattern,
bool  verbose 
)

Definition at line 5199 of file describe.c.

5200 {
5202  PGresult *res;
5203  printQueryOpt myopt = pset.popt;
5204 
5205  if (verbose)
5206  return listTSParsersVerbose(pattern);
5207 
5208  initPQExpBuffer(&buf);
5209 
5211  "SELECT\n"
5212  " n.nspname as \"%s\",\n"
5213  " p.prsname as \"%s\",\n"
5214  " pg_catalog.obj_description(p.oid, 'pg_ts_parser') as \"%s\"\n"
5215  "FROM pg_catalog.pg_ts_parser p\n"
5216  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n",
5217  gettext_noop("Schema"),
5218  gettext_noop("Name"),
5219  gettext_noop("Description")
5220  );
5221 
5222  if (!validateSQLNamePattern(&buf, pattern, false, false,
5223  "n.nspname", "p.prsname", NULL,
5224  "pg_catalog.pg_ts_parser_is_visible(p.oid)",
5225  NULL, 3))
5226  {
5227  termPQExpBuffer(&buf);
5228  return false;
5229  }
5230 
5231  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5232 
5233  res = PSQLexec(buf.data);
5234  termPQExpBuffer(&buf);
5235  if (!res)
5236  return false;
5237 
5238  myopt.title = _("List of text search parsers");
5239  myopt.translate_header = true;
5240 
5241  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5242 
5243  PQclear(res);
5244  return true;
5245 }
static bool listTSParsersVerbose(const char *pattern)
Definition: describe.c:5251

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), listTSParsersVerbose(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listTSTemplates()

bool listTSTemplates ( const char *  pattern,
bool  verbose 
)

Definition at line 5511 of file describe.c.

5512 {
5514  PGresult *res;
5515  printQueryOpt myopt = pset.popt;
5516 
5517  initPQExpBuffer(&buf);
5518 
5519  if (verbose)
5521  "SELECT\n"
5522  " n.nspname AS \"%s\",\n"
5523  " t.tmplname AS \"%s\",\n"
5524  " t.tmplinit::pg_catalog.regproc AS \"%s\",\n"
5525  " t.tmpllexize::pg_catalog.regproc AS \"%s\",\n"
5526  " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5527  gettext_noop("Schema"),
5528  gettext_noop("Name"),
5529  gettext_noop("Init"),
5530  gettext_noop("Lexize"),
5531  gettext_noop("Description"));
5532  else
5534  "SELECT\n"
5535  " n.nspname AS \"%s\",\n"
5536  " t.tmplname AS \"%s\",\n"
5537  " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5538  gettext_noop("Schema"),
5539  gettext_noop("Name"),
5540  gettext_noop("Description"));
5541 
5542  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_template t\n"
5543  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace\n");
5544 
5545  if (!validateSQLNamePattern(&buf, pattern, false, false,
5546  "n.nspname", "t.tmplname", NULL,
5547  "pg_catalog.pg_ts_template_is_visible(t.oid)",
5548  NULL, 3))
5549  {
5550  termPQExpBuffer(&buf);
5551  return false;
5552  }
5553 
5554  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5555 
5556  res = PSQLexec(buf.data);
5557  termPQExpBuffer(&buf);
5558  if (!res)
5559  return false;
5560 
5561  myopt.title = _("List of text search templates");
5562  myopt.translate_header = true;
5563 
5564  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5565 
5566  PQclear(res);
5567  return true;
5568 }

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ listUserMappings()

bool listUserMappings ( const char *  pattern,
bool  verbose 
)

Definition at line 5927 of file describe.c.

5928 {
5930  PGresult *res;
5931  printQueryOpt myopt = pset.popt;
5932 
5933  initPQExpBuffer(&buf);
5935  "SELECT um.srvname AS \"%s\",\n"
5936  " um.usename AS \"%s\"",
5937  gettext_noop("Server"),
5938  gettext_noop("User name"));
5939 
5940  if (verbose)
5942  ",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
5943  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5944  " pg_catalog.quote_ident(option_name) || ' ' || "
5945  " pg_catalog.quote_literal(option_value) FROM "
5946  " pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' "
5947  " END AS \"%s\"",
5948  gettext_noop("FDW options"));
5949 
5950  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_user_mappings um\n");
5951 
5952  if (!validateSQLNamePattern(&buf, pattern, false, false,
5953  NULL, "um.srvname", "um.usename", NULL,
5954  NULL, 1))
5955  {
5956  termPQExpBuffer(&buf);
5957  return false;
5958  }
5959 
5960  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5961 
5962  res = PSQLexec(buf.data);
5963  termPQExpBuffer(&buf);
5964  if (!res)
5965  return false;
5966 
5967  myopt.title = _("List of user mappings");
5968  myopt.translate_header = true;
5969 
5970  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5971 
5972  PQclear(res);
5973  return true;
5974 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_header, validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ objectDescription()

bool objectDescription ( const char *  pattern,
bool  showSystem 
)

Definition at line 1252 of file describe.c.

1253 {
1255  PGresult *res;
1256  printQueryOpt myopt = pset.popt;
1257  static const bool translate_columns[] = {false, false, true, false};
1258 
1259  initPQExpBuffer(&buf);
1260 
1262  "SELECT DISTINCT tt.nspname AS \"%s\", tt.name AS \"%s\", tt.object AS \"%s\", d.description AS \"%s\"\n"
1263  "FROM (\n",
1264  gettext_noop("Schema"),
1265  gettext_noop("Name"),
1266  gettext_noop("Object"),
1267  gettext_noop("Description"));
1268 
1269  /* Table constraint descriptions */
1271  " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
1272  " n.nspname as nspname,\n"
1273  " CAST(pgc.conname AS pg_catalog.text) as name,"
1274  " CAST('%s' AS pg_catalog.text) as object\n"
1275  " FROM pg_catalog.pg_constraint pgc\n"
1276  " JOIN pg_catalog.pg_class c "
1277  "ON c.oid = pgc.conrelid\n"
1278  " LEFT JOIN pg_catalog.pg_namespace n "
1279  " ON n.oid = c.relnamespace\n",
1280  gettext_noop("table constraint"));
1281 
1282  if (!showSystem && !pattern)
1283  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1284  " AND n.nspname <> 'information_schema'\n");
1285 
1286  if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
1287  false, "n.nspname", "pgc.conname", NULL,
1288  "pg_catalog.pg_table_is_visible(c.oid)",
1289  NULL, 3))
1290  goto error_return;
1291 
1292  /* Domain constraint descriptions */
1294  "UNION ALL\n"
1295  " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
1296  " n.nspname as nspname,\n"
1297  " CAST(pgc.conname AS pg_catalog.text) as name,"
1298  " CAST('%s' AS pg_catalog.text) as object\n"
1299  " FROM pg_catalog.pg_constraint pgc\n"
1300  " JOIN pg_catalog.pg_type t "
1301  "ON t.oid = pgc.contypid\n"
1302  " LEFT JOIN pg_catalog.pg_namespace n "
1303  " ON n.oid = t.typnamespace\n",
1304  gettext_noop("domain constraint"));
1305 
1306  if (!showSystem && !pattern)
1307  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1308  " AND n.nspname <> 'information_schema'\n");
1309 
1310  if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
1311  false, "n.nspname", "pgc.conname", NULL,
1312  "pg_catalog.pg_type_is_visible(t.oid)",
1313  NULL, 3))
1314  goto error_return;
1315 
1316  /* Operator class descriptions */
1318  "UNION ALL\n"
1319  " SELECT o.oid as oid, o.tableoid as tableoid,\n"
1320  " n.nspname as nspname,\n"
1321  " CAST(o.opcname AS pg_catalog.text) as name,\n"
1322  " CAST('%s' AS pg_catalog.text) as object\n"
1323  " FROM pg_catalog.pg_opclass o\n"
1324  " JOIN pg_catalog.pg_am am ON "
1325  "o.opcmethod = am.oid\n"
1326  " JOIN pg_catalog.pg_namespace n ON "
1327  "n.oid = o.opcnamespace\n",
1328  gettext_noop("operator class"));
1329 
1330  if (!showSystem && !pattern)
1331  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1332  " AND n.nspname <> 'information_schema'\n");
1333 
1334  if (!validateSQLNamePattern(&buf, pattern, true, false,
1335  "n.nspname", "o.opcname", NULL,
1336  "pg_catalog.pg_opclass_is_visible(o.oid)",
1337  NULL, 3))
1338  goto error_return;
1339 
1340  /* Operator family descriptions */
1342  "UNION ALL\n"
1343  " SELECT opf.oid as oid, opf.tableoid as tableoid,\n"
1344  " n.nspname as nspname,\n"
1345  " CAST(opf.opfname AS pg_catalog.text) AS name,\n"
1346  " CAST('%s' AS pg_catalog.text) as object\n"
1347  " FROM pg_catalog.pg_opfamily opf\n"
1348  " JOIN pg_catalog.pg_am am "
1349  "ON opf.opfmethod = am.oid\n"
1350  " JOIN pg_catalog.pg_namespace n "
1351  "ON opf.opfnamespace = n.oid\n",
1352  gettext_noop("operator family"));
1353 
1354  if (!showSystem && !pattern)
1355  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1356  " AND n.nspname <> 'information_schema'\n");
1357 
1358  if (!validateSQLNamePattern(&buf, pattern, true, false,
1359  "n.nspname", "opf.opfname", NULL,
1360  "pg_catalog.pg_opfamily_is_visible(opf.oid)",
1361  NULL, 3))
1362  goto error_return;
1363 
1364  /* Rule descriptions (ignore rules for views) */
1366  "UNION ALL\n"
1367  " SELECT r.oid as oid, r.tableoid as tableoid,\n"
1368  " n.nspname as nspname,\n"
1369  " CAST(r.rulename AS pg_catalog.text) as name,"
1370  " CAST('%s' AS pg_catalog.text) as object\n"
1371  " FROM pg_catalog.pg_rewrite r\n"
1372  " JOIN pg_catalog.pg_class c ON c.oid = r.ev_class\n"
1373  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
1374  " WHERE r.rulename != '_RETURN'\n",
1375  gettext_noop("rule"));
1376 
1377  if (!showSystem && !pattern)
1378  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1379  " AND n.nspname <> 'information_schema'\n");
1380 
1381  if (!validateSQLNamePattern(&buf, pattern, true, false,
1382  "n.nspname", "r.rulename", NULL,
1383  "pg_catalog.pg_table_is_visible(c.oid)",
1384  NULL, 3))
1385  goto error_return;
1386 
1387  /* Trigger descriptions */
1389  "UNION ALL\n"
1390  " SELECT t.oid as oid, t.tableoid as tableoid,\n"
1391  " n.nspname as nspname,\n"
1392  " CAST(t.tgname AS pg_catalog.text) as name,"
1393  " CAST('%s' AS pg_catalog.text) as object\n"
1394  " FROM pg_catalog.pg_trigger t\n"
1395  " JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid\n"
1396  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n",
1397  gettext_noop("trigger"));
1398 
1399  if (!showSystem && !pattern)
1400  appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1401  " AND n.nspname <> 'information_schema'\n");
1402 
1403  if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
1404  "n.nspname", "t.tgname", NULL,
1405  "pg_catalog.pg_table_is_visible(c.oid)",
1406  NULL, 3))
1407  goto error_return;
1408 
1410  ") AS tt\n"
1411  " JOIN pg_catalog.pg_description d ON (tt.oid = d.objoid AND tt.tableoid = d.classoid AND d.objsubid = 0)\n");
1412 
1413  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1414 
1415  res = PSQLexec(buf.data);
1416  termPQExpBuffer(&buf);
1417  if (!res)
1418  return false;
1419 
1420  myopt.title = _("Object descriptions");
1421  myopt.translate_header = true;
1422  myopt.translate_columns = translate_columns;
1423  myopt.n_translate_columns = lengthof(translate_columns);
1424 
1425  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1426 
1427  PQclear(res);
1428  return true;
1429 
1430 error_return:
1431  termPQExpBuffer(&buf);
1432  return false;
1433 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ permissionsList()

bool permissionsList ( const char *  pattern,
bool  showSystem 
)

Definition at line 1011 of file describe.c.

1012 {
1014  PGresult *res;
1015  printQueryOpt myopt = pset.popt;
1016  static const bool translate_columns[] = {false, false, true, false, false, false};
1017 
1018  initPQExpBuffer(&buf);
1019 
1020  /*
1021  * we ignore indexes and toast tables since they have no meaningful rights
1022  */
1024  "SELECT n.nspname as \"%s\",\n"
1025  " c.relname as \"%s\",\n"
1026  " CASE c.relkind"
1027  " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
1028  " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
1029  " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
1030  " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
1031  " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
1032  " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
1033  " END as \"%s\",\n"
1034  " ",
1035  gettext_noop("Schema"),
1036  gettext_noop("Name"),
1037  gettext_noop("table"),
1038  gettext_noop("view"),
1039  gettext_noop("materialized view"),
1040  gettext_noop("sequence"),
1041  gettext_noop("foreign table"),
1042  gettext_noop("partitioned table"),
1043  gettext_noop("Type"));
1044 
1045  printACLColumn(&buf, "c.relacl");
1046 
1047  /*
1048  * The formatting of attacl should match printACLColumn(). However, we
1049  * need no special case for an empty attacl, because the backend always
1050  * optimizes that back to NULL.
1051  */
1053  ",\n pg_catalog.array_to_string(ARRAY(\n"
1054  " SELECT attname || E':\\n ' || pg_catalog.array_to_string(attacl, E'\\n ')\n"
1055  " FROM pg_catalog.pg_attribute a\n"
1056  " WHERE attrelid = c.oid AND NOT attisdropped AND attacl IS NOT NULL\n"
1057  " ), E'\\n') AS \"%s\"",
1058  gettext_noop("Column privileges"));
1059 
1060  if (pset.sversion >= 90500 && pset.sversion < 100000)
1062  ",\n pg_catalog.array_to_string(ARRAY(\n"
1063  " SELECT polname\n"
1064  " || CASE WHEN polcmd != '*' THEN\n"
1065  " E' (' || polcmd::pg_catalog.text || E'):'\n"
1066  " ELSE E':'\n"
1067  " END\n"
1068  " || CASE WHEN polqual IS NOT NULL THEN\n"
1069  " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
1070  " ELSE E''\n"
1071  " END\n"
1072  " || CASE WHEN polwithcheck IS NOT NULL THEN\n"
1073  " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
1074  " ELSE E''\n"
1075  " END"
1076  " || CASE WHEN polroles <> '{0}' THEN\n"
1077  " E'\\n to: ' || pg_catalog.array_to_string(\n"
1078  " ARRAY(\n"
1079  " SELECT rolname\n"
1080  " FROM pg_catalog.pg_roles\n"
1081  " WHERE oid = ANY (polroles)\n"
1082  " ORDER BY 1\n"
1083  " ), E', ')\n"
1084  " ELSE E''\n"
1085  " END\n"
1086  " FROM pg_catalog.pg_policy pol\n"
1087  " WHERE polrelid = c.oid), E'\\n')\n"
1088  " AS \"%s\"",
1089  gettext_noop("Policies"));
1090 
1091  if (pset.sversion >= 100000)
1093  ",\n pg_catalog.array_to_string(ARRAY(\n"
1094  " SELECT polname\n"
1095  " || CASE WHEN NOT polpermissive THEN\n"
1096  " E' (RESTRICTIVE)'\n"
1097  " ELSE '' END\n"
1098  " || CASE WHEN polcmd != '*' THEN\n"
1099  " E' (' || polcmd::pg_catalog.text || E'):'\n"
1100  " ELSE E':'\n"
1101  " END\n"
1102  " || CASE WHEN polqual IS NOT NULL THEN\n"
1103  " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
1104  " ELSE E''\n"
1105  " END\n"
1106  " || CASE WHEN polwithcheck IS NOT NULL THEN\n"
1107  " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
1108  " ELSE E''\n"
1109  " END"
1110  " || CASE WHEN polroles <> '{0}' THEN\n"
1111  " E'\\n to: ' || pg_catalog.array_to_string(\n"
1112  " ARRAY(\n"
1113  " SELECT rolname\n"
1114  " FROM pg_catalog.pg_roles\n"
1115  " WHERE oid = ANY (polroles)\n"
1116  " ORDER BY 1\n"
1117  " ), E', ')\n"
1118  " ELSE E''\n"
1119  " END\n"
1120  " FROM pg_catalog.pg_policy pol\n"
1121  " WHERE polrelid = c.oid), E'\\n')\n"
1122  " AS \"%s\"",
1123  gettext_noop("Policies"));
1124 
1125  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n"
1126  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
1127  "WHERE c.relkind IN ("
1128  CppAsString2(RELKIND_RELATION) ","
1129  CppAsString2(RELKIND_VIEW) ","
1130  CppAsString2(RELKIND_MATVIEW) ","
1131  CppAsString2(RELKIND_SEQUENCE) ","
1132  CppAsString2(RELKIND_FOREIGN_TABLE) ","
1133  CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
1134 
1135  if (!showSystem && !pattern)
1136  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1137  " AND n.nspname <> 'information_schema'\n");
1138 
1139  if (!validateSQLNamePattern(&buf, pattern, true, false,
1140  "n.nspname", "c.relname", NULL,
1141  "pg_catalog.pg_table_is_visible(c.oid)",
1142  NULL, 3))
1143  goto error_return;
1144 
1145  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
1146 
1147  res = PSQLexec(buf.data);
1148  if (!res)
1149  goto error_return;
1150 
1151  printfPQExpBuffer(&buf, _("Access privileges"));
1152  myopt.title = buf.data;
1153  myopt.translate_header = true;
1154  myopt.translate_columns = translate_columns;
1155  myopt.n_translate_columns = lengthof(translate_columns);
1156 
1157  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1158 
1159  termPQExpBuffer(&buf);
1160  PQclear(res);
1161  return true;
1162 
1163 error_return:
1164  termPQExpBuffer(&buf);
1165  return false;
1166 }

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear(), printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, res, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d(), and exec_command_z().