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:581
#define gettext_noop(x)
Definition: c.h:1209
#define lengthof(array)
Definition: c.h:777
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:6199
#define _(x)
Definition: elog.c:91
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 4585 of file describe.c.

4587 {
4589  PGresult *res;
4590  printQueryOpt myopt = pset.popt;
4591 
4592  initPQExpBuffer(&buf);
4594  "SELECT s.name AS \"%s\", "
4595  "pg_catalog.current_setting(s.name) AS \"%s\"",
4596  gettext_noop("Parameter"),
4597  gettext_noop("Value"));
4598 
4599  if (verbose)
4600  {
4602  ", s.vartype AS \"%s\", s.context AS \"%s\", ",
4603  gettext_noop("Type"),
4604  gettext_noop("Context"));
4605  if (pset.sversion >= 150000)
4606  printACLColumn(&buf, "p.paracl");
4607  else
4608  appendPQExpBuffer(&buf, "NULL AS \"%s\"",
4609  gettext_noop("Access privileges"));
4610  }
4611 
4612  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_settings s\n");
4613 
4614  if (verbose && pset.sversion >= 150000)
4616  " LEFT JOIN pg_catalog.pg_parameter_acl p\n"
4617  " ON pg_catalog.lower(s.name) = p.parname\n");
4618 
4619  if (pattern)
4620  processSQLNamePattern(pset.db, &buf, pattern,
4621  false, false,
4622  NULL, "pg_catalog.lower(s.name)", NULL,
4623  NULL, NULL, NULL);
4624  else
4625  appendPQExpBufferStr(&buf, "WHERE s.source <> 'default' AND\n"
4626  " s.setting IS DISTINCT FROM s.boot_val\n");
4627 
4628  appendPQExpBufferStr(&buf, "ORDER BY 1;");
4629 
4630  res = PSQLexec(buf.data);
4631  termPQExpBuffer(&buf);
4632  if (!res)
4633  return false;
4634 
4635  if (pattern)
4636  myopt.title = _("List of configuration parameters");
4637  else
4638  myopt.title = _("List of non-default configuration parameters");
4639  myopt.translate_header = true;
4640 
4641  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4642 
4643  PQclear(res);
4644  return true;
4645 }
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:6688
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 6374 of file describe.c.

6375 {
6377  int i;
6378  PGresult *res;
6379  bool has_pubtruncate;
6380  bool has_pubviaroot;
6381 
6382  PQExpBufferData title;
6383  printTableContent cont;
6384 
6385  if (pset.sversion < 100000)
6386  {
6387  char sverbuf[32];
6388 
6389  pg_log_error("The server (version %s) does not support publications.",
6391  sverbuf, sizeof(sverbuf)));
6392  return true;
6393  }
6394 
6395  has_pubtruncate = (pset.sversion >= 110000);
6396  has_pubviaroot = (pset.sversion >= 130000);
6397 
6398  initPQExpBuffer(&buf);
6399 
6401  "SELECT oid, pubname,\n"
6402  " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n"
6403  " puballtables, pubinsert, pubupdate, pubdelete");
6404  if (has_pubtruncate)
6406  ", pubtruncate");
6407  if (has_pubviaroot)
6409  ", pubviaroot");
6411  "\nFROM pg_catalog.pg_publication\n");
6412 
6413  if (!validateSQLNamePattern(&buf, pattern, false, false,
6414  NULL, "pubname", NULL,
6415  NULL,
6416  NULL, 1))
6417  {
6418  termPQExpBuffer(&buf);
6419  return false;
6420  }
6421 
6422  appendPQExpBufferStr(&buf, "ORDER BY 2;");
6423 
6424  res = PSQLexec(buf.data);
6425  if (!res)
6426  {
6427  termPQExpBuffer(&buf);
6428  return false;
6429  }
6430 
6431  if (PQntuples(res) == 0)
6432  {
6433  if (!pset.quiet)
6434  {
6435  if (pattern)
6436  pg_log_error("Did not find any publication named \"%s\".",
6437  pattern);
6438  else
6439  pg_log_error("Did not find any publications.");
6440  }
6441 
6442  termPQExpBuffer(&buf);
6443  PQclear(res);
6444  return false;
6445  }
6446 
6447  for (i = 0; i < PQntuples(res); i++)
6448  {
6449  const char align = 'l';
6450  int ncols = 5;
6451  int nrows = 1;
6452  char *pubid = PQgetvalue(res, i, 0);
6453  char *pubname = PQgetvalue(res, i, 1);
6454  bool puballtables = strcmp(PQgetvalue(res, i, 3), "t") == 0;
6455  printTableOpt myopt = pset.popt.topt;
6456 
6457  if (has_pubtruncate)
6458  ncols++;
6459  if (has_pubviaroot)
6460  ncols++;
6461 
6462  initPQExpBuffer(&title);
6463  printfPQExpBuffer(&title, _("Publication %s"), pubname);
6464  printTableInit(&cont, &myopt, title.data, ncols, nrows);
6465 
6466  printTableAddHeader(&cont, gettext_noop("Owner"), true, align);
6467  printTableAddHeader(&cont, gettext_noop("All tables"), true, align);
6468  printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
6469  printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
6470  printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
6471  if (has_pubtruncate)
6472  printTableAddHeader(&cont, gettext_noop("Truncates"), true, align);
6473  if (has_pubviaroot)
6474  printTableAddHeader(&cont, gettext_noop("Via root"), true, align);
6475 
6476  printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
6477  printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
6478  printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
6479  printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
6480  printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
6481  if (has_pubtruncate)
6482  printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
6483  if (has_pubviaroot)
6484  printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
6485 
6486  if (!puballtables)
6487  {
6488  /* Get the tables for the specified publication */
6490  "SELECT n.nspname, c.relname");
6491  if (pset.sversion >= 150000)
6492  {
6494  ", pg_get_expr(pr.prqual, c.oid)");
6496  ", (CASE WHEN pr.prattrs IS NOT NULL THEN\n"
6497  " pg_catalog.array_to_string("
6498  " ARRAY(SELECT attname\n"
6499  " FROM\n"
6500  " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
6501  " pg_catalog.pg_attribute\n"
6502  " WHERE attrelid = c.oid AND attnum = prattrs[s]), ', ')\n"
6503  " ELSE NULL END)");
6504  }
6505  else
6507  ", NULL, NULL");
6509  "\nFROM pg_catalog.pg_class c,\n"
6510  " pg_catalog.pg_namespace n,\n"
6511  " pg_catalog.pg_publication_rel pr\n"
6512  "WHERE c.relnamespace = n.oid\n"
6513  " AND c.oid = pr.prrelid\n"
6514  " AND pr.prpubid = '%s'\n"
6515  "ORDER BY 1,2", pubid);
6516  if (!addFooterToPublicationDesc(&buf, _("Tables:"), false, &cont))
6517  goto error_return;
6518 
6519  if (pset.sversion >= 150000)
6520  {
6521  /* Get the schemas for the specified publication */
6523  "SELECT n.nspname\n"
6524  "FROM pg_catalog.pg_namespace n\n"
6525  " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n"
6526  "WHERE pn.pnpubid = '%s'\n"
6527  "ORDER BY 1", pubid);
6528  if (!addFooterToPublicationDesc(&buf, _("Tables from schemas:"),
6529  true, &cont))
6530  goto error_return;
6531  }
6532  }
6533 
6534  printTable(&cont, pset.queryFout, false, pset.logfile);
6535  printTableCleanup(&cont);
6536 
6537  termPQExpBuffer(&title);
6538  }
6539 
6540  termPQExpBuffer(&buf);
6541  PQclear(res);
6542 
6543  return true;
6544 
6545 error_return:
6546  printTableCleanup(&cont);
6547  PQclear(res);
6548  termPQExpBuffer(&buf);
6549  termPQExpBuffer(&title);
6550  return false;
6551 }
static bool addFooterToPublicationDesc(PQExpBuffer buf, const char *footermsg, bool as_schema, printTableContent *const cont)
Definition: describe.c:6328
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3422
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3817
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 3869 of file describe.c.

3870 {
3872  PGresult *res;
3873  printQueryOpt myopt = pset.popt;
3874 
3875  initPQExpBuffer(&buf);
3877  "SELECT m.rolname AS \"%s\", r.rolname AS \"%s\",\n"
3878  " pg_catalog.concat_ws(', ',\n",
3879  gettext_noop("Role name"),
3880  gettext_noop("Member of"));
3881 
3882  if (pset.sversion >= 160000)
3884  " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3885  " CASE WHEN pam.inherit_option THEN 'INHERIT' END,\n"
3886  " CASE WHEN pam.set_option THEN 'SET' END\n");
3887  else
3889  " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3890  " CASE WHEN m.rolinherit THEN 'INHERIT' END,\n"
3891  " 'SET'\n");
3892 
3894  " ) AS \"%s\",\n"
3895  " g.rolname AS \"%s\"\n",
3896  gettext_noop("Options"),
3897  gettext_noop("Grantor"));
3898 
3900  "FROM pg_catalog.pg_roles m\n"
3901  " JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)\n"
3902  " LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)\n"
3903  " LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)\n");
3904 
3905  if (!showSystem && !pattern)
3906  appendPQExpBufferStr(&buf, "WHERE m.rolname !~ '^pg_'\n");
3907 
3908  if (!validateSQLNamePattern(&buf, pattern, false, false,
3909  NULL, "m.rolname", NULL, NULL,
3910  NULL, 1))
3911  {
3912  termPQExpBuffer(&buf);
3913  return false;
3914  }
3915 
3916  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;\n");
3917 
3918  res = PSQLexec(buf.data);
3919  termPQExpBuffer(&buf);
3920  if (!res)
3921  return false;
3922 
3923  myopt.title = _("List of role grants");
3924  myopt.translate_header = true;
3925 
3926  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3927 
3928  PQclear(res);
3929  return true;
3930 }

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

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

6561 {
6563  PGresult *res;
6564  printQueryOpt myopt = pset.popt;
6565  static const bool translate_columns[] = {false, false, false, false,
6566  false, false, false, false, false, false, false, false, false, false};
6567 
6568  if (pset.sversion < 100000)
6569  {
6570  char sverbuf[32];
6571 
6572  pg_log_error("The server (version %s) does not support subscriptions.",
6574  sverbuf, sizeof(sverbuf)));
6575  return true;
6576  }
6577 
6578  initPQExpBuffer(&buf);
6579 
6581  "SELECT subname AS \"%s\"\n"
6582  ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
6583  ", subenabled AS \"%s\"\n"
6584  ", subpublications AS \"%s\"\n",
6585  gettext_noop("Name"),
6586  gettext_noop("Owner"),
6587  gettext_noop("Enabled"),
6588  gettext_noop("Publication"));
6589 
6590  if (verbose)
6591  {
6592  /* Binary mode and streaming are only supported in v14 and higher */
6593  if (pset.sversion >= 140000)
6594  {
6596  ", subbinary AS \"%s\"\n",
6597  gettext_noop("Binary"));
6598 
6599  if (pset.sversion >= 160000)
6601  ", (CASE substream\n"
6602  " WHEN 'f' THEN 'off'\n"
6603  " WHEN 't' THEN 'on'\n"
6604  " WHEN 'p' THEN 'parallel'\n"
6605  " END) AS \"%s\"\n",
6606  gettext_noop("Streaming"));
6607  else
6609  ", substream AS \"%s\"\n",
6610  gettext_noop("Streaming"));
6611  }
6612 
6613  /* Two_phase and disable_on_error are only supported in v15 and higher */
6614  if (pset.sversion >= 150000)
6616  ", subtwophasestate AS \"%s\"\n"
6617  ", subdisableonerr AS \"%s\"\n",
6618  gettext_noop("Two-phase commit"),
6619  gettext_noop("Disable on error"));
6620 
6621  if (pset.sversion >= 160000)
6623  ", suborigin AS \"%s\"\n"
6624  ", subpasswordrequired AS \"%s\"\n"
6625  ", subrunasowner AS \"%s\"\n",
6626  gettext_noop("Origin"),
6627  gettext_noop("Password required"),
6628  gettext_noop("Run as owner?"));
6629 
6631  ", subsynccommit AS \"%s\"\n"
6632  ", subconninfo AS \"%s\"\n",
6633  gettext_noop("Synchronous commit"),
6634  gettext_noop("Conninfo"));
6635 
6636  /* Skip LSN is only supported in v15 and higher */
6637  if (pset.sversion >= 150000)
6639  ", subskiplsn AS \"%s\"\n",
6640  gettext_noop("Skip LSN"));
6641  }
6642 
6643  /* Only display subscriptions in current database. */
6645  "FROM pg_catalog.pg_subscription\n"
6646  "WHERE subdbid = (SELECT oid\n"
6647  " FROM pg_catalog.pg_database\n"
6648  " WHERE datname = pg_catalog.current_database())");
6649 
6650  if (!validateSQLNamePattern(&buf, pattern, true, false,
6651  NULL, "subname", NULL,
6652  NULL,
6653  NULL, 1))
6654  {
6655  termPQExpBuffer(&buf);
6656  return false;
6657  }
6658 
6659  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6660 
6661  res = PSQLexec(buf.data);
6662  termPQExpBuffer(&buf);
6663  if (!res)
6664  return false;
6665 
6666  myopt.title = _("List of subscriptions");
6667  myopt.translate_header = true;
6668  myopt.translate_columns = translate_columns;
6669  myopt.n_translate_columns = lengthof(translate_columns);
6670 
6671  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6672 
6673  PQclear(res);
6674  return true;
6675 }

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

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

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 '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 >= 150000)
942  " d.daticulocale as \"%s\",\n",
943  gettext_noop("ICU Locale"));
944  else
946  " NULL as \"%s\",\n",
947  gettext_noop("ICU Locale"));
948  if (pset.sversion >= 160000)
950  " d.daticurules as \"%s\",\n",
951  gettext_noop("ICU Rules"));
952  else
954  " NULL as \"%s\",\n",
955  gettext_noop("ICU Rules"));
956  appendPQExpBufferStr(&buf, " ");
957  printACLColumn(&buf, "d.datacl");
958  if (verbose)
960  ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
961  " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
962  " ELSE 'No Access'\n"
963  " END as \"%s\""
964  ",\n t.spcname as \"%s\""
965  ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
966  gettext_noop("Size"),
967  gettext_noop("Tablespace"),
968  gettext_noop("Description"));
970  "\nFROM pg_catalog.pg_database d\n");
971  if (verbose)
973  " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
974 
975  if (pattern)
976  {
977  if (!validateSQLNamePattern(&buf, pattern, false, false,
978  NULL, "d.datname", NULL, NULL,
979  NULL, 1))
980  {
982  return false;
983  }
984  }
985 
986  appendPQExpBufferStr(&buf, "ORDER BY 1;");
987  res = PSQLexec(buf.data);
989  if (!res)
990  return false;
991 
992  myopt.title = _("List of databases");
993  myopt.translate_header = true;
994 
995  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
996 
997  PQclear(res);
998  return true;
999 }

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

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

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

4948 {
4950  PGresult *res;
4951  printQueryOpt myopt = pset.popt;
4952  static const bool translate_columns[] = {false, false, false, false, false, false, false, true, false};
4953 
4954  initPQExpBuffer(&buf);
4955 
4957  "SELECT\n"
4958  " n.nspname AS \"%s\",\n"
4959  " c.collname AS \"%s\",\n",
4960  gettext_noop("Schema"),
4961  gettext_noop("Name"));
4962 
4963  if (pset.sversion >= 100000)
4965  " CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \"%s\",\n",
4966  gettext_noop("Provider"));
4967  else
4969  " 'libc' AS \"%s\",\n",
4970  gettext_noop("Provider"));
4971 
4973  " c.collcollate AS \"%s\",\n"
4974  " c.collctype AS \"%s\",\n",
4975  gettext_noop("Collate"),
4976  gettext_noop("Ctype"));
4977 
4978  if (pset.sversion >= 150000)
4980  " c.colliculocale AS \"%s\",\n",
4981  gettext_noop("ICU Locale"));
4982  else
4984  " c.collcollate AS \"%s\",\n",
4985  gettext_noop("ICU Locale"));
4986 
4987  if (pset.sversion >= 160000)
4989  " c.collicurules AS \"%s\",\n",
4990  gettext_noop("ICU Rules"));
4991  else
4993  " NULL AS \"%s\",\n",
4994  gettext_noop("ICU Rules"));
4995 
4996  if (pset.sversion >= 120000)
4998  " CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \"%s\"",
4999  gettext_noop("yes"), gettext_noop("no"),
5000  gettext_noop("Deterministic?"));
5001  else
5003  " '%s' AS \"%s\"",
5004  gettext_noop("yes"),
5005  gettext_noop("Deterministic?"));
5006 
5007  if (verbose)
5009  ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
5010  gettext_noop("Description"));
5011 
5013  "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
5014  "WHERE n.oid = c.collnamespace\n");
5015 
5016  if (!showSystem && !pattern)
5017  appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
5018  " AND n.nspname <> 'information_schema'\n");
5019 
5020  /*
5021  * Hide collations that aren't usable in the current database's encoding.
5022  * If you think to change this, note that pg_collation_is_visible rejects
5023  * unusable collations, so you will need to hack name pattern processing
5024  * somehow to avoid inconsistent behavior.
5025  */
5026  appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
5027 
5028  if (!validateSQLNamePattern(&buf, pattern, true, false,
5029  "n.nspname", "c.collname", NULL,
5030  "pg_catalog.pg_collation_is_visible(c.oid)",
5031  NULL, 3))
5032  {
5033  termPQExpBuffer(&buf);
5034  return false;
5035  }
5036 
5037  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5038 
5039  res = PSQLexec(buf.data);
5040  termPQExpBuffer(&buf);
5041  if (!res)
5042  return false;
5043 
5044  myopt.title = _("List of collations");
5045  myopt.translate_header = true;
5046  myopt.translate_columns = translate_columns;
5047  myopt.n_translate_columns = lengthof(translate_columns);
5048 
5049  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5050 
5051  PQclear(res);
5052  return true;
5053 }

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

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

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

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

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

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

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

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

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

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

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

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

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

6089 {
6091  PGresult *res;
6092  int i;
6093 
6094  initPQExpBuffer(&buf);
6096  "SELECT e.extname, e.oid\n"
6097  "FROM pg_catalog.pg_extension e\n");
6098 
6099  if (!validateSQLNamePattern(&buf, pattern,
6100  false, false,
6101  NULL, "e.extname", NULL,
6102  NULL,
6103  NULL, 1))
6104  {
6105  termPQExpBuffer(&buf);
6106  return false;
6107  }
6108 
6109  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6110 
6111  res = PSQLexec(buf.data);
6112  termPQExpBuffer(&buf);
6113  if (!res)
6114  return false;
6115 
6116  if (PQntuples(res) == 0)
6117  {
6118  if (!pset.quiet)
6119  {
6120  if (pattern)
6121  pg_log_error("Did not find any extension named \"%s\".",
6122  pattern);
6123  else
6124  pg_log_error("Did not find any extensions.");
6125  }
6126  PQclear(res);
6127  return false;
6128  }
6129 
6130  for (i = 0; i < PQntuples(res); i++)
6131  {
6132  const char *extname;
6133  const char *oid;
6134 
6135  extname = PQgetvalue(res, i, 0);
6136  oid = PQgetvalue(res, i, 1);
6137 
6138  if (!listOneExtensionContents(extname, oid))
6139  {
6140  PQclear(res);
6141  return false;
6142  }
6143  if (cancel_pressed)
6144  {
6145  PQclear(res);
6146  return false;
6147  }
6148  }
6149 
6150  PQclear(res);
6151  return true;
6152 }
static bool listOneExtensionContents(const char *extname, const char *oid)
Definition: describe.c:6155

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

6038 {
6040  PGresult *res;
6041  printQueryOpt myopt = pset.popt;
6042 
6043  initPQExpBuffer(&buf);
6045  "SELECT e.extname AS \"%s\", "
6046  "e.extversion AS \"%s\", n.nspname AS \"%s\", c.description AS \"%s\"\n"
6047  "FROM pg_catalog.pg_extension e "
6048  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
6049  "LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid "
6050  "AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass\n",
6051  gettext_noop("Name"),
6052  gettext_noop("Version"),
6053  gettext_noop("Schema"),
6054  gettext_noop("Description"));
6055 
6056  if (!validateSQLNamePattern(&buf, pattern,
6057  false, false,
6058  NULL, "e.extname", NULL,
6059  NULL,
6060  NULL, 1))
6061  {
6062  termPQExpBuffer(&buf);
6063  return false;
6064  }
6065 
6066  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6067 
6068  res = PSQLexec(buf.data);
6069  termPQExpBuffer(&buf);
6070  if (!res)
6071  return false;
6072 
6073  myopt.title = _("List of installed extensions");
6074  myopt.translate_header = true;
6075 
6076  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6077 
6078  PQclear(res);
6079  return true;
6080 }

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

5764 {
5766  PGresult *res;
5767  printQueryOpt myopt = pset.popt;
5768 
5769  initPQExpBuffer(&buf);
5771  "SELECT fdw.fdwname AS \"%s\",\n"
5772  " pg_catalog.pg_get_userbyid(fdw.fdwowner) AS \"%s\",\n"
5773  " fdw.fdwhandler::pg_catalog.regproc AS \"%s\",\n"
5774  " fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
5775  gettext_noop("Name"),
5776  gettext_noop("Owner"),
5777  gettext_noop("Handler"),
5778  gettext_noop("Validator"));
5779 
5780  if (verbose)
5781  {
5782  appendPQExpBufferStr(&buf, ",\n ");
5783  printACLColumn(&buf, "fdwacl");
5785  ",\n CASE WHEN fdwoptions IS NULL THEN '' ELSE "
5786  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5787  " pg_catalog.quote_ident(option_name) || ' ' || "
5788  " pg_catalog.quote_literal(option_value) FROM "
5789  " pg_catalog.pg_options_to_table(fdwoptions)), ', ') || ')' "
5790  " END AS \"%s\""
5791  ",\n d.description AS \"%s\" ",
5792  gettext_noop("FDW options"),
5793  gettext_noop("Description"));
5794  }
5795 
5796  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
5797 
5798  if (verbose)
5800  "LEFT JOIN pg_catalog.pg_description d\n"
5801  " ON d.classoid = fdw.tableoid "
5802  "AND d.objoid = fdw.oid AND d.objsubid = 0\n");
5803 
5804  if (!validateSQLNamePattern(&buf, pattern, false, false,
5805  NULL, "fdwname", NULL, NULL,
5806  NULL, 1))
5807  {
5808  termPQExpBuffer(&buf);
5809  return false;
5810  }
5811 
5812  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5813 
5814  res = PSQLexec(buf.data);
5815  termPQExpBuffer(&buf);
5816  if (!res)
5817  return false;
5818 
5819  myopt.title = _("List of foreign-data wrappers");
5820  myopt.translate_header = true;
5821 
5822  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5823 
5824  PQclear(res);
5825  return true;
5826 }

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

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

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

5966 {
5968  PGresult *res;
5969  printQueryOpt myopt = pset.popt;
5970 
5971  initPQExpBuffer(&buf);
5973  "SELECT n.nspname AS \"%s\",\n"
5974  " c.relname AS \"%s\",\n"
5975  " s.srvname AS \"%s\"",
5976  gettext_noop("Schema"),
5977  gettext_noop("Table"),
5978  gettext_noop("Server"));
5979 
5980  if (verbose)
5982  ",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
5983  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5984  " pg_catalog.quote_ident(option_name) || ' ' || "
5985  " pg_catalog.quote_literal(option_value) FROM "
5986  " pg_catalog.pg_options_to_table(ftoptions)), ', ') || ')' "
5987  " END AS \"%s\",\n"
5988  " d.description AS \"%s\"",
5989  gettext_noop("FDW options"),
5990  gettext_noop("Description"));
5991 
5993  "\nFROM pg_catalog.pg_foreign_table ft\n"
5994  " INNER JOIN pg_catalog.pg_class c"
5995  " ON c.oid = ft.ftrelid\n"
5996  " INNER JOIN pg_catalog.pg_namespace n"
5997  " ON n.oid = c.relnamespace\n"
5998  " INNER JOIN pg_catalog.pg_foreign_server s"
5999  " ON s.oid = ft.ftserver\n");
6000  if (verbose)
6002  " LEFT JOIN pg_catalog.pg_description d\n"
6003  " ON d.classoid = c.tableoid AND "
6004  "d.objoid = c.oid AND d.objsubid = 0\n");
6005 
6006  if (!validateSQLNamePattern(&buf, pattern, false, false,
6007  "n.nspname", "c.relname", NULL,
6008  "pg_catalog.pg_table_is_visible(c.oid)",
6009  NULL, 3))
6010  {
6011  termPQExpBuffer(&buf);
6012  return false;
6013  }
6014 
6015  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6016 
6017  res = PSQLexec(buf.data);
6018  termPQExpBuffer(&buf);
6019  if (!res)
6020  return false;
6021 
6022  myopt.title = _("List of foreign tables");
6023  myopt.translate_header = true;
6024 
6025  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6026 
6027  PQclear(res);
6028  return true;
6029 }

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

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

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

7084 {
7086  PGresult *res;
7087  printQueryOpt myopt = pset.popt;
7088 
7089  initPQExpBuffer(&buf);
7090 
7092  "SELECT oid as \"%s\",\n"
7093  " pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n ",
7094  gettext_noop("ID"),
7095  gettext_noop("Owner"));
7096 
7097  if (verbose)
7098  {
7099  printACLColumn(&buf, "lomacl");
7100  appendPQExpBufferStr(&buf, ",\n ");
7101  }
7102 
7104  "pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
7105  "FROM pg_catalog.pg_largeobject_metadata\n"
7106  "ORDER BY oid",
7107  gettext_noop("Description"));
7108 
7109  res = PSQLexec(buf.data);
7110  termPQExpBuffer(&buf);
7111  if (!res)
7112  return false;
7113 
7114  myopt.title = _("Large objects");
7115  myopt.translate_header = true;
7116 
7117  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7118 
7119  PQclear(res);
7120  return true;
7121 }

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

6708 {
6710  PGresult *res;
6711  printQueryOpt myopt = pset.popt;
6712  bool have_where = false;
6713  static const bool translate_columns[] = {false, false, false, false, false, false, false};
6714 
6715  initPQExpBuffer(&buf);
6716 
6718  "SELECT\n"
6719  " am.amname AS \"%s\",\n"
6720  " pg_catalog.format_type(c.opcintype, NULL) AS \"%s\",\n"
6721  " CASE\n"
6722  " WHEN c.opckeytype <> 0 AND c.opckeytype <> c.opcintype\n"
6723  " THEN pg_catalog.format_type(c.opckeytype, NULL)\n"
6724  " ELSE NULL\n"
6725  " END AS \"%s\",\n"
6726  " CASE\n"
6727  " WHEN pg_catalog.pg_opclass_is_visible(c.oid)\n"
6728  " THEN pg_catalog.format('%%I', c.opcname)\n"
6729  " ELSE pg_catalog.format('%%I.%%I', n.nspname, c.opcname)\n"
6730  " END AS \"%s\",\n"
6731  " (CASE WHEN c.opcdefault\n"
6732  " THEN '%s'\n"
6733  " ELSE '%s'\n"
6734  " END) AS \"%s\"",
6735  gettext_noop("AM"),
6736  gettext_noop("Input type"),
6737  gettext_noop("Storage type"),
6738  gettext_noop("Operator class"),
6739  gettext_noop("yes"),
6740  gettext_noop("no"),
6741  gettext_noop("Default?"));
6742  if (verbose)
6744  ",\n CASE\n"
6745  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
6746  " THEN pg_catalog.format('%%I', of.opfname)\n"
6747  " ELSE pg_catalog.format('%%I.%%I', ofn.nspname, of.opfname)\n"
6748  " END AS \"%s\",\n"
6749  " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n",
6750  gettext_noop("Operator family"),
6751  gettext_noop("Owner"));
6753  "\nFROM pg_catalog.pg_opclass c\n"
6754  " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n"
6755  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
6756  " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
6757  " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
6758  if (verbose)
6760  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
6761  " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
6762 
6763  if (access_method_pattern)
6764  if (!validateSQLNamePattern(&buf, access_method_pattern,
6765  false, false, NULL, "am.amname", NULL, NULL,
6766  &have_where, 1))
6767  goto error_return;
6768  if (type_pattern)
6769  {
6770  /* Match type name pattern against either internal or external name */
6771  if (!validateSQLNamePattern(&buf, type_pattern, have_where, false,
6772  "tn.nspname", "t.typname",
6773  "pg_catalog.format_type(t.oid, NULL)",
6774  "pg_catalog.pg_type_is_visible(t.oid)",
6775  NULL, 3))
6776  goto error_return;
6777  }
6778 
6779  appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
6780  res = PSQLexec(buf.data);
6781  termPQExpBuffer(&buf);
6782  if (!res)
6783  return false;
6784 
6785  myopt.title = _("List of operator classes");
6786  myopt.translate_header = true;
6787  myopt.translate_columns = translate_columns;
6788  myopt.n_translate_columns = lengthof(translate_columns);
6789 
6790  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6791 
6792  PQclear(res);
6793  return true;
6794 
6795 error_return:
6796  termPQExpBuffer(&buf);
6797  return false;
6798 }

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

6809 {
6811  PGresult *res;
6812  printQueryOpt myopt = pset.popt;
6813  bool have_where = false;
6814  static const bool translate_columns[] = {false, false, false, false};
6815 
6816  initPQExpBuffer(&buf);
6817 
6819  "SELECT\n"
6820  " am.amname AS \"%s\",\n"
6821  " CASE\n"
6822  " WHEN pg_catalog.pg_opfamily_is_visible(f.oid)\n"
6823  " THEN pg_catalog.format('%%I', f.opfname)\n"
6824  " ELSE pg_catalog.format('%%I.%%I', n.nspname, f.opfname)\n"
6825  " END AS \"%s\",\n"
6826  " (SELECT\n"
6827  " pg_catalog.string_agg(pg_catalog.format_type(oc.opcintype, NULL), ', ')\n"
6828  " FROM pg_catalog.pg_opclass oc\n"
6829  " WHERE oc.opcfamily = f.oid) \"%s\"",
6830  gettext_noop("AM"),
6831  gettext_noop("Operator family"),
6832  gettext_noop("Applicable types"));
6833  if (verbose)
6835  ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
6836  gettext_noop("Owner"));
6838  "\nFROM pg_catalog.pg_opfamily f\n"
6839  " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n"
6840  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n");
6841 
6842  if (access_method_pattern)
6843  if (!validateSQLNamePattern(&buf, access_method_pattern,
6844  false, false, NULL, "am.amname", NULL, NULL,
6845  &have_where, 1))
6846  goto error_return;
6847  if (type_pattern)
6848  {
6850  " %s EXISTS (\n"
6851  " SELECT 1\n"
6852  " FROM pg_catalog.pg_type t\n"
6853  " JOIN pg_catalog.pg_opclass oc ON oc.opcintype = t.oid\n"
6854  " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"
6855  " WHERE oc.opcfamily = f.oid\n",
6856  have_where ? "AND" : "WHERE");
6857  /* Match type name pattern against either internal or external name */
6858  if (!validateSQLNamePattern(&buf, type_pattern, true, false,
6859  "tn.nspname", "t.typname",
6860  "pg_catalog.format_type(t.oid, NULL)",
6861  "pg_catalog.pg_type_is_visible(t.oid)",
6862  NULL, 3))
6863  goto error_return;
6864  appendPQExpBufferStr(&buf, " )\n");
6865  }
6866 
6867  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6868  res = PSQLexec(buf.data);
6869  termPQExpBuffer(&buf);
6870  if (!res)
6871  return false;
6872 
6873  myopt.title = _("List of operator families");
6874  myopt.translate_header = true;
6875  myopt.translate_columns = translate_columns;
6876  myopt.n_translate_columns = lengthof(translate_columns);
6877 
6878  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6879 
6880  PQclear(res);
6881  return true;
6882 
6883 error_return:
6884  termPQExpBuffer(&buf);
6885  return false;
6886 }

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

6996 {
6998  PGresult *res;
6999  printQueryOpt myopt = pset.popt;
7000  bool have_where = false;
7001  static const bool translate_columns[] = {false, false, false, false, false, false};
7002 
7003  initPQExpBuffer(&buf);
7004 
7006  "SELECT\n"
7007  " am.amname AS \"%s\",\n"
7008  " CASE\n"
7009  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7010  " THEN pg_catalog.format('%%I', of.opfname)\n"
7011  " ELSE pg_catalog.format('%%I.%%I', ns.nspname, of.opfname)\n"
7012  " END AS \"%s\",\n"
7013  " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n"
7014  " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n"
7015  " ap.amprocnum AS \"%s\"\n",
7016  gettext_noop("AM"),
7017  gettext_noop("Operator family"),
7018  gettext_noop("Registered left type"),
7019  gettext_noop("Registered right type"),
7020  gettext_noop("Number"));
7021 
7022  if (!verbose)
7024  ", p.proname AS \"%s\"\n",
7025  gettext_noop("Function"));
7026  else
7028  ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n",
7029  gettext_noop("Function"));
7030 
7032  "FROM pg_catalog.pg_amproc ap\n"
7033  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n"
7034  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n"
7035  " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n"
7036  " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
7037 
7038  if (access_method_pattern)
7039  {
7040  if (!validateSQLNamePattern(&buf, access_method_pattern,
7041  false, false, NULL, "am.amname",
7042  NULL, NULL,
7043  &have_where, 1))
7044  goto error_return;
7045  }
7046  if (family_pattern)
7047  {
7048  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
7049  "ns.nspname", "of.opfname", NULL, NULL,
7050  NULL, 3))
7051  goto error_return;
7052  }
7053 
7054  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7055  " ap.amproclefttype = ap.amprocrighttype DESC,\n"
7056  " 3, 4, 5;");
7057 
7058  res = PSQLexec(buf.data);
7059  termPQExpBuffer(&buf);
7060  if (!res)
7061  return false;
7062 
7063  myopt.title = _("List of support functions of operator families");
7064  myopt.translate_header = true;
7065  myopt.translate_columns = translate_columns;
7066  myopt.n_translate_columns = lengthof(translate_columns);
7067 
7068  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7069 
7070  PQclear(res);
7071  return true;
7072 
7073 error_return:
7074  termPQExpBuffer(&buf);
7075  return false;
7076 }

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

6898 {
6900  PGresult *res;
6901  printQueryOpt myopt = pset.popt;
6902  bool have_where = false;
6903 
6904  static const bool translate_columns[] = {false, false, false, false, false, false};
6905 
6906  initPQExpBuffer(&buf);
6907 
6909  "SELECT\n"
6910  " am.amname AS \"%s\",\n"
6911  " CASE\n"
6912  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
6913  " THEN pg_catalog.format('%%I', of.opfname)\n"
6914  " ELSE pg_catalog.format('%%I.%%I', nsf.nspname, of.opfname)\n"
6915  " END AS \"%s\",\n"
6916  " o.amopopr::pg_catalog.regoperator AS \"%s\"\n,"
6917  " o.amopstrategy AS \"%s\",\n"
6918  " CASE o.amoppurpose\n"
6919  " WHEN 'o' THEN '%s'\n"
6920  " WHEN 's' THEN '%s'\n"
6921  " END AS \"%s\"\n",
6922  gettext_noop("AM"),
6923  gettext_noop("Operator family"),
6924  gettext_noop("Operator"),
6925  gettext_noop("Strategy"),
6926  gettext_noop("ordering"),
6927  gettext_noop("search"),
6928  gettext_noop("Purpose"));
6929 
6930  if (verbose)
6932  ", ofs.opfname AS \"%s\"\n",
6933  gettext_noop("Sort opfamily"));
6935  "FROM pg_catalog.pg_amop o\n"
6936  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
6937  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
6938  " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
6939  if (verbose)
6941  " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
6942 
6943  if (access_method_pattern)
6944  {
6945  if (!validateSQLNamePattern(&buf, access_method_pattern,
6946  false, false, NULL, "am.amname",
6947  NULL, NULL,
6948  &have_where, 1))
6949  goto error_return;
6950  }
6951 
6952  if (family_pattern)
6953  {
6954  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
6955  "nsf.nspname", "of.opfname", NULL, NULL,
6956  NULL, 3))
6957  goto error_return;
6958  }
6959 
6960  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
6961  " o.amoplefttype = o.amoprighttype DESC,\n"
6962  " pg_catalog.format_type(o.amoplefttype, NULL),\n"
6963  " pg_catalog.format_type(o.amoprighttype, NULL),\n"
6964  " o.amopstrategy;");
6965 
6966  res = PSQLexec(buf.data);
6967  termPQExpBuffer(&buf);
6968  if (!res)
6969  return false;
6970 
6971  myopt.title = _("List of operators of operator families");
6972  myopt.translate_header = true;
6973  myopt.translate_columns = translate_columns;
6974  myopt.n_translate_columns = lengthof(translate_columns);
6975 
6976  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6977 
6978  PQclear(res);
6979  return true;
6980 
6981 error_return:
6982  termPQExpBuffer(&buf);
6983  return false;
6984 }

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

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

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

6253 {
6255  PGresult *res;
6256  printQueryOpt myopt = pset.popt;
6257  static const bool translate_columns[] = {false, false, false, false, false, false, false, false};
6258 
6259  if (pset.sversion < 100000)
6260  {
6261  char sverbuf[32];
6262 
6263  pg_log_error("The server (version %s) does not support publications.",
6265  sverbuf, sizeof(sverbuf)));
6266  return true;
6267  }
6268 
6269  initPQExpBuffer(&buf);
6270 
6272  "SELECT pubname AS \"%s\",\n"
6273  " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n"
6274  " puballtables AS \"%s\",\n"
6275  " pubinsert AS \"%s\",\n"
6276  " pubupdate AS \"%s\",\n"
6277  " pubdelete AS \"%s\"",
6278  gettext_noop("Name"),
6279  gettext_noop("Owner"),
6280  gettext_noop("All tables"),
6281  gettext_noop("Inserts"),
6282  gettext_noop("Updates"),
6283  gettext_noop("Deletes"));
6284  if (pset.sversion >= 110000)
6286  ",\n pubtruncate AS \"%s\"",
6287  gettext_noop("Truncates"));
6288  if (pset.sversion >= 130000)
6290  ",\n pubviaroot AS \"%s\"",
6291  gettext_noop("Via root"));
6292 
6294  "\nFROM pg_catalog.pg_publication\n");
6295 
6296  if (!validateSQLNamePattern(&buf, pattern, false, false,
6297  NULL, "pubname", NULL,
6298  NULL,
6299  NULL, 1))
6300  {
6301  termPQExpBuffer(&buf);
6302  return false;
6303  }
6304 
6305  appendPQExpBufferStr(&buf, "ORDER BY 1;");
6306 
6307  res = PSQLexec(buf.data);
6308  termPQExpBuffer(&buf);
6309  if (!res)
6310  return false;
6311 
6312  myopt.title = _("List of publications");
6313  myopt.translate_header = true;
6314  myopt.translate_columns = translate_columns;
6315  myopt.n_translate_columns = lengthof(translate_columns);
6316 
6317  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6318 
6319  PQclear(res);
6320 
6321  return true;
6322 }

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

5062 {
5064  PGresult *res;
5065  printQueryOpt myopt = pset.popt;
5066  int pub_schema_tuples = 0;
5067  char **footers = NULL;
5068 
5069  initPQExpBuffer(&buf);
5071  "SELECT n.nspname AS \"%s\",\n"
5072  " pg_catalog.pg_get_userbyid(n.nspowner) AS \"%s\"",
5073  gettext_noop("Name"),
5074  gettext_noop("Owner"));
5075 
5076  if (verbose)
5077  {
5078  appendPQExpBufferStr(&buf, ",\n ");
5079  printACLColumn(&buf, "n.nspacl");
5081  ",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
5082  gettext_noop("Description"));
5083  }
5084 
5086  "\nFROM pg_catalog.pg_namespace n\n");
5087 
5088  if (!showSystem && !pattern)
5090  "WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'\n");
5091 
5092  if (!validateSQLNamePattern(&buf, pattern,
5093  !showSystem && !pattern, false,
5094  NULL, "n.nspname", NULL,
5095  NULL,
5096  NULL, 2))
5097  goto error_return;
5098 
5099  appendPQExpBufferStr(&buf, "ORDER BY 1;");
5100 
5101  res = PSQLexec(buf.data);
5102  if (!res)
5103  goto error_return;
5104 
5105  myopt.title = _("List of schemas");
5106  myopt.translate_header = true;
5107 
5108  if (pattern && pset.sversion >= 150000)
5109  {
5110  PGresult *result;
5111  int i;
5112 
5114  "SELECT pubname \n"
5115  "FROM pg_catalog.pg_publication p\n"
5116  " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n"
5117  " JOIN pg_catalog.pg_namespace n ON n.oid = pn.pnnspid \n"
5118  "WHERE n.nspname = '%s'\n"
5119  "ORDER BY 1",
5120  pattern);
5121  result = PSQLexec(buf.data);
5122  if (!result)
5123  goto error_return;
5124  else
5125  pub_schema_tuples = PQntuples(result);
5126 
5127  if (pub_schema_tuples > 0)
5128  {
5129  /*
5130  * Allocate memory for footers. Size of footers will be 1 (for
5131  * storing "Publications:" string) + publication schema mapping
5132  * count + 1 (for storing NULL).
5133  */
5134  footers = (char **) pg_malloc((1 + pub_schema_tuples + 1) * sizeof(char *));
5135  footers[0] = pg_strdup(_("Publications:"));
5136 
5137  /* Might be an empty set - that's ok */
5138  for (i = 0; i < pub_schema_tuples; i++)
5139  {
5140  printfPQExpBuffer(&buf, " \"%s\"",
5141  PQgetvalue(result, i, 0));
5142 
5143  footers[i + 1] = pg_strdup(buf.data);
5144  }
5145 
5146  footers[i + 1] = NULL;
5147  myopt.footers = footers;
5148  }
5149 
5150  PQclear(result);
5151  }
5152 
5153  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5154 
5155  termPQExpBuffer(&buf);
5156  PQclear(res);
5157 
5158  /* Free the memory allocated for the footer */
5159  if (footers)
5160  {
5161  char **footer = NULL;
5162 
5163  for (footer = footers; *footer; footer++)
5164  pg_free(*footer);
5165 
5166  pg_free(footers);
5167  }
5168 
5169  return true;
5170 
5171 error_return:
5172  termPQExpBuffer(&buf);
5173  return false;
5174 }
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 3948 of file describe.c.

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

5560 {
5562  PGresult *res;
5563  printQueryOpt myopt = pset.popt;
5564 
5565  if (verbose)
5566  return listTSConfigsVerbose(pattern);
5567 
5568  initPQExpBuffer(&buf);
5569 
5571  "SELECT\n"
5572  " n.nspname as \"%s\",\n"
5573  " c.cfgname as \"%s\",\n"
5574  " pg_catalog.obj_description(c.oid, 'pg_ts_config') as \"%s\"\n"
5575  "FROM pg_catalog.pg_ts_config c\n"
5576  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace\n",
5577  gettext_noop("Schema"),
5578  gettext_noop("Name"),
5579  gettext_noop("Description")
5580  );
5581 
5582  if (!validateSQLNamePattern(&buf, pattern, false, false,
5583  "n.nspname", "c.cfgname", NULL,
5584  "pg_catalog.pg_ts_config_is_visible(c.oid)",
5585  NULL, 3))
5586  {
5587  termPQExpBuffer(&buf);
5588  return false;
5589  }
5590 
5591  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5592 
5593  res = PSQLexec(buf.data);
5594  termPQExpBuffer(&buf);
5595  if (!res)
5596  return false;
5597 
5598  myopt.title = _("List of text search configurations");
5599  myopt.translate_header = true;
5600 
5601  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5602 
5603  PQclear(res);
5604  return true;
5605 }
static bool listTSConfigsVerbose(const char *pattern)
Definition: describe.c:5608

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

5430 {
5432  PGresult *res;
5433  printQueryOpt myopt = pset.popt;
5434 
5435  initPQExpBuffer(&buf);
5436 
5438  "SELECT\n"
5439  " n.nspname as \"%s\",\n"
5440  " d.dictname as \"%s\",\n",
5441  gettext_noop("Schema"),
5442  gettext_noop("Name"));
5443 
5444  if (verbose)
5445  {
5447  " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
5448  " pg_catalog.pg_ts_template t\n"
5449  " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace\n"
5450  " WHERE d.dicttemplate = t.oid ) AS \"%s\",\n"
5451  " d.dictinitoption as \"%s\",\n",
5452  gettext_noop("Template"),
5453  gettext_noop("Init options"));
5454  }
5455 
5457  " pg_catalog.obj_description(d.oid, 'pg_ts_dict') as \"%s\"\n",
5458  gettext_noop("Description"));
5459 
5460  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_dict d\n"
5461  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace\n");
5462 
5463  if (!validateSQLNamePattern(&buf, pattern, false, false,
5464  "n.nspname", "d.dictname", NULL,
5465  "pg_catalog.pg_ts_dict_is_visible(d.oid)",
5466  NULL, 3))
5467  {
5468  termPQExpBuffer(&buf);
5469  return false;
5470  }
5471 
5472  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5473 
5474  res = PSQLexec(buf.data);
5475  termPQExpBuffer(&buf);
5476  if (!res)
5477  return false;
5478 
5479  myopt.title = _("List of text search dictionaries");
5480  myopt.translate_header = true;
5481 
5482  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5483 
5484  PQclear(res);
5485  return true;
5486 }

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

5183 {
5185  PGresult *res;
5186  printQueryOpt myopt = pset.popt;
5187 
5188  if (verbose)
5189  return listTSParsersVerbose(pattern);
5190 
5191  initPQExpBuffer(&buf);
5192 
5194  "SELECT\n"
5195  " n.nspname as \"%s\",\n"
5196  " p.prsname as \"%s\",\n"
5197  " pg_catalog.obj_description(p.oid, 'pg_ts_parser') as \"%s\"\n"
5198  "FROM pg_catalog.pg_ts_parser p\n"
5199  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n",
5200  gettext_noop("Schema"),
5201  gettext_noop("Name"),
5202  gettext_noop("Description")
5203  );
5204 
5205  if (!validateSQLNamePattern(&buf, pattern, false, false,
5206  "n.nspname", "p.prsname", NULL,
5207  "pg_catalog.pg_ts_parser_is_visible(p.oid)",
5208  NULL, 3))
5209  {
5210  termPQExpBuffer(&buf);
5211  return false;
5212  }
5213 
5214  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5215 
5216  res = PSQLexec(buf.data);
5217  termPQExpBuffer(&buf);
5218  if (!res)
5219  return false;
5220 
5221  myopt.title = _("List of text search parsers");
5222  myopt.translate_header = true;
5223 
5224  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5225 
5226  PQclear(res);
5227  return true;
5228 }
static bool listTSParsersVerbose(const char *pattern)
Definition: describe.c:5234

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

5495 {
5497  PGresult *res;
5498  printQueryOpt myopt = pset.popt;
5499 
5500  initPQExpBuffer(&buf);
5501 
5502  if (verbose)
5504  "SELECT\n"
5505  " n.nspname AS \"%s\",\n"
5506  " t.tmplname AS \"%s\",\n"
5507  " t.tmplinit::pg_catalog.regproc AS \"%s\",\n"
5508  " t.tmpllexize::pg_catalog.regproc AS \"%s\",\n"
5509  " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5510  gettext_noop("Schema"),
5511  gettext_noop("Name"),
5512  gettext_noop("Init"),
5513  gettext_noop("Lexize"),
5514  gettext_noop("Description"));
5515  else
5517  "SELECT\n"
5518  " n.nspname AS \"%s\",\n"
5519  " t.tmplname AS \"%s\",\n"
5520  " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5521  gettext_noop("Schema"),
5522  gettext_noop("Name"),
5523  gettext_noop("Description"));
5524 
5525  appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_template t\n"
5526  "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace\n");
5527 
5528  if (!validateSQLNamePattern(&buf, pattern, false, false,
5529  "n.nspname", "t.tmplname", NULL,
5530  "pg_catalog.pg_ts_template_is_visible(t.oid)",
5531  NULL, 3))
5532  {
5533  termPQExpBuffer(&buf);
5534  return false;
5535  }
5536 
5537  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5538 
5539  res = PSQLexec(buf.data);
5540  termPQExpBuffer(&buf);
5541  if (!res)
5542  return false;
5543 
5544  myopt.title = _("List of text search templates");
5545  myopt.translate_header = true;
5546 
5547  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5548 
5549  PQclear(res);
5550  return true;
5551 }

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

5911 {
5913  PGresult *res;
5914  printQueryOpt myopt = pset.popt;
5915 
5916  initPQExpBuffer(&buf);
5918  "SELECT um.srvname AS \"%s\",\n"
5919  " um.usename AS \"%s\"",
5920  gettext_noop("Server"),
5921  gettext_noop("User name"));
5922 
5923  if (verbose)
5925  ",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
5926  " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5927  " pg_catalog.quote_ident(option_name) || ' ' || "
5928  " pg_catalog.quote_literal(option_value) FROM "
5929  " pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' "
5930  " END AS \"%s\"",
5931  gettext_noop("FDW options"));
5932 
5933  appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_user_mappings um\n");
5934 
5935  if (!validateSQLNamePattern(&buf, pattern, false, false,
5936  NULL, "um.srvname", "um.usename", NULL,
5937  NULL, 1))
5938  {
5939  termPQExpBuffer(&buf);
5940  return false;
5941  }
5942 
5943  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5944 
5945  res = PSQLexec(buf.data);
5946  termPQExpBuffer(&buf);
5947  if (!res)
5948  return false;
5949 
5950  myopt.title = _("List of user mappings");
5951  myopt.translate_header = true;
5952 
5953  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5954 
5955  PQclear(res);
5956  return true;
5957 }

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

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

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

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

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().