PostgreSQL Source Code  git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 140 of file describe.c.

141 {
143  PGresult *res;
144  printQueryOpt myopt = pset.popt;
145  static const bool translate_columns[] = {false, true, false, false};
146 
147  if (pset.sversion < 90600)
148  {
149  char sverbuf[32];
150 
151  pg_log_error("The server (version %s) does not support access methods.",
153  sverbuf, sizeof(sverbuf)));
154  return true;
155  }
156 
158 
160  "SELECT amname AS \"%s\",\n"
161  " CASE amtype"
162  " WHEN 'i' THEN '%s'"
163  " WHEN 't' THEN '%s'"
164  " END AS \"%s\"",
165  gettext_noop("Name"),
166  gettext_noop("Index"),
167  gettext_noop("Table"),
168  gettext_noop("Type"));
169 
170  if (verbose)
171  {
173  ",\n amhandler AS \"%s\",\n"
174  " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
175  gettext_noop("Handler"),
176  gettext_noop("Description"));
177  }
178 
180  "\nFROM pg_catalog.pg_am\n");
181 
182  if (!validateSQLNamePattern(&buf, pattern, false, false,
183  NULL, "amname", NULL,
184  NULL,
185  NULL, 1))
186  {
188  return false;
189  }
190 
191  appendPQExpBufferStr(&buf, "ORDER BY 1;");
192 
193  res = PSQLexec(buf.data);
195  if (!res)
196  return false;
197 
198  myopt.title = _("List of access methods");
199  myopt.translate_header = true;
200  myopt.translate_columns = translate_columns;
201  myopt.n_translate_columns = lengthof(translate_columns);
202 
203  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
204 
205  PQclear(res);
206  return true;
207 }
PGresult * PSQLexec(const char *query)
Definition: common.c:620
#define gettext_noop(x)
Definition: c.h:1201
#define lengthof(array)
Definition: c.h:793
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:6221
#define _(x)
Definition: elog.c:90
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3549
int verbose
#define pg_log_error(...)
Definition: logging.h:106
static char * buf
Definition: pg_test_fsync.c:72
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:100
FILE * logfile
Definition: settings.h:131
FILE * queryFout
Definition: settings.h:93
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 70 of file describe.c.

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

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

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

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

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

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

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

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

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

Referenced by exec_command_d().

◆ describeRoleGrants()

bool describeRoleGrants ( const char *  pattern,
bool  showSystem 
)

Definition at line 3877 of file describe.c.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

7128 {
7130  PGresult *res;
7131  printQueryOpt myopt = pset.popt;
7132 
7133  initPQExpBuffer(&buf);
7134 
7136  "SELECT oid as \"%s\",\n"
7137  " pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n ",
7138  gettext_noop("ID"),
7139  gettext_noop("Owner"));
7140 
7141  if (verbose)
7142  {
7143  printACLColumn(&buf, "lomacl");
7144  appendPQExpBufferStr(&buf, ",\n ");
7145  }
7146 
7148  "pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
7149  "FROM pg_catalog.pg_largeobject_metadata\n"
7150  "ORDER BY oid",
7151  gettext_noop("Description"));
7152 
7153  res = PSQLexec(buf.data);
7154  termPQExpBuffer(&buf);
7155  if (!res)
7156  return false;
7157 
7158  myopt.title = _("Large objects");
7159  myopt.translate_header = true;
7160 
7161  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7162 
7163  PQclear(res);
7164  return true;
7165 }

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

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

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

6853 {
6855  PGresult *res;
6856  printQueryOpt myopt = pset.popt;
6857  bool have_where = false;
6858  static const bool translate_columns[] = {false, false, false, false};
6859 
6860  initPQExpBuffer(&buf);
6861 
6863  "SELECT\n"
6864  " am.amname AS \"%s\",\n"
6865  " CASE\n"
6866  " WHEN pg_catalog.pg_opfamily_is_visible(f.oid)\n"
6867  " THEN pg_catalog.format('%%I', f.opfname)\n"
6868  " ELSE pg_catalog.format('%%I.%%I', n.nspname, f.opfname)\n"
6869  " END AS \"%s\",\n"
6870  " (SELECT\n"
6871  " pg_catalog.string_agg(pg_catalog.format_type(oc.opcintype, NULL), ', ')\n"
6872  " FROM pg_catalog.pg_opclass oc\n"
6873  " WHERE oc.opcfamily = f.oid) \"%s\"",
6874  gettext_noop("AM"),
6875  gettext_noop("Operator family"),
6876  gettext_noop("Applicable types"));
6877  if (verbose)
6879  ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
6880  gettext_noop("Owner"));
6882  "\nFROM pg_catalog.pg_opfamily f\n"
6883  " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n"
6884  " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n");
6885 
6886  if (access_method_pattern)
6887  if (!validateSQLNamePattern(&buf, access_method_pattern,
6888  false, false, NULL, "am.amname", NULL, NULL,
6889  &have_where, 1))
6890  goto error_return;
6891  if (type_pattern)
6892  {
6894  " %s EXISTS (\n"
6895  " SELECT 1\n"
6896  " FROM pg_catalog.pg_type t\n"
6897  " JOIN pg_catalog.pg_opclass oc ON oc.opcintype = t.oid\n"
6898  " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"
6899  " WHERE oc.opcfamily = f.oid\n",
6900  have_where ? "AND" : "WHERE");
6901  /* Match type name pattern against either internal or external name */
6902  if (!validateSQLNamePattern(&buf, type_pattern, true, false,
6903  "tn.nspname", "t.typname",
6904  "pg_catalog.format_type(t.oid, NULL)",
6905  "pg_catalog.pg_type_is_visible(t.oid)",
6906  NULL, 3))
6907  goto error_return;
6908  appendPQExpBufferStr(&buf, " )\n");
6909  }
6910 
6911  appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6912  res = PSQLexec(buf.data);
6913  termPQExpBuffer(&buf);
6914  if (!res)
6915  return false;
6916 
6917  myopt.title = _("List of operator families");
6918  myopt.translate_header = true;
6919  myopt.translate_columns = translate_columns;
6920  myopt.n_translate_columns = lengthof(translate_columns);
6921 
6922  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6923 
6924  PQclear(res);
6925  return true;
6926 
6927 error_return:
6928  termPQExpBuffer(&buf);
6929  return false;
6930 }

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

7040 {
7042  PGresult *res;
7043  printQueryOpt myopt = pset.popt;
7044  bool have_where = false;
7045  static const bool translate_columns[] = {false, false, false, false, false, false};
7046 
7047  initPQExpBuffer(&buf);
7048 
7050  "SELECT\n"
7051  " am.amname AS \"%s\",\n"
7052  " CASE\n"
7053  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7054  " THEN pg_catalog.format('%%I', of.opfname)\n"
7055  " ELSE pg_catalog.format('%%I.%%I', ns.nspname, of.opfname)\n"
7056  " END AS \"%s\",\n"
7057  " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n"
7058  " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n"
7059  " ap.amprocnum AS \"%s\"\n",
7060  gettext_noop("AM"),
7061  gettext_noop("Operator family"),
7062  gettext_noop("Registered left type"),
7063  gettext_noop("Registered right type"),
7064  gettext_noop("Number"));
7065 
7066  if (!verbose)
7068  ", p.proname AS \"%s\"\n",
7069  gettext_noop("Function"));
7070  else
7072  ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n",
7073  gettext_noop("Function"));
7074 
7076  "FROM pg_catalog.pg_amproc ap\n"
7077  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n"
7078  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n"
7079  " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n"
7080  " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
7081 
7082  if (access_method_pattern)
7083  {
7084  if (!validateSQLNamePattern(&buf, access_method_pattern,
7085  false, false, NULL, "am.amname",
7086  NULL, NULL,
7087  &have_where, 1))
7088  goto error_return;
7089  }
7090  if (family_pattern)
7091  {
7092  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
7093  "ns.nspname", "of.opfname", NULL, NULL,
7094  NULL, 3))
7095  goto error_return;
7096  }
7097 
7098  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7099  " ap.amproclefttype = ap.amprocrighttype DESC,\n"
7100  " 3, 4, 5;");
7101 
7102  res = PSQLexec(buf.data);
7103  termPQExpBuffer(&buf);
7104  if (!res)
7105  return false;
7106 
7107  myopt.title = _("List of support functions of operator families");
7108  myopt.translate_header = true;
7109  myopt.translate_columns = translate_columns;
7110  myopt.n_translate_columns = lengthof(translate_columns);
7111 
7112  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7113 
7114  PQclear(res);
7115  return true;
7116 
7117 error_return:
7118  termPQExpBuffer(&buf);
7119  return false;
7120 }

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

6942 {
6944  PGresult *res;
6945  printQueryOpt myopt = pset.popt;
6946  bool have_where = false;
6947 
6948  static const bool translate_columns[] = {false, false, false, false, false, false};
6949 
6950  initPQExpBuffer(&buf);
6951 
6953  "SELECT\n"
6954  " am.amname AS \"%s\",\n"
6955  " CASE\n"
6956  " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
6957  " THEN pg_catalog.format('%%I', of.opfname)\n"
6958  " ELSE pg_catalog.format('%%I.%%I', nsf.nspname, of.opfname)\n"
6959  " END AS \"%s\",\n"
6960  " o.amopopr::pg_catalog.regoperator AS \"%s\"\n,"
6961  " o.amopstrategy AS \"%s\",\n"
6962  " CASE o.amoppurpose\n"
6963  " WHEN 'o' THEN '%s'\n"
6964  " WHEN 's' THEN '%s'\n"
6965  " END AS \"%s\"\n",
6966  gettext_noop("AM"),
6967  gettext_noop("Operator family"),
6968  gettext_noop("Operator"),
6969  gettext_noop("Strategy"),
6970  gettext_noop("ordering"),
6971  gettext_noop("search"),
6972  gettext_noop("Purpose"));
6973 
6974  if (verbose)
6976  ", ofs.opfname AS \"%s\"\n",
6977  gettext_noop("Sort opfamily"));
6979  "FROM pg_catalog.pg_amop o\n"
6980  " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
6981  " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
6982  " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
6983  if (verbose)
6985  " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n");
6986 
6987  if (access_method_pattern)
6988  {
6989  if (!validateSQLNamePattern(&buf, access_method_pattern,
6990  false, false, NULL, "am.amname",
6991  NULL, NULL,
6992  &have_where, 1))
6993  goto error_return;
6994  }
6995 
6996  if (family_pattern)
6997  {
6998  if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
6999  "nsf.nspname", "of.opfname", NULL, NULL,
7000  NULL, 3))
7001  goto error_return;
7002  }
7003 
7004  appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7005  " o.amoplefttype = o.amoprighttype DESC,\n"
7006  " pg_catalog.format_type(o.amoplefttype, NULL),\n"
7007  " pg_catalog.format_type(o.amoprighttype, NULL),\n"
7008  " o.amopstrategy;");
7009 
7010  res = PSQLexec(buf.data);
7011  termPQExpBuffer(&buf);
7012  if (!res)
7013  return false;
7014 
7015  myopt.title = _("List of operators of operator families");
7016  myopt.translate_header = true;
7017  myopt.translate_columns = translate_columns;
7018  myopt.n_translate_columns = lengthof(translate_columns);
7019 
7020  printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7021 
7022  PQclear(res);
7023  return true;
7024 
7025 error_return:
7026  termPQExpBuffer(&buf);
7027  return false;
7028 }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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