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

149{
151 PGresult *res;
152 printQueryOpt myopt = pset.popt;
153 static const bool translate_columns[] = {false, true, false, false};
154
155 if (pset.sversion < 90600)
156 {
157 char sverbuf[32];
158
159 pg_log_error("The server (version %s) does not support access methods.",
161 sverbuf, sizeof(sverbuf)));
162 return true;
163 }
164
166
168 "SELECT amname AS \"%s\",\n"
169 " CASE amtype"
170 " WHEN " CppAsString2(AMTYPE_INDEX) " THEN '%s'"
171 " WHEN " CppAsString2(AMTYPE_TABLE) " THEN '%s'"
172 " END AS \"%s\"",
173 gettext_noop("Name"),
174 gettext_noop("Index"),
175 gettext_noop("Table"),
176 gettext_noop("Type"));
177
178 if (verbose)
179 {
181 ",\n amhandler AS \"%s\",\n"
182 " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
183 gettext_noop("Handler"),
184 gettext_noop("Description"));
185 }
186
188 "\nFROM pg_catalog.pg_am\n");
189
190 if (!validateSQLNamePattern(&buf, pattern, false, false,
191 NULL, "amname", NULL,
192 NULL,
193 NULL, 1))
194 {
196 return false;
197 }
198
199 appendPQExpBufferStr(&buf, "ORDER BY 1;");
200
201 res = PSQLexec(buf.data);
203 if (!res)
204 return false;
205
206 myopt.title = _("List of access methods");
207 myopt.translate_header = true;
208 myopt.translate_columns = translate_columns;
209 myopt.n_translate_columns = lengthof(translate_columns);
210
211 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
212
213 PQclear(res);
214 return true;
215}
PGresult * PSQLexec(const char *query)
Definition: common.c:655
#define gettext_noop(x)
Definition: c.h:1199
#define CppAsString2(x)
Definition: c.h:422
#define lengthof(array)
Definition: c.h:791
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:6377
#define _(x)
Definition: elog.c:91
void printQuery(const PGresult *result, const printQueryOpt *opt, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3742
int verbose
#define PQclear
Definition: libpq-be-fe.h:245
#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:313
printQueryOpt popt
Definition: settings.h:112
FILE * logfile
Definition: settings.h:149
FILE * queryFout
Definition: settings.h:105
const bool * translate_columns
Definition: print.h:192
char * title
Definition: print.h:189
bool translate_header
Definition: print.h:191
int n_translate_columns
Definition: print.h:194

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 78 of file describe.c.

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

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 4745 of file describe.c.

4747{
4749 PGresult *res;
4750 printQueryOpt myopt = pset.popt;
4751
4754 "SELECT s.name AS \"%s\", "
4755 "pg_catalog.current_setting(s.name) AS \"%s\"",
4756 gettext_noop("Parameter"),
4757 gettext_noop("Value"));
4758
4759 if (verbose)
4760 {
4762 ", s.vartype AS \"%s\", s.context AS \"%s\", ",
4763 gettext_noop("Type"),
4764 gettext_noop("Context"));
4765 if (pset.sversion >= 150000)
4766 printACLColumn(&buf, "p.paracl");
4767 else
4768 appendPQExpBuffer(&buf, "NULL AS \"%s\"",
4769 gettext_noop("Access privileges"));
4770 }
4771
4772 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_settings s\n");
4773
4774 if (verbose && pset.sversion >= 150000)
4776 " LEFT JOIN pg_catalog.pg_parameter_acl p\n"
4777 " ON pg_catalog.lower(s.name) = p.parname\n");
4778
4779 if (pattern)
4780 processSQLNamePattern(pset.db, &buf, pattern,
4781 false, false,
4782 NULL, "pg_catalog.lower(s.name)", NULL,
4783 NULL, NULL, NULL);
4784 else
4785 appendPQExpBufferStr(&buf, "WHERE s.source <> 'default' AND\n"
4786 " s.setting IS DISTINCT FROM s.boot_val\n");
4787
4788 appendPQExpBufferStr(&buf, "ORDER BY 1;");
4789
4790 res = PSQLexec(buf.data);
4792 if (!res)
4793 return false;
4794
4795 if (pattern)
4796 myopt.title = _("List of configuration parameters");
4797 else
4798 myopt.title = _("List of non-default configuration parameters");
4799 myopt.translate_header = true;
4800
4801 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4802
4803 PQclear(res);
4804 return true;
4805}
static void printACLColumn(PQExpBuffer buf, const char *colname)
Definition: describe.c:6950
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)
PGconn * db
Definition: settings.h:103

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, _psqlSettings::db, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), processSQLNamePattern(), pset, PSQLexec(), _psqlSettings::queryFout, _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 295 of file describe.c.

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

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, 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, 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 794 of file describe.c.

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

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

Referenced by exec_command_dfo().

◆ describePublications()

bool describePublications ( const char *  pattern)

Definition at line 6568 of file describe.c.

6569{
6571 int i;
6572 PGresult *res;
6573 bool has_pubtruncate;
6574 bool has_pubgencols;
6575 bool has_pubviaroot;
6576 bool has_pubsequence;
6577
6578 PQExpBufferData title;
6579 printTableContent cont;
6580
6581 if (pset.sversion < 100000)
6582 {
6583 char sverbuf[32];
6584
6585 pg_log_error("The server (version %s) does not support publications.",
6587 sverbuf, sizeof(sverbuf)));
6588 return true;
6589 }
6590
6591 has_pubsequence = (pset.sversion >= 190000);
6592 has_pubtruncate = (pset.sversion >= 110000);
6593 has_pubgencols = (pset.sversion >= 180000);
6594 has_pubviaroot = (pset.sversion >= 130000);
6595
6597
6599 "SELECT oid, pubname,\n"
6600 " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n"
6601 " puballtables");
6602
6603 if (has_pubsequence)
6605 ", puballsequences");
6606 else
6608 ", false AS puballsequences");
6609
6611 ", pubinsert, pubupdate, pubdelete");
6612
6613 if (has_pubtruncate)
6615 ", pubtruncate");
6616 else
6618 ", false AS pubtruncate");
6619
6620 if (has_pubgencols)
6622 ", (CASE pubgencols\n"
6623 " WHEN '%c' THEN 'none'\n"
6624 " WHEN '%c' THEN 'stored'\n"
6625 " END) AS \"%s\"\n",
6626 PUBLISH_GENCOLS_NONE,
6627 PUBLISH_GENCOLS_STORED,
6628 gettext_noop("Generated columns"));
6629 else
6631 ", 'none' AS pubgencols");
6632
6633 if (has_pubviaroot)
6635 ", pubviaroot");
6636 else
6638 ", false AS pubviaroot");
6639
6641 "\nFROM pg_catalog.pg_publication\n");
6642
6643 if (!validateSQLNamePattern(&buf, pattern, false, false,
6644 NULL, "pubname", NULL,
6645 NULL,
6646 NULL, 1))
6647 {
6649 return false;
6650 }
6651
6652 appendPQExpBufferStr(&buf, "ORDER BY 2;");
6653
6654 res = PSQLexec(buf.data);
6655 if (!res)
6656 {
6658 return false;
6659 }
6660
6661 if (PQntuples(res) == 0)
6662 {
6663 if (!pset.quiet)
6664 {
6665 if (pattern)
6666 pg_log_error("Did not find any publication named \"%s\".",
6667 pattern);
6668 else
6669 pg_log_error("Did not find any publications.");
6670 }
6671
6673 PQclear(res);
6674 return false;
6675 }
6676
6677 for (i = 0; i < PQntuples(res); i++)
6678 {
6679 const char align = 'l';
6680 int ncols = 5;
6681 int nrows = 1;
6682 char *pubid = PQgetvalue(res, i, 0);
6683 char *pubname = PQgetvalue(res, i, 1);
6684 bool puballtables = strcmp(PQgetvalue(res, i, 3), "t") == 0;
6685 printTableOpt myopt = pset.popt.topt;
6686
6687 if (has_pubsequence)
6688 ncols++;
6689 if (has_pubtruncate)
6690 ncols++;
6691 if (has_pubgencols)
6692 ncols++;
6693 if (has_pubviaroot)
6694 ncols++;
6695
6696 initPQExpBuffer(&title);
6697 printfPQExpBuffer(&title, _("Publication %s"), pubname);
6698 printTableInit(&cont, &myopt, title.data, ncols, nrows);
6699
6700 printTableAddHeader(&cont, gettext_noop("Owner"), true, align);
6701 printTableAddHeader(&cont, gettext_noop("All tables"), true, align);
6702 if (has_pubsequence)
6703 printTableAddHeader(&cont, gettext_noop("All sequences"), true, align);
6704 printTableAddHeader(&cont, gettext_noop("Inserts"), true, align);
6705 printTableAddHeader(&cont, gettext_noop("Updates"), true, align);
6706 printTableAddHeader(&cont, gettext_noop("Deletes"), true, align);
6707 if (has_pubtruncate)
6708 printTableAddHeader(&cont, gettext_noop("Truncates"), true, align);
6709 if (has_pubgencols)
6710 printTableAddHeader(&cont, gettext_noop("Generated columns"), true, align);
6711 if (has_pubviaroot)
6712 printTableAddHeader(&cont, gettext_noop("Via root"), true, align);
6713
6714 printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
6715 printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
6716 if (has_pubsequence)
6717 printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
6718 printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
6719 printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false);
6720 printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false);
6721 if (has_pubtruncate)
6722 printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
6723 if (has_pubgencols)
6724 printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
6725 if (has_pubviaroot)
6726 printTableAddCell(&cont, PQgetvalue(res, i, 10), false, false);
6727
6728 if (!puballtables)
6729 {
6730 /* Get the tables for the specified publication */
6732 "SELECT n.nspname, c.relname");
6733 if (pset.sversion >= 150000)
6734 {
6736 ", pg_get_expr(pr.prqual, c.oid)");
6738 ", (CASE WHEN pr.prattrs IS NOT NULL THEN\n"
6739 " pg_catalog.array_to_string("
6740 " ARRAY(SELECT attname\n"
6741 " FROM\n"
6742 " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n"
6743 " pg_catalog.pg_attribute\n"
6744 " WHERE attrelid = c.oid AND attnum = prattrs[s]), ', ')\n"
6745 " ELSE NULL END)");
6746 }
6747 else
6749 ", NULL, NULL");
6751 "\nFROM pg_catalog.pg_class c,\n"
6752 " pg_catalog.pg_namespace n,\n"
6753 " pg_catalog.pg_publication_rel pr\n"
6754 "WHERE c.relnamespace = n.oid\n"
6755 " AND c.oid = pr.prrelid\n"
6756 " AND pr.prpubid = '%s'\n"
6757 "ORDER BY 1,2", pubid);
6758 if (!addFooterToPublicationDesc(&buf, _("Tables:"), false, &cont))
6759 goto error_return;
6760
6761 if (pset.sversion >= 150000)
6762 {
6763 /* Get the schemas for the specified publication */
6765 "SELECT n.nspname\n"
6766 "FROM pg_catalog.pg_namespace n\n"
6767 " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n"
6768 "WHERE pn.pnpubid = '%s'\n"
6769 "ORDER BY 1", pubid);
6770 if (!addFooterToPublicationDesc(&buf, _("Tables from schemas:"),
6771 true, &cont))
6772 goto error_return;
6773 }
6774 }
6775
6776 printTable(&cont, pset.queryFout, false, pset.logfile);
6777 printTableCleanup(&cont);
6778
6779 termPQExpBuffer(&title);
6780 }
6781
6783 PQclear(res);
6784
6785 return true;
6786
6787error_return:
6788 printTableCleanup(&cont);
6789 PQclear(res);
6791 termPQExpBuffer(&title);
6792 return false;
6793}
static bool addFooterToPublicationDesc(PQExpBuffer buf, const char *footermsg, bool as_schema, printTableContent *const cont)
Definition: describe.c:6522
void printTableInit(printTableContent *const content, const printTableOpt *opt, const char *title, const int ncolumns, const int nrows)
Definition: print.c:3191
void printTableCleanup(printTableContent *const content)
Definition: print.c:3372
void printTableAddCell(printTableContent *const content, char *cell, const bool translate, const bool mustfree)
Definition: print.c:3279
void printTable(const printTableContent *cont, FILE *fout, bool is_pager, FILE *flog)
Definition: print.c:3636
void printTableAddHeader(printTableContent *const content, char *header, const bool translate, const char align)
Definition: print.c:3239
#define PQgetvalue
Definition: libpq-be-fe.h:253
#define PQntuples
Definition: libpq-be-fe.h:251
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, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::topt, and validateSQLNamePattern().

Referenced by exec_command_d().

◆ describeRoleGrants()

bool describeRoleGrants ( const char *  pattern,
bool  showSystem 
)

Definition at line 3962 of file describe.c.

3963{
3965 PGresult *res;
3966 printQueryOpt myopt = pset.popt;
3967
3970 "SELECT m.rolname AS \"%s\", r.rolname AS \"%s\",\n"
3971 " pg_catalog.concat_ws(', ',\n",
3972 gettext_noop("Role name"),
3973 gettext_noop("Member of"));
3974
3975 if (pset.sversion >= 160000)
3977 " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3978 " CASE WHEN pam.inherit_option THEN 'INHERIT' END,\n"
3979 " CASE WHEN pam.set_option THEN 'SET' END\n");
3980 else
3982 " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n"
3983 " CASE WHEN m.rolinherit THEN 'INHERIT' END,\n"
3984 " 'SET'\n");
3985
3987 " ) AS \"%s\",\n"
3988 " g.rolname AS \"%s\"\n",
3989 gettext_noop("Options"),
3990 gettext_noop("Grantor"));
3991
3993 "FROM pg_catalog.pg_roles m\n"
3994 " JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)\n"
3995 " LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)\n"
3996 " LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)\n");
3997
3998 if (!showSystem && !pattern)
3999 appendPQExpBufferStr(&buf, "WHERE m.rolname !~ '^pg_'\n");
4000
4001 if (!validateSQLNamePattern(&buf, pattern, false, false,
4002 NULL, "m.rolname", NULL, NULL,
4003 NULL, 1))
4004 {
4006 return false;
4007 }
4008
4009 appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;\n");
4010
4011 res = PSQLexec(buf.data);
4013 if (!res)
4014 return false;
4015
4016 myopt.title = _("List of role grants");
4017 myopt.translate_header = true;
4018
4019 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4020
4021 PQclear(res);
4022 return true;
4023}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 3746 of file describe.c.

3747{
3749 PGresult *res;
3750 printTableContent cont;
3751 printTableOpt myopt = pset.popt.topt;
3752 int ncols = 2;
3753 int nrows = 0;
3754 int i;
3755 int conns;
3756 const char align = 'l';
3757 char **attr;
3758
3759 myopt.default_footer = false;
3760
3762
3764 "SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
3765 " r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
3766 " r.rolconnlimit, r.rolvaliduntil");
3767
3768 if (verbose)
3769 {
3770 appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
3771 ncols++;
3772 }
3773 appendPQExpBufferStr(&buf, "\n, r.rolreplication");
3774
3775 if (pset.sversion >= 90500)
3776 {
3777 appendPQExpBufferStr(&buf, "\n, r.rolbypassrls");
3778 }
3779
3780 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
3781
3782 if (!showSystem && !pattern)
3783 appendPQExpBufferStr(&buf, "WHERE r.rolname !~ '^pg_'\n");
3784
3785 if (!validateSQLNamePattern(&buf, pattern, false, false,
3786 NULL, "r.rolname", NULL, NULL,
3787 NULL, 1))
3788 {
3790 return false;
3791 }
3792
3793 appendPQExpBufferStr(&buf, "ORDER BY 1;");
3794
3795 res = PSQLexec(buf.data);
3796 if (!res)
3797 return false;
3798
3799 nrows = PQntuples(res);
3800 attr = pg_malloc0((nrows + 1) * sizeof(*attr));
3801
3802 printTableInit(&cont, &myopt, _("List of roles"), ncols, nrows);
3803
3804 printTableAddHeader(&cont, gettext_noop("Role name"), true, align);
3805 printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
3806
3807 if (verbose)
3808 printTableAddHeader(&cont, gettext_noop("Description"), true, align);
3809
3810 for (i = 0; i < nrows; i++)
3811 {
3812 printTableAddCell(&cont, PQgetvalue(res, i, 0), false, false);
3813
3815 if (strcmp(PQgetvalue(res, i, 1), "t") == 0)
3816 add_role_attribute(&buf, _("Superuser"));
3817
3818 if (strcmp(PQgetvalue(res, i, 2), "t") != 0)
3819 add_role_attribute(&buf, _("No inheritance"));
3820
3821 if (strcmp(PQgetvalue(res, i, 3), "t") == 0)
3822 add_role_attribute(&buf, _("Create role"));
3823
3824 if (strcmp(PQgetvalue(res, i, 4), "t") == 0)
3825 add_role_attribute(&buf, _("Create DB"));
3826
3827 if (strcmp(PQgetvalue(res, i, 5), "t") != 0)
3828 add_role_attribute(&buf, _("Cannot login"));
3829
3830 if (strcmp(PQgetvalue(res, i, (verbose ? 9 : 8)), "t") == 0)
3831 add_role_attribute(&buf, _("Replication"));
3832
3833 if (pset.sversion >= 90500)
3834 if (strcmp(PQgetvalue(res, i, (verbose ? 10 : 9)), "t") == 0)
3835 add_role_attribute(&buf, _("Bypass RLS"));
3836
3837 conns = atoi(PQgetvalue(res, i, 6));
3838 if (conns >= 0)
3839 {
3840 if (buf.len > 0)
3841 appendPQExpBufferChar(&buf, '\n');
3842
3843 if (conns == 0)
3844 appendPQExpBufferStr(&buf, _("No connections"));
3845 else
3846 appendPQExpBuffer(&buf, ngettext("%d connection",
3847 "%d connections",
3848 conns),
3849 conns);
3850 }
3851
3852 if (strcmp(PQgetvalue(res, i, 7), "") != 0)
3853 {
3854 if (buf.len > 0)
3855 appendPQExpBufferChar(&buf, '\n');
3856 appendPQExpBufferStr(&buf, _("Password valid until "));
3858 }
3859
3860 attr[i] = pg_strdup(buf.data);
3861
3862 printTableAddCell(&cont, attr[i], false, false);
3863
3864 if (verbose)
3865 printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
3866 }
3868
3869 printTable(&cont, pset.queryFout, false, pset.logfile);
3870 printTableCleanup(&cont);
3871
3872 for (i = 0; i < nrows; i++)
3873 free(attr[i]);
3874 free(attr);
3875
3876 PQclear(res);
3877 return true;
3878}
#define ngettext(s, p, n)
Definition: c.h:1184
static void add_role_attribute(PQExpBuffer buf, const char *const str)
Definition: describe.c:3881
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
#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, 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 6802 of file describe.c.

6803{
6805 PGresult *res;
6806 printQueryOpt myopt = pset.popt;
6807 static const bool translate_columns[] = {false, false, false, false,
6808 false, false, false, false, false, false, false, false, false, false,
6809 false, false, false, false};
6810
6811 if (pset.sversion < 100000)
6812 {
6813 char sverbuf[32];
6814
6815 pg_log_error("The server (version %s) does not support subscriptions.",
6817 sverbuf, sizeof(sverbuf)));
6818 return true;
6819 }
6820
6822
6824 "SELECT subname AS \"%s\"\n"
6825 ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n"
6826 ", subenabled AS \"%s\"\n"
6827 ", subpublications AS \"%s\"\n",
6828 gettext_noop("Name"),
6829 gettext_noop("Owner"),
6830 gettext_noop("Enabled"),
6831 gettext_noop("Publication"));
6832
6833 if (verbose)
6834 {
6835 /* Binary mode and streaming are only supported in v14 and higher */
6836 if (pset.sversion >= 140000)
6837 {
6839 ", subbinary AS \"%s\"\n",
6840 gettext_noop("Binary"));
6841
6842 if (pset.sversion >= 160000)
6844 ", (CASE substream\n"
6845 " WHEN " CppAsString2(LOGICALREP_STREAM_OFF) " THEN 'off'\n"
6846 " WHEN " CppAsString2(LOGICALREP_STREAM_ON) " THEN 'on'\n"
6847 " WHEN " CppAsString2(LOGICALREP_STREAM_PARALLEL) " THEN 'parallel'\n"
6848 " END) AS \"%s\"\n",
6849 gettext_noop("Streaming"));
6850 else
6852 ", substream AS \"%s\"\n",
6853 gettext_noop("Streaming"));
6854 }
6855
6856 /* Two_phase and disable_on_error are only supported in v15 and higher */
6857 if (pset.sversion >= 150000)
6859 ", subtwophasestate AS \"%s\"\n"
6860 ", subdisableonerr AS \"%s\"\n",
6861 gettext_noop("Two-phase commit"),
6862 gettext_noop("Disable on error"));
6863
6864 if (pset.sversion >= 160000)
6866 ", suborigin AS \"%s\"\n"
6867 ", subpasswordrequired AS \"%s\"\n"
6868 ", subrunasowner AS \"%s\"\n",
6869 gettext_noop("Origin"),
6870 gettext_noop("Password required"),
6871 gettext_noop("Run as owner?"));
6872
6873 if (pset.sversion >= 170000)
6875 ", subfailover AS \"%s\"\n",
6876 gettext_noop("Failover"));
6877 if (pset.sversion >= 190000)
6878 {
6880 ", subretaindeadtuples AS \"%s\"\n",
6881 gettext_noop("Retain dead tuples"));
6882
6884 ", submaxretention AS \"%s\"\n",
6885 gettext_noop("Max retention duration"));
6886
6888 ", subretentionactive AS \"%s\"\n",
6889 gettext_noop("Retention active"));
6890 }
6891
6893 ", subsynccommit AS \"%s\"\n"
6894 ", subconninfo AS \"%s\"\n",
6895 gettext_noop("Synchronous commit"),
6896 gettext_noop("Conninfo"));
6897
6898 /* Skip LSN is only supported in v15 and higher */
6899 if (pset.sversion >= 150000)
6901 ", subskiplsn AS \"%s\"\n",
6902 gettext_noop("Skip LSN"));
6903 }
6904
6905 /* Only display subscriptions in current database. */
6907 "FROM pg_catalog.pg_subscription\n"
6908 "WHERE subdbid = (SELECT oid\n"
6909 " FROM pg_catalog.pg_database\n"
6910 " WHERE datname = pg_catalog.current_database())");
6911
6912 if (!validateSQLNamePattern(&buf, pattern, true, false,
6913 NULL, "subname", NULL,
6914 NULL,
6915 NULL, 1))
6916 {
6918 return false;
6919 }
6920
6921 appendPQExpBufferStr(&buf, "ORDER BY 1;");
6922
6923 res = PSQLexec(buf.data);
6925 if (!res)
6926 return false;
6927
6928 myopt.title = _("List of subscriptions");
6929 myopt.translate_header = true;
6930 myopt.translate_columns = translate_columns;
6931 myopt.n_translate_columns = lengthof(translate_columns);
6932
6933 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6934
6935 PQclear(res);
6936 return true;
6937}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, formatPGVersionNumber(), gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 1488 of file describe.c.

1489{
1491 PGresult *res;
1492 int i;
1493
1495
1497 "SELECT c.oid,\n"
1498 " n.nspname,\n"
1499 " c.relname\n"
1500 "FROM pg_catalog.pg_class c\n"
1501 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n");
1502
1503 if (!showSystem && !pattern)
1504 appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1505 " AND n.nspname <> 'information_schema'\n");
1506
1507 if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
1508 "n.nspname", "c.relname", NULL,
1509 "pg_catalog.pg_table_is_visible(c.oid)",
1510 NULL, 3))
1511 {
1513 return false;
1514 }
1515
1516 appendPQExpBufferStr(&buf, "ORDER BY 2, 3;");
1517
1518 res = PSQLexec(buf.data);
1520 if (!res)
1521 return false;
1522
1523 if (PQntuples(res) == 0)
1524 {
1525 if (!pset.quiet)
1526 {
1527 if (pattern)
1528 pg_log_error("Did not find any relation named \"%s\".",
1529 pattern);
1530 else
1531 pg_log_error("Did not find any relations.");
1532 }
1533 PQclear(res);
1534 return false;
1535 }
1536
1537 for (i = 0; i < PQntuples(res); i++)
1538 {
1539 const char *oid;
1540 const char *nspname;
1541 const char *relname;
1542
1543 oid = PQgetvalue(res, i, 0);
1544 nspname = PQgetvalue(res, i, 1);
1545 relname = PQgetvalue(res, i, 2);
1546
1547 if (!describeOneTableDetails(nspname, relname, oid, verbose))
1548 {
1549 PQclear(res);
1550 return false;
1551 }
1552 if (cancel_pressed)
1553 {
1554 PQclear(res);
1555 return false;
1556 }
1557 }
1558
1559 PQclear(res);
1560 return true;
1561}
static bool describeOneTableDetails(const char *schemaname, const char *relationname, const char *oid, bool verbose)
Definition: describe.c:1571
volatile sig_atomic_t cancel_pressed
Definition: print.c:48
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, termPQExpBuffer(), validateSQLNamePattern(), and verbose.

Referenced by exec_command_d().

◆ describeTablespaces()

bool describeTablespaces ( const char *  pattern,
bool  verbose 
)

Definition at line 222 of file describe.c.

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

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 639 of file describe.c.

640{
642 PGresult *res;
643 printQueryOpt myopt = pset.popt;
644
646
648 "SELECT n.nspname as \"%s\",\n"
649 " pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
650 gettext_noop("Schema"),
651 gettext_noop("Name"));
652 if (verbose)
653 {
655 " t.typname AS \"%s\",\n"
656 " CASE WHEN t.typrelid != 0\n"
657 " THEN CAST('tuple' AS pg_catalog.text)\n"
658 " WHEN t.typlen < 0\n"
659 " THEN CAST('var' AS pg_catalog.text)\n"
660 " ELSE CAST(t.typlen AS pg_catalog.text)\n"
661 " END AS \"%s\",\n"
662 " pg_catalog.array_to_string(\n"
663 " ARRAY(\n"
664 " SELECT e.enumlabel\n"
665 " FROM pg_catalog.pg_enum e\n"
666 " WHERE e.enumtypid = t.oid\n"
667 " ORDER BY e.enumsortorder\n"
668 " ),\n"
669 " E'\\n'\n"
670 " ) AS \"%s\",\n"
671 " pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
672 gettext_noop("Internal name"),
673 gettext_noop("Size"),
674 gettext_noop("Elements"),
675 gettext_noop("Owner"));
676 printACLColumn(&buf, "t.typacl");
677 appendPQExpBufferStr(&buf, ",\n ");
678 }
679
681 " pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n",
682 gettext_noop("Description"));
683
684 appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_type t\n"
685 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
686
687 /*
688 * do not include complex types (typrelid!=0) unless they are standalone
689 * composite types
690 */
691 appendPQExpBufferStr(&buf, "WHERE (t.typrelid = 0 ");
692 appendPQExpBufferStr(&buf, "OR (SELECT c.relkind = " CppAsString2(RELKIND_COMPOSITE_TYPE)
693 " FROM pg_catalog.pg_class c "
694 "WHERE c.oid = t.typrelid))\n");
695
696 /*
697 * do not include array types unless the pattern contains []
698 */
699 if (pattern == NULL || strstr(pattern, "[]") == NULL)
700 appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n");
701
702 if (!showSystem && !pattern)
703 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
704 " AND n.nspname <> 'information_schema'\n");
705
706 /* Match name pattern against either internal or external name */
708 true, false,
709 "n.nspname", "t.typname",
710 "pg_catalog.format_type(t.oid, NULL)",
711 "pg_catalog.pg_type_is_visible(t.oid)",
712 NULL, 3))
713 {
715 return false;
716 }
717
718 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
719
720 res = PSQLexec(buf.data);
722 if (!res)
723 return false;
724
725 myopt.title = _("List of data types");
726 myopt.translate_header = true;
727
728 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
729
730 PQclear(res);
731 return true;
732}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, map_typename_pattern(), _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 946 of file describe.c.

947{
948 PGresult *res;
950 printQueryOpt myopt = pset.popt;
951
953
955 "SELECT\n"
956 " d.datname as \"%s\",\n"
957 " pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
958 " pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n",
959 gettext_noop("Name"),
960 gettext_noop("Owner"),
961 gettext_noop("Encoding"));
962 if (pset.sversion >= 150000)
964 " CASE d.datlocprovider "
965 "WHEN " CppAsString2(COLLPROVIDER_BUILTIN) " THEN 'builtin' "
966 "WHEN " CppAsString2(COLLPROVIDER_LIBC) " THEN 'libc' "
967 "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' "
968 "END AS \"%s\",\n",
969 gettext_noop("Locale Provider"));
970 else
972 " 'libc' AS \"%s\",\n",
973 gettext_noop("Locale Provider"));
975 " d.datcollate as \"%s\",\n"
976 " d.datctype as \"%s\",\n",
977 gettext_noop("Collate"),
978 gettext_noop("Ctype"));
979 if (pset.sversion >= 170000)
981 " d.datlocale as \"%s\",\n",
982 gettext_noop("Locale"));
983 else if (pset.sversion >= 150000)
985 " d.daticulocale as \"%s\",\n",
986 gettext_noop("Locale"));
987 else
989 " NULL as \"%s\",\n",
990 gettext_noop("Locale"));
991 if (pset.sversion >= 160000)
993 " d.daticurules as \"%s\",\n",
994 gettext_noop("ICU Rules"));
995 else
997 " NULL as \"%s\",\n",
998 gettext_noop("ICU Rules"));
1000 printACLColumn(&buf, "d.datacl");
1001 if (verbose)
1003 ",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
1004 " THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
1005 " ELSE 'No Access'\n"
1006 " END as \"%s\""
1007 ",\n t.spcname as \"%s\""
1008 ",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
1009 gettext_noop("Size"),
1010 gettext_noop("Tablespace"),
1011 gettext_noop("Description"));
1013 "\nFROM pg_catalog.pg_database d\n");
1014 if (verbose)
1016 " JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
1017
1018 if (pattern)
1019 {
1020 if (!validateSQLNamePattern(&buf, pattern, false, false,
1021 NULL, "d.datname", NULL, NULL,
1022 NULL, 1))
1023 {
1025 return false;
1026 }
1027 }
1028
1029 appendPQExpBufferStr(&buf, "ORDER BY 1;");
1030 res = PSQLexec(buf.data);
1032 if (!res)
1033 return false;
1034
1035 myopt.title = _("List of databases");
1036 myopt.translate_header = true;
1037
1038 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1039
1040 PQclear(res);
1041 return true;
1042}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 4989 of file describe.c.

4990{
4992 PGresult *res;
4993 printQueryOpt myopt = pset.popt;
4994 static const bool translate_columns[] = {false, false, false, true, true, false};
4995
4997
4999 "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n"
5000 " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n",
5001 gettext_noop("Source type"),
5002 gettext_noop("Target type"));
5003
5004 /*
5005 * We don't attempt to localize '(binary coercible)' or '(with inout)',
5006 * because there's too much risk of gettext translating a function name
5007 * that happens to match some string in the PO database.
5008 */
5010 " CASE WHEN c.castmethod = '%c' THEN '(binary coercible)'\n"
5011 " WHEN c.castmethod = '%c' THEN '(with inout)'\n"
5012 " ELSE p.proname\n"
5013 " END AS \"%s\",\n",
5014 COERCION_METHOD_BINARY,
5015 COERCION_METHOD_INOUT,
5016 gettext_noop("Function"));
5017
5019 " CASE WHEN c.castcontext = '%c' THEN '%s'\n"
5020 " WHEN c.castcontext = '%c' THEN '%s'\n"
5021 " ELSE '%s'\n"
5022 " END AS \"%s\"",
5023 COERCION_CODE_EXPLICIT,
5024 gettext_noop("no"),
5025 COERCION_CODE_ASSIGNMENT,
5026 gettext_noop("in assignment"),
5027 gettext_noop("yes"),
5028 gettext_noop("Implicit?"));
5029
5030 if (verbose)
5032 ",\n CASE WHEN p.proleakproof THEN '%s'\n"
5033 " ELSE '%s'\n"
5034 " END AS \"%s\",\n"
5035 " d.description AS \"%s\"",
5036 gettext_noop("yes"),
5037 gettext_noop("no"),
5038 gettext_noop("Leakproof?"),
5039 gettext_noop("Description"));
5040
5041 /*
5042 * We need a left join to pg_proc for binary casts; the others are just
5043 * paranoia.
5044 */
5046 "\nFROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n"
5047 " ON c.castfunc = p.oid\n"
5048 " LEFT JOIN pg_catalog.pg_type ts\n"
5049 " ON c.castsource = ts.oid\n"
5050 " LEFT JOIN pg_catalog.pg_namespace ns\n"
5051 " ON ns.oid = ts.typnamespace\n"
5052 " LEFT JOIN pg_catalog.pg_type tt\n"
5053 " ON c.casttarget = tt.oid\n"
5054 " LEFT JOIN pg_catalog.pg_namespace nt\n"
5055 " ON nt.oid = tt.typnamespace\n");
5056
5057 if (verbose)
5059 " LEFT JOIN pg_catalog.pg_description d\n"
5060 " ON d.classoid = c.tableoid AND d.objoid = "
5061 "c.oid AND d.objsubid = 0\n");
5062
5063 appendPQExpBufferStr(&buf, "WHERE ( (true");
5064
5065 /*
5066 * Match name pattern against either internal or external name of either
5067 * castsource or casttarget
5068 */
5069 if (!validateSQLNamePattern(&buf, pattern, true, false,
5070 "ns.nspname", "ts.typname",
5071 "pg_catalog.format_type(ts.oid, NULL)",
5072 "pg_catalog.pg_type_is_visible(ts.oid)",
5073 NULL, 3))
5074 goto error_return;
5075
5076 appendPQExpBufferStr(&buf, ") OR (true");
5077
5078 if (!validateSQLNamePattern(&buf, pattern, true, false,
5079 "nt.nspname", "tt.typname",
5080 "pg_catalog.format_type(tt.oid, NULL)",
5081 "pg_catalog.pg_type_is_visible(tt.oid)",
5082 NULL, 3))
5083 goto error_return;
5084
5085 appendPQExpBufferStr(&buf, ") )\nORDER BY 1, 2;");
5086
5087 res = PSQLexec(buf.data);
5089 if (!res)
5090 return false;
5091
5092 myopt.title = _("List of casts");
5093 myopt.translate_header = true;
5094 myopt.translate_columns = translate_columns;
5095 myopt.n_translate_columns = lengthof(translate_columns);
5096
5097 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5098
5099 PQclear(res);
5100 return true;
5101
5102error_return:
5104 return false;
5105}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 5113 of file describe.c.

5114{
5116 PGresult *res;
5117 printQueryOpt myopt = pset.popt;
5118 static const bool translate_columns[] = {false, false, false, false, false, false, false, true, false};
5119
5121
5123 "SELECT\n"
5124 " n.nspname AS \"%s\",\n"
5125 " c.collname AS \"%s\",\n",
5126 gettext_noop("Schema"),
5127 gettext_noop("Name"));
5128
5129 if (pset.sversion >= 100000)
5131 " CASE c.collprovider "
5132 "WHEN " CppAsString2(COLLPROVIDER_DEFAULT) " THEN 'default' "
5133 "WHEN " CppAsString2(COLLPROVIDER_BUILTIN) " THEN 'builtin' "
5134 "WHEN " CppAsString2(COLLPROVIDER_LIBC) " THEN 'libc' "
5135 "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' "
5136 "END AS \"%s\",\n",
5137 gettext_noop("Provider"));
5138 else
5140 " 'libc' AS \"%s\",\n",
5141 gettext_noop("Provider"));
5142
5144 " c.collcollate AS \"%s\",\n"
5145 " c.collctype AS \"%s\",\n",
5146 gettext_noop("Collate"),
5147 gettext_noop("Ctype"));
5148
5149 if (pset.sversion >= 170000)
5151 " c.colllocale AS \"%s\",\n",
5152 gettext_noop("Locale"));
5153 else if (pset.sversion >= 150000)
5155 " c.colliculocale AS \"%s\",\n",
5156 gettext_noop("Locale"));
5157 else
5159 " c.collcollate AS \"%s\",\n",
5160 gettext_noop("Locale"));
5161
5162 if (pset.sversion >= 160000)
5164 " c.collicurules AS \"%s\",\n",
5165 gettext_noop("ICU Rules"));
5166 else
5168 " NULL AS \"%s\",\n",
5169 gettext_noop("ICU Rules"));
5170
5171 if (pset.sversion >= 120000)
5173 " CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \"%s\"",
5174 gettext_noop("yes"), gettext_noop("no"),
5175 gettext_noop("Deterministic?"));
5176 else
5178 " '%s' AS \"%s\"",
5179 gettext_noop("yes"),
5180 gettext_noop("Deterministic?"));
5181
5182 if (verbose)
5184 ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
5185 gettext_noop("Description"));
5186
5188 "\nFROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n\n"
5189 "WHERE n.oid = c.collnamespace\n");
5190
5191 if (!showSystem && !pattern)
5192 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
5193 " AND n.nspname <> 'information_schema'\n");
5194
5195 /*
5196 * Hide collations that aren't usable in the current database's encoding.
5197 * If you think to change this, note that pg_collation_is_visible rejects
5198 * unusable collations, so you will need to hack name pattern processing
5199 * somehow to avoid inconsistent behavior.
5200 */
5201 appendPQExpBufferStr(&buf, " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding()))\n");
5202
5203 if (!validateSQLNamePattern(&buf, pattern, true, false,
5204 "n.nspname", "c.collname", NULL,
5205 "pg_catalog.pg_collation_is_visible(c.oid)",
5206 NULL, 3))
5207 {
5209 return false;
5210 }
5211
5212 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5213
5214 res = PSQLexec(buf.data);
5216 if (!res)
5217 return false;
5218
5219 myopt.title = _("List of collations");
5220 myopt.translate_header = true;
5221 myopt.translate_columns = translate_columns;
5222 myopt.n_translate_columns = lengthof(translate_columns);
5223
5224 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5225
5226 PQclear(res);
5227 return true;
5228}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _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 4665 of file describe.c.

4666{
4668 PGresult *res;
4669 printQueryOpt myopt = pset.popt;
4670 static const bool translate_columns[] =
4671 {false, false, false, false, true, false};
4672
4674
4676 "SELECT n.nspname AS \"%s\",\n"
4677 " c.conname AS \"%s\",\n"
4678 " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n"
4679 " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n"
4680 " CASE WHEN c.condefault THEN '%s'\n"
4681 " ELSE '%s' END AS \"%s\"",
4682 gettext_noop("Schema"),
4683 gettext_noop("Name"),
4684 gettext_noop("Source"),
4685 gettext_noop("Destination"),
4686 gettext_noop("yes"), gettext_noop("no"),
4687 gettext_noop("Default?"));
4688
4689 if (verbose)
4691 ",\n d.description AS \"%s\"",
4692 gettext_noop("Description"));
4693
4695 "\nFROM pg_catalog.pg_conversion c\n"
4696 " JOIN pg_catalog.pg_namespace n "
4697 "ON n.oid = c.connamespace\n");
4698
4699 if (verbose)
4701 "LEFT JOIN pg_catalog.pg_description d "
4702 "ON d.classoid = c.tableoid\n"
4703 " AND d.objoid = c.oid "
4704 "AND d.objsubid = 0\n");
4705
4706 appendPQExpBufferStr(&buf, "WHERE true\n");
4707
4708 if (!showSystem && !pattern)
4709 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4710 " AND n.nspname <> 'information_schema'\n");
4711
4712 if (!validateSQLNamePattern(&buf, pattern, true, false,
4713 "n.nspname", "c.conname", NULL,
4714 "pg_catalog.pg_conversion_is_visible(c.oid)",
4715 NULL, 3))
4716 {
4718 return false;
4719 }
4720
4721 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4722
4723 res = PSQLexec(buf.data);
4725 if (!res)
4726 return false;
4727
4728 myopt.title = _("List of conversions");
4729 myopt.translate_header = true;
4730 myopt.translate_columns = translate_columns;
4731 myopt.n_translate_columns = lengthof(translate_columns);
4732
4733 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4734
4735 PQclear(res);
4736 return true;
4737}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 3893 of file describe.c.

3894{
3896 PGresult *res;
3897 printQueryOpt myopt = pset.popt;
3898 bool havewhere;
3899
3901
3902 printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n"
3903 "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n"
3904 "FROM pg_catalog.pg_db_role_setting s\n"
3905 "LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase\n"
3906 "LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole\n",
3907 gettext_noop("Role"),
3908 gettext_noop("Database"),
3909 gettext_noop("Settings"));
3910 if (!validateSQLNamePattern(&buf, pattern, false, false,
3911 NULL, "r.rolname", NULL, NULL, &havewhere, 1))
3912 goto error_return;
3913 if (!validateSQLNamePattern(&buf, pattern2, havewhere, false,
3914 NULL, "d.datname", NULL, NULL,
3915 NULL, 1))
3916 goto error_return;
3917 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
3918
3919 res = PSQLexec(buf.data);
3921 if (!res)
3922 return false;
3923
3924 /*
3925 * Most functions in this file are content to print an empty table when
3926 * there are no matching objects. We intentionally deviate from that
3927 * here, but only in !quiet mode, because of the possibility that the user
3928 * is confused about what the two pattern arguments mean.
3929 */
3930 if (PQntuples(res) == 0 && !pset.quiet)
3931 {
3932 if (pattern && pattern2)
3933 pg_log_error("Did not find any settings for role \"%s\" and database \"%s\".",
3934 pattern, pattern2);
3935 else if (pattern)
3936 pg_log_error("Did not find any settings for role \"%s\".",
3937 pattern);
3938 else
3939 pg_log_error("Did not find any settings.");
3940 }
3941 else
3942 {
3943 myopt.title = _("List of settings");
3944 myopt.translate_header = true;
3945
3946 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
3947 }
3948
3949 PQclear(res);
3950 return true;
3951
3952error_return:
3954 return false;
3955}

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

Referenced by exec_command_d().

◆ listDefaultACLs()

bool listDefaultACLs ( const char *  pattern)

Definition at line 1214 of file describe.c.

1215{
1217 PGresult *res;
1218 printQueryOpt myopt = pset.popt;
1219 static const bool translate_columns[] = {false, false, true, false};
1220
1222
1224 "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n"
1225 " n.nspname AS \"%s\",\n"
1226 " CASE d.defaclobjtype "
1227 " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s'"
1228 " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n"
1229 " ",
1230 gettext_noop("Owner"),
1231 gettext_noop("Schema"),
1232 DEFACLOBJ_RELATION,
1233 gettext_noop("table"),
1234 DEFACLOBJ_SEQUENCE,
1235 gettext_noop("sequence"),
1236 DEFACLOBJ_FUNCTION,
1237 gettext_noop("function"),
1238 DEFACLOBJ_TYPE,
1239 gettext_noop("type"),
1240 DEFACLOBJ_NAMESPACE,
1241 gettext_noop("schema"),
1242 DEFACLOBJ_LARGEOBJECT,
1243 gettext_noop("large object"),
1244 gettext_noop("Type"));
1245
1246 printACLColumn(&buf, "d.defaclacl");
1247
1248 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n"
1249 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
1250
1251 if (!validateSQLNamePattern(&buf, pattern, false, false,
1252 NULL,
1253 "n.nspname",
1254 "pg_catalog.pg_get_userbyid(d.defaclrole)",
1255 NULL,
1256 NULL, 3))
1257 goto error_return;
1258
1259 appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1260
1261 res = PSQLexec(buf.data);
1262 if (!res)
1263 goto error_return;
1264
1265 printfPQExpBuffer(&buf, _("Default access privileges"));
1266 myopt.title = buf.data;
1267 myopt.translate_header = true;
1268 myopt.translate_columns = translate_columns;
1269 myopt.n_translate_columns = lengthof(translate_columns);
1270
1271 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1272
1274 PQclear(res);
1275 return true;
1276
1277error_return:
1279 return false;
1280}

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 4582 of file describe.c.

4583{
4585 PGresult *res;
4586 printQueryOpt myopt = pset.popt;
4587
4589
4591 "SELECT n.nspname as \"%s\",\n"
4592 " t.typname as \"%s\",\n"
4593 " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n"
4594 " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n"
4595 " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n"
4596 " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n"
4597 " t.typdefault as \"%s\",\n"
4598 " pg_catalog.array_to_string(ARRAY(\n"
4599 " SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM pg_catalog.pg_constraint r WHERE t.oid = r.contypid AND r.contype = " CppAsString2(CONSTRAINT_CHECK) " ORDER BY r.conname\n"
4600 " ), ' ') as \"%s\"",
4601 gettext_noop("Schema"),
4602 gettext_noop("Name"),
4603 gettext_noop("Type"),
4604 gettext_noop("Collation"),
4605 gettext_noop("Nullable"),
4606 gettext_noop("Default"),
4607 gettext_noop("Check"));
4608
4609 if (verbose)
4610 {
4611 appendPQExpBufferStr(&buf, ",\n ");
4612 printACLColumn(&buf, "t.typacl");
4614 ",\n d.description as \"%s\"",
4615 gettext_noop("Description"));
4616 }
4617
4619 "\nFROM pg_catalog.pg_type t\n"
4620 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
4621
4622 if (verbose)
4624 " LEFT JOIN pg_catalog.pg_description d "
4625 "ON d.classoid = t.tableoid AND d.objoid = t.oid "
4626 "AND d.objsubid = 0\n");
4627
4628 appendPQExpBufferStr(&buf, "WHERE t.typtype = 'd'\n");
4629
4630 if (!showSystem && !pattern)
4631 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4632 " AND n.nspname <> 'information_schema'\n");
4633
4634 if (!validateSQLNamePattern(&buf, pattern, true, false,
4635 "n.nspname", "t.typname", NULL,
4636 "pg_catalog.pg_type_is_visible(t.oid)",
4637 NULL, 3))
4638 {
4640 return false;
4641 }
4642
4643 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4644
4645 res = PSQLexec(buf.data);
4647 if (!res)
4648 return false;
4649
4650 myopt.title = _("List of domains");
4651 myopt.translate_header = true;
4652
4653 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4654
4655 PQclear(res);
4656 return true;
4657}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 4813 of file describe.c.

4814{
4816 PGresult *res;
4817 printQueryOpt myopt = pset.popt;
4818 static const bool translate_columns[] =
4819 {false, false, false, true, false, false, false};
4820
4821 if (pset.sversion < 90300)
4822 {
4823 char sverbuf[32];
4824
4825 pg_log_error("The server (version %s) does not support event triggers.",
4827 sverbuf, sizeof(sverbuf)));
4828 return true;
4829 }
4830
4832
4834 "SELECT evtname as \"%s\", "
4835 "evtevent as \"%s\", "
4836 "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n"
4837 " case evtenabled when 'O' then '%s'"
4838 " when 'R' then '%s'"
4839 " when 'A' then '%s'"
4840 " when 'D' then '%s' end as \"%s\",\n"
4841 " e.evtfoid::pg_catalog.regproc as \"%s\", "
4842 "pg_catalog.array_to_string(array(select x"
4843 " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
4844 gettext_noop("Name"),
4845 gettext_noop("Event"),
4846 gettext_noop("Owner"),
4847 gettext_noop("enabled"),
4848 gettext_noop("replica"),
4849 gettext_noop("always"),
4850 gettext_noop("disabled"),
4851 gettext_noop("Enabled"),
4852 gettext_noop("Function"),
4853 gettext_noop("Tags"));
4854 if (verbose)
4856 ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
4857 gettext_noop("Description"));
4859 "\nFROM pg_catalog.pg_event_trigger e ");
4860
4861 if (!validateSQLNamePattern(&buf, pattern, false, false,
4862 NULL, "evtname", NULL, NULL,
4863 NULL, 1))
4864 {
4866 return false;
4867 }
4868
4869 appendPQExpBufferStr(&buf, "ORDER BY 1");
4870
4871 res = PSQLexec(buf.data);
4873 if (!res)
4874 return false;
4875
4876 myopt.title = _("List of event triggers");
4877 myopt.translate_header = true;
4878 myopt.translate_columns = translate_columns;
4879 myopt.n_translate_columns = lengthof(translate_columns);
4880
4881 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4882
4883 PQclear(res);
4884 return true;
4885}

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, _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 4893 of file describe.c.

4894{
4896 PGresult *res;
4897 printQueryOpt myopt = pset.popt;
4898
4899 if (pset.sversion < 100000)
4900 {
4901 char sverbuf[32];
4902
4903 pg_log_error("The server (version %s) does not support extended statistics.",
4905 sverbuf, sizeof(sverbuf)));
4906 return true;
4907 }
4908
4911 "SELECT \n"
4912 "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text AS \"%s\", \n"
4913 "es.stxname AS \"%s\", \n",
4914 gettext_noop("Schema"),
4915 gettext_noop("Name"));
4916
4917 if (pset.sversion >= 140000)
4919 "pg_catalog.format('%%s FROM %%s', \n"
4920 " pg_catalog.pg_get_statisticsobjdef_columns(es.oid), \n"
4921 " es.stxrelid::pg_catalog.regclass) AS \"%s\"",
4922 gettext_noop("Definition"));
4923 else
4925 "pg_catalog.format('%%s FROM %%s', \n"
4926 " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(a.attname),', ') \n"
4927 " FROM pg_catalog.unnest(es.stxkeys) s(attnum) \n"
4928 " JOIN pg_catalog.pg_attribute a \n"
4929 " ON (es.stxrelid = a.attrelid \n"
4930 " AND a.attnum = s.attnum \n"
4931 " AND NOT a.attisdropped)), \n"
4932 "es.stxrelid::pg_catalog.regclass) AS \"%s\"",
4933 gettext_noop("Definition"));
4934
4936 ",\nCASE WHEN " CppAsString2(STATS_EXT_NDISTINCT) " = any(es.stxkind) THEN 'defined' \n"
4937 "END AS \"%s\", \n"
4938 "CASE WHEN " CppAsString2(STATS_EXT_DEPENDENCIES) " = any(es.stxkind) THEN 'defined' \n"
4939 "END AS \"%s\"",
4940 gettext_noop("Ndistinct"),
4941 gettext_noop("Dependencies"));
4942
4943 /*
4944 * Include the MCV statistics kind.
4945 */
4946 if (pset.sversion >= 120000)
4947 {
4949 ",\nCASE WHEN " CppAsString2(STATS_EXT_MCV) " = any(es.stxkind) THEN 'defined' \n"
4950 "END AS \"%s\" ",
4951 gettext_noop("MCV"));
4952 }
4953
4955 " \nFROM pg_catalog.pg_statistic_ext es \n");
4956
4957 if (!validateSQLNamePattern(&buf, pattern,
4958 false, false,
4959 "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text", "es.stxname",
4960 NULL, "pg_catalog.pg_statistics_obj_is_visible(es.oid)",
4961 NULL, 3))
4962 {
4964 return false;
4965 }
4966
4967 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
4968
4969 res = PSQLexec(buf.data);
4971 if (!res)
4972 return false;
4973
4974 myopt.title = _("List of extended statistics");
4975 myopt.translate_header = true;
4976
4977 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4978
4979 PQclear(res);
4980 return true;
4981}

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

Referenced by exec_command_d().

◆ listExtensionContents()

bool listExtensionContents ( const char *  pattern)

Definition at line 6266 of file describe.c.

6267{
6269 PGresult *res;
6270 int i;
6271
6274 "SELECT e.extname, e.oid\n"
6275 "FROM pg_catalog.pg_extension e\n");
6276
6277 if (!validateSQLNamePattern(&buf, pattern,
6278 false, false,
6279 NULL, "e.extname", NULL,
6280 NULL,
6281 NULL, 1))
6282 {
6284 return false;
6285 }
6286
6287 appendPQExpBufferStr(&buf, "ORDER BY 1;");
6288
6289 res = PSQLexec(buf.data);
6291 if (!res)
6292 return false;
6293
6294 if (PQntuples(res) == 0)
6295 {
6296 if (!pset.quiet)
6297 {
6298 if (pattern)
6299 pg_log_error("Did not find any extension named \"%s\".",
6300 pattern);
6301 else
6302 pg_log_error("Did not find any extensions.");
6303 }
6304 PQclear(res);
6305 return false;
6306 }
6307
6308 for (i = 0; i < PQntuples(res); i++)
6309 {
6310 const char *extname;
6311 const char *oid;
6312
6313 extname = PQgetvalue(res, i, 0);
6314 oid = PQgetvalue(res, i, 1);
6315
6316 if (!listOneExtensionContents(extname, oid))
6317 {
6318 PQclear(res);
6319 return false;
6320 }
6321 if (cancel_pressed)
6322 {
6323 PQclear(res);
6324 return false;
6325 }
6326 }
6327
6328 PQclear(res);
6329 return true;
6330}
static bool listOneExtensionContents(const char *extname, const char *oid)
Definition: describe.c:6333

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

Referenced by exec_command_d().

◆ listExtensions()

bool listExtensions ( const char *  pattern)

Definition at line 6212 of file describe.c.

6213{
6215 PGresult *res;
6216 printQueryOpt myopt = pset.popt;
6217
6220 "SELECT e.extname AS \"%s\", "
6221 "e.extversion AS \"%s\", ae.default_version AS \"%s\","
6222 "n.nspname AS \"%s\", d.description AS \"%s\"\n"
6223 "FROM pg_catalog.pg_extension e "
6224 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
6225 "LEFT JOIN pg_catalog.pg_description d ON d.objoid = e.oid "
6226 "AND d.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass "
6227 "LEFT JOIN pg_catalog.pg_available_extensions() ae(name, default_version, comment) ON ae.name = e.extname\n",
6228 gettext_noop("Name"),
6229 gettext_noop("Version"),
6230 gettext_noop("Default version"),
6231 gettext_noop("Schema"),
6232 gettext_noop("Description"));
6233
6234 if (!validateSQLNamePattern(&buf, pattern,
6235 false, false,
6236 NULL, "e.extname", NULL,
6237 NULL,
6238 NULL, 1))
6239 {
6241 return false;
6242 }
6243
6244 appendPQExpBufferStr(&buf, "ORDER BY 1;");
6245
6246 res = PSQLexec(buf.data);
6248 if (!res)
6249 return false;
6250
6251 myopt.title = _("List of installed extensions");
6252 myopt.translate_header = true;
6253
6254 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6255
6256 PQclear(res);
6257 return true;
6258}

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

Referenced by exec_command_d().

◆ listForeignDataWrappers()

bool listForeignDataWrappers ( const char *  pattern,
bool  verbose 
)

Definition at line 5938 of file describe.c.

5939{
5941 PGresult *res;
5942 printQueryOpt myopt = pset.popt;
5943
5946 "SELECT fdw.fdwname AS \"%s\",\n"
5947 " pg_catalog.pg_get_userbyid(fdw.fdwowner) AS \"%s\",\n"
5948 " fdw.fdwhandler::pg_catalog.regproc AS \"%s\",\n"
5949 " fdw.fdwvalidator::pg_catalog.regproc AS \"%s\"",
5950 gettext_noop("Name"),
5951 gettext_noop("Owner"),
5952 gettext_noop("Handler"),
5953 gettext_noop("Validator"));
5954
5955 if (verbose)
5956 {
5957 appendPQExpBufferStr(&buf, ",\n ");
5958 printACLColumn(&buf, "fdwacl");
5960 ",\n CASE WHEN fdwoptions IS NULL THEN '' ELSE "
5961 " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
5962 " pg_catalog.quote_ident(option_name) || ' ' || "
5963 " pg_catalog.quote_literal(option_value) FROM "
5964 " pg_catalog.pg_options_to_table(fdwoptions)), ', ') || ')' "
5965 " END AS \"%s\""
5966 ",\n d.description AS \"%s\" ",
5967 gettext_noop("FDW options"),
5968 gettext_noop("Description"));
5969 }
5970
5971 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_foreign_data_wrapper fdw\n");
5972
5973 if (verbose)
5975 "LEFT JOIN pg_catalog.pg_description d\n"
5976 " ON d.classoid = fdw.tableoid "
5977 "AND d.objoid = fdw.oid AND d.objsubid = 0\n");
5978
5979 if (!validateSQLNamePattern(&buf, pattern, false, false,
5980 NULL, "fdwname", NULL, NULL,
5981 NULL, 1))
5982 {
5984 return false;
5985 }
5986
5987 appendPQExpBufferStr(&buf, "ORDER BY 1;");
5988
5989 res = PSQLexec(buf.data);
5991 if (!res)
5992 return false;
5993
5994 myopt.title = _("List of foreign-data wrappers");
5995 myopt.translate_header = true;
5996
5997 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5998
5999 PQclear(res);
6000 return true;
6001}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 6009 of file describe.c.

6010{
6012 PGresult *res;
6013 printQueryOpt myopt = pset.popt;
6014
6017 "SELECT s.srvname AS \"%s\",\n"
6018 " pg_catalog.pg_get_userbyid(s.srvowner) AS \"%s\",\n"
6019 " f.fdwname AS \"%s\"",
6020 gettext_noop("Name"),
6021 gettext_noop("Owner"),
6022 gettext_noop("Foreign-data wrapper"));
6023
6024 if (verbose)
6025 {
6026 appendPQExpBufferStr(&buf, ",\n ");
6027 printACLColumn(&buf, "s.srvacl");
6029 ",\n"
6030 " s.srvtype AS \"%s\",\n"
6031 " s.srvversion AS \"%s\",\n"
6032 " CASE WHEN srvoptions IS NULL THEN '' ELSE "
6033 " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
6034 " pg_catalog.quote_ident(option_name) || ' ' || "
6035 " pg_catalog.quote_literal(option_value) FROM "
6036 " pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')' "
6037 " END AS \"%s\",\n"
6038 " d.description AS \"%s\"",
6039 gettext_noop("Type"),
6040 gettext_noop("Version"),
6041 gettext_noop("FDW options"),
6042 gettext_noop("Description"));
6043 }
6044
6046 "\nFROM pg_catalog.pg_foreign_server s\n"
6047 " JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw\n");
6048
6049 if (verbose)
6051 "LEFT JOIN pg_catalog.pg_description d\n "
6052 "ON d.classoid = s.tableoid AND d.objoid = s.oid "
6053 "AND d.objsubid = 0\n");
6054
6055 if (!validateSQLNamePattern(&buf, pattern, false, false,
6056 NULL, "s.srvname", NULL, NULL,
6057 NULL, 1))
6058 {
6060 return false;
6061 }
6062
6063 appendPQExpBufferStr(&buf, "ORDER BY 1;");
6064
6065 res = PSQLexec(buf.data);
6067 if (!res)
6068 return false;
6069
6070 myopt.title = _("List of foreign servers");
6071 myopt.translate_header = true;
6072
6073 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6074
6075 PQclear(res);
6076 return true;
6077}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 6140 of file describe.c.

6141{
6143 PGresult *res;
6144 printQueryOpt myopt = pset.popt;
6145
6148 "SELECT n.nspname AS \"%s\",\n"
6149 " c.relname AS \"%s\",\n"
6150 " s.srvname AS \"%s\"",
6151 gettext_noop("Schema"),
6152 gettext_noop("Table"),
6153 gettext_noop("Server"));
6154
6155 if (verbose)
6157 ",\n CASE WHEN ftoptions IS NULL THEN '' ELSE "
6158 " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
6159 " pg_catalog.quote_ident(option_name) || ' ' || "
6160 " pg_catalog.quote_literal(option_value) FROM "
6161 " pg_catalog.pg_options_to_table(ftoptions)), ', ') || ')' "
6162 " END AS \"%s\",\n"
6163 " d.description AS \"%s\"",
6164 gettext_noop("FDW options"),
6165 gettext_noop("Description"));
6166
6168 "\nFROM pg_catalog.pg_foreign_table ft\n"
6169 " INNER JOIN pg_catalog.pg_class c"
6170 " ON c.oid = ft.ftrelid\n"
6171 " INNER JOIN pg_catalog.pg_namespace n"
6172 " ON n.oid = c.relnamespace\n"
6173 " INNER JOIN pg_catalog.pg_foreign_server s"
6174 " ON s.oid = ft.ftserver\n");
6175 if (verbose)
6177 " LEFT JOIN pg_catalog.pg_description d\n"
6178 " ON d.classoid = c.tableoid AND "
6179 "d.objoid = c.oid AND d.objsubid = 0\n");
6180
6181 if (!validateSQLNamePattern(&buf, pattern, false, false,
6182 "n.nspname", "c.relname", NULL,
6183 "pg_catalog.pg_table_is_visible(c.oid)",
6184 NULL, 3))
6185 {
6187 return false;
6188 }
6189
6190 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6191
6192 res = PSQLexec(buf.data);
6194 if (!res)
6195 return false;
6196
6197 myopt.title = _("List of foreign tables");
6198 myopt.translate_header = true;
6199
6200 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6201
6202 PQclear(res);
6203 return true;
6204}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 4506 of file describe.c.

4507{
4509 PGresult *res;
4510 printQueryOpt myopt = pset.popt;
4511
4513
4515 "SELECT l.lanname AS \"%s\",\n"
4516 " pg_catalog.pg_get_userbyid(l.lanowner) as \"%s\",\n"
4517 " l.lanpltrusted AS \"%s\"",
4518 gettext_noop("Name"),
4519 gettext_noop("Owner"),
4520 gettext_noop("Trusted"));
4521
4522 if (verbose)
4523 {
4525 ",\n NOT l.lanispl AS \"%s\",\n"
4526 " l.lanplcallfoid::pg_catalog.regprocedure AS \"%s\",\n"
4527 " l.lanvalidator::pg_catalog.regprocedure AS \"%s\",\n "
4528 "l.laninline::pg_catalog.regprocedure AS \"%s\",\n ",
4529 gettext_noop("Internal language"),
4530 gettext_noop("Call handler"),
4531 gettext_noop("Validator"),
4532 gettext_noop("Inline handler"));
4533 printACLColumn(&buf, "l.lanacl");
4534 }
4535
4537 ",\n d.description AS \"%s\""
4538 "\nFROM pg_catalog.pg_language l\n"
4539 "LEFT JOIN pg_catalog.pg_description d\n"
4540 " ON d.classoid = l.tableoid AND d.objoid = l.oid\n"
4541 " AND d.objsubid = 0\n",
4542 gettext_noop("Description"));
4543
4544 if (pattern)
4545 {
4546 if (!validateSQLNamePattern(&buf, pattern, false, false,
4547 NULL, "l.lanname", NULL, NULL,
4548 NULL, 2))
4549 {
4551 return false;
4552 }
4553 }
4554
4555 if (!showSystem && !pattern)
4556 appendPQExpBufferStr(&buf, "WHERE l.lanplcallfoid != 0\n");
4557
4558
4559 appendPQExpBufferStr(&buf, "ORDER BY 1;");
4560
4561 res = PSQLexec(buf.data);
4563 if (!res)
4564 return false;
4565
4566 myopt.title = _("List of languages");
4567 myopt.translate_header = true;
4568
4569 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4570
4571 PQclear(res);
4572 return true;
4573}

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

Referenced by exec_command_d().

◆ listLargeObjects()

bool listLargeObjects ( bool  verbose)

Definition at line 7354 of file describe.c.

7355{
7357 PGresult *res;
7358 printQueryOpt myopt = pset.popt;
7359
7361
7363 "SELECT oid as \"%s\",\n"
7364 " pg_catalog.pg_get_userbyid(lomowner) as \"%s\",\n ",
7365 gettext_noop("ID"),
7366 gettext_noop("Owner"));
7367
7368 if (verbose)
7369 {
7370 printACLColumn(&buf, "lomacl");
7371 appendPQExpBufferStr(&buf, ",\n ");
7372 }
7373
7375 "pg_catalog.obj_description(oid, 'pg_largeobject') as \"%s\"\n"
7376 "FROM pg_catalog.pg_largeobject_metadata\n"
7377 "ORDER BY oid",
7378 gettext_noop("Description"));
7379
7380 res = PSQLexec(buf.data);
7382 if (!res)
7383 return false;
7384
7385 myopt.title = _("Large objects");
7386 myopt.translate_header = true;
7387
7388 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7389
7390 PQclear(res);
7391 return true;
7392}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printACLColumn(), printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 6968 of file describe.c.

6970{
6972 PGresult *res;
6973 printQueryOpt myopt = pset.popt;
6974 bool have_where = false;
6975 static const bool translate_columns[] = {false, false, false, false, false, false, false};
6976
6978
6980 "SELECT\n"
6981 " am.amname AS \"%s\",\n"
6982 " pg_catalog.format_type(c.opcintype, NULL) AS \"%s\",\n"
6983 " CASE\n"
6984 " WHEN c.opckeytype <> 0 AND c.opckeytype <> c.opcintype\n"
6985 " THEN pg_catalog.format_type(c.opckeytype, NULL)\n"
6986 " ELSE NULL\n"
6987 " END AS \"%s\",\n"
6988 " CASE\n"
6989 " WHEN pg_catalog.pg_opclass_is_visible(c.oid)\n"
6990 " THEN pg_catalog.format('%%I', c.opcname)\n"
6991 " ELSE pg_catalog.format('%%I.%%I', n.nspname, c.opcname)\n"
6992 " END AS \"%s\",\n"
6993 " (CASE WHEN c.opcdefault\n"
6994 " THEN '%s'\n"
6995 " ELSE '%s'\n"
6996 " END) AS \"%s\"",
6997 gettext_noop("AM"),
6998 gettext_noop("Input type"),
6999 gettext_noop("Storage type"),
7000 gettext_noop("Operator class"),
7001 gettext_noop("yes"),
7002 gettext_noop("no"),
7003 gettext_noop("Default?"));
7004 if (verbose)
7006 ",\n CASE\n"
7007 " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7008 " THEN pg_catalog.format('%%I', of.opfname)\n"
7009 " ELSE pg_catalog.format('%%I.%%I', ofn.nspname, of.opfname)\n"
7010 " END AS \"%s\",\n"
7011 " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n",
7012 gettext_noop("Operator family"),
7013 gettext_noop("Owner"));
7015 "\nFROM pg_catalog.pg_opclass c\n"
7016 " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n"
7017 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n"
7018 " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n"
7019 " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n");
7020 if (verbose)
7022 " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n"
7023 " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
7024
7025 if (access_method_pattern)
7026 if (!validateSQLNamePattern(&buf, access_method_pattern,
7027 false, false, NULL, "am.amname", NULL, NULL,
7028 &have_where, 1))
7029 goto error_return;
7030 if (type_pattern)
7031 {
7032 /* Match type name pattern against either internal or external name */
7033 if (!validateSQLNamePattern(&buf, type_pattern, have_where, false,
7034 "tn.nspname", "t.typname",
7035 "pg_catalog.format_type(t.oid, NULL)",
7036 "pg_catalog.pg_type_is_visible(t.oid)",
7037 NULL, 3))
7038 goto error_return;
7039 }
7040
7041 appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
7042 res = PSQLexec(buf.data);
7044 if (!res)
7045 return false;
7046
7047 myopt.title = _("List of operator classes");
7048 myopt.translate_header = true;
7049 myopt.translate_columns = translate_columns;
7050 myopt.n_translate_columns = lengthof(translate_columns);
7051
7052 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7053
7054 PQclear(res);
7055 return true;
7056
7057error_return:
7059 return false;
7060}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 7069 of file describe.c.

7071{
7073 PGresult *res;
7074 printQueryOpt myopt = pset.popt;
7075 bool have_where = false;
7076 static const bool translate_columns[] = {false, false, false, false};
7077
7079
7081 "SELECT\n"
7082 " am.amname AS \"%s\",\n"
7083 " CASE\n"
7084 " WHEN pg_catalog.pg_opfamily_is_visible(f.oid)\n"
7085 " THEN pg_catalog.format('%%I', f.opfname)\n"
7086 " ELSE pg_catalog.format('%%I.%%I', n.nspname, f.opfname)\n"
7087 " END AS \"%s\",\n"
7088 " (SELECT\n"
7089 " pg_catalog.string_agg(pg_catalog.format_type(oc.opcintype, NULL), ', ')\n"
7090 " FROM pg_catalog.pg_opclass oc\n"
7091 " WHERE oc.opcfamily = f.oid) \"%s\"",
7092 gettext_noop("AM"),
7093 gettext_noop("Operator family"),
7094 gettext_noop("Applicable types"));
7095 if (verbose)
7097 ",\n pg_catalog.pg_get_userbyid(f.opfowner) AS \"%s\"\n",
7098 gettext_noop("Owner"));
7100 "\nFROM pg_catalog.pg_opfamily f\n"
7101 " LEFT JOIN pg_catalog.pg_am am on am.oid = f.opfmethod\n"
7102 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = f.opfnamespace\n");
7103
7104 if (access_method_pattern)
7105 if (!validateSQLNamePattern(&buf, access_method_pattern,
7106 false, false, NULL, "am.amname", NULL, NULL,
7107 &have_where, 1))
7108 goto error_return;
7109 if (type_pattern)
7110 {
7112 " %s EXISTS (\n"
7113 " SELECT 1\n"
7114 " FROM pg_catalog.pg_type t\n"
7115 " JOIN pg_catalog.pg_opclass oc ON oc.opcintype = t.oid\n"
7116 " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"
7117 " WHERE oc.opcfamily = f.oid\n",
7118 have_where ? "AND" : "WHERE");
7119 /* Match type name pattern against either internal or external name */
7120 if (!validateSQLNamePattern(&buf, type_pattern, true, false,
7121 "tn.nspname", "t.typname",
7122 "pg_catalog.format_type(t.oid, NULL)",
7123 "pg_catalog.pg_type_is_visible(t.oid)",
7124 NULL, 3))
7125 goto error_return;
7126 appendPQExpBufferStr(&buf, " )\n");
7127 }
7128
7129 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
7130 res = PSQLexec(buf.data);
7132 if (!res)
7133 return false;
7134
7135 myopt.title = _("List of operator families");
7136 myopt.translate_header = true;
7137 myopt.translate_columns = translate_columns;
7138 myopt.n_translate_columns = lengthof(translate_columns);
7139
7140 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7141
7142 PQclear(res);
7143 return true;
7144
7145error_return:
7147 return false;
7148}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 7265 of file describe.c.

7267{
7269 PGresult *res;
7270 printQueryOpt myopt = pset.popt;
7271 bool have_where = false;
7272 static const bool translate_columns[] = {false, false, false, false, false, false};
7273
7275
7277 "SELECT\n"
7278 " am.amname AS \"%s\",\n"
7279 " CASE\n"
7280 " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7281 " THEN pg_catalog.format('%%I', of.opfname)\n"
7282 " ELSE pg_catalog.format('%%I.%%I', ns.nspname, of.opfname)\n"
7283 " END AS \"%s\",\n"
7284 " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n"
7285 " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n"
7286 " ap.amprocnum AS \"%s\"\n",
7287 gettext_noop("AM"),
7288 gettext_noop("Operator family"),
7289 gettext_noop("Registered left type"),
7290 gettext_noop("Registered right type"),
7291 gettext_noop("Number"));
7292
7293 if (!verbose)
7295 ", p.proname AS \"%s\"\n",
7296 gettext_noop("Function"));
7297 else
7299 ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n",
7300 gettext_noop("Function"));
7301
7303 "FROM pg_catalog.pg_amproc ap\n"
7304 " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n"
7305 " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n"
7306 " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n"
7307 " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
7308
7309 if (access_method_pattern)
7310 {
7311 if (!validateSQLNamePattern(&buf, access_method_pattern,
7312 false, false, NULL, "am.amname",
7313 NULL, NULL,
7314 &have_where, 1))
7315 goto error_return;
7316 }
7317 if (family_pattern)
7318 {
7319 if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
7320 "ns.nspname", "of.opfname", NULL, NULL,
7321 NULL, 3))
7322 goto error_return;
7323 }
7324
7325 appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7326 " ap.amproclefttype = ap.amprocrighttype DESC,\n"
7327 " 3, 4, 5;");
7328
7329 res = PSQLexec(buf.data);
7331 if (!res)
7332 return false;
7333
7334 myopt.title = _("List of support functions of operator families");
7335 myopt.translate_header = true;
7336 myopt.translate_columns = translate_columns;
7337 myopt.n_translate_columns = lengthof(translate_columns);
7338
7339 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7340
7341 PQclear(res);
7342 return true;
7343
7344error_return:
7346 return false;
7347}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 7158 of file describe.c.

7160{
7162 PGresult *res;
7163 printQueryOpt myopt = pset.popt;
7164 bool have_where = false;
7165
7166 static const bool translate_columns[] = {false, false, false, false, false, false, true};
7167
7169
7171 "SELECT\n"
7172 " am.amname AS \"%s\",\n"
7173 " CASE\n"
7174 " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n"
7175 " THEN pg_catalog.format('%%I', of.opfname)\n"
7176 " ELSE pg_catalog.format('%%I.%%I', nsf.nspname, of.opfname)\n"
7177 " END AS \"%s\",\n"
7178 " o.amopopr::pg_catalog.regoperator AS \"%s\"\n,"
7179 " o.amopstrategy AS \"%s\",\n"
7180 " CASE o.amoppurpose\n"
7181 " WHEN " CppAsString2(AMOP_ORDER) " THEN '%s'\n"
7182 " WHEN " CppAsString2(AMOP_SEARCH) " THEN '%s'\n"
7183 " END AS \"%s\"\n",
7184 gettext_noop("AM"),
7185 gettext_noop("Operator family"),
7186 gettext_noop("Operator"),
7187 gettext_noop("Strategy"),
7188 gettext_noop("ordering"),
7189 gettext_noop("search"),
7190 gettext_noop("Purpose"));
7191
7192 if (verbose)
7194 ", ofs.opfname AS \"%s\",\n"
7195 " CASE\n"
7196 " WHEN p.proleakproof THEN '%s'\n"
7197 " ELSE '%s'\n"
7198 " END AS \"%s\"\n",
7199 gettext_noop("Sort opfamily"),
7200 gettext_noop("yes"),
7201 gettext_noop("no"),
7202 gettext_noop("Leakproof?"));
7204 "FROM pg_catalog.pg_amop o\n"
7205 " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n"
7206 " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n"
7207 " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n");
7208 if (verbose)
7210 " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n"
7211 " LEFT JOIN pg_catalog.pg_operator op ON op.oid = o.amopopr\n"
7212 " LEFT JOIN pg_catalog.pg_proc p ON p.oid = op.oprcode\n");
7213
7214 if (access_method_pattern)
7215 {
7216 if (!validateSQLNamePattern(&buf, access_method_pattern,
7217 false, false, NULL, "am.amname",
7218 NULL, NULL,
7219 &have_where, 1))
7220 goto error_return;
7221 }
7222
7223 if (family_pattern)
7224 {
7225 if (!validateSQLNamePattern(&buf, family_pattern, have_where, false,
7226 "nsf.nspname", "of.opfname", NULL, NULL,
7227 NULL, 3))
7228 goto error_return;
7229 }
7230
7231 appendPQExpBufferStr(&buf, "ORDER BY 1, 2,\n"
7232 " o.amoplefttype = o.amoprighttype DESC,\n"
7233 " pg_catalog.format_type(o.amoplefttype, NULL),\n"
7234 " pg_catalog.format_type(o.amoprighttype, NULL),\n"
7235 " o.amopstrategy;");
7236
7237 res = PSQLexec(buf.data);
7239 if (!res)
7240 return false;
7241
7242 myopt.title = _("List of operators of operator families");
7243 myopt.translate_header = true;
7244 myopt.translate_columns = translate_columns;
7245 myopt.n_translate_columns = lengthof(translate_columns);
7246
7247 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
7248
7249 PQclear(res);
7250 return true;
7251
7252error_return:
7254 return false;
7255}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 4296 of file describe.c.

4297{
4298 bool showTables = strchr(reltypes, 't') != NULL;
4299 bool showIndexes = strchr(reltypes, 'i') != NULL;
4300 bool showNested = strchr(reltypes, 'n') != NULL;
4302 PQExpBufferData title;
4303 PGresult *res;
4304 printQueryOpt myopt = pset.popt;
4305 bool translate_columns[] = {false, false, false, false, false, false, false, false, false, false};
4306 const char *tabletitle;
4307 bool mixed_output = false;
4308
4309 /*
4310 * Note: Declarative table partitioning is only supported as of Pg 10.0.
4311 */
4312 if (pset.sversion < 100000)
4313 {
4314 char sverbuf[32];
4315
4316 pg_log_error("The server (version %s) does not support declarative table partitioning.",
4318 sverbuf, sizeof(sverbuf)));
4319 return true;
4320 }
4321
4322 /* If no relation kind was selected, show them all */
4323 if (!showTables && !showIndexes)
4324 showTables = showIndexes = true;
4325
4326 if (showIndexes && !showTables)
4327 tabletitle = _("List of partitioned indexes"); /* \dPi */
4328 else if (showTables && !showIndexes)
4329 tabletitle = _("List of partitioned tables"); /* \dPt */
4330 else
4331 {
4332 /* show all kinds */
4333 tabletitle = _("List of partitioned relations");
4334 mixed_output = true;
4335 }
4336
4338
4340 "SELECT n.nspname as \"%s\",\n"
4341 " c.relname as \"%s\",\n"
4342 " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
4343 gettext_noop("Schema"),
4344 gettext_noop("Name"),
4345 gettext_noop("Owner"));
4346
4347 if (mixed_output)
4348 {
4350 ",\n CASE c.relkind"
4351 " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
4352 " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
4353 " END as \"%s\"",
4354 gettext_noop("partitioned table"),
4355 gettext_noop("partitioned index"),
4356 gettext_noop("Type"));
4357
4358 translate_columns[3] = true;
4359 }
4360
4361 if (showNested || pattern)
4363 ",\n inh.inhparent::pg_catalog.regclass as \"%s\"",
4364 gettext_noop("Parent name"));
4365
4366 if (showIndexes)
4368 ",\n c2.oid::pg_catalog.regclass as \"%s\"",
4369 gettext_noop("Table"));
4370
4371 if (verbose)
4372 {
4373 /*
4374 * Table access methods were introduced in v12, and can be set on
4375 * partitioned tables since v17.
4376 */
4377 appendPQExpBuffer(&buf, ",\n am.amname as \"%s\"",
4378 gettext_noop("Access method"));
4379
4380 if (showNested)
4381 {
4383 ",\n s.dps as \"%s\"",
4384 gettext_noop("Leaf partition size"));
4386 ",\n s.tps as \"%s\"",
4387 gettext_noop("Total size"));
4388 }
4389 else
4390 /* Sizes of all partitions are considered in this case. */
4392 ",\n s.tps as \"%s\"",
4393 gettext_noop("Total size"));
4394
4396 ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
4397 gettext_noop("Description"));
4398 }
4399
4401 "\nFROM pg_catalog.pg_class c"
4402 "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
4403
4404 if (showIndexes)
4406 "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid"
4407 "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
4408
4409 if (showNested || pattern)
4411 "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
4412
4413 if (verbose)
4414 {
4416 "\n LEFT JOIN pg_catalog.pg_am am ON c.relam = am.oid");
4417
4418 if (pset.sversion < 120000)
4419 {
4421 ",\n LATERAL (WITH RECURSIVE d\n"
4422 " AS (SELECT inhrelid AS oid, 1 AS level\n"
4423 " FROM pg_catalog.pg_inherits\n"
4424 " WHERE inhparent = c.oid\n"
4425 " UNION ALL\n"
4426 " SELECT inhrelid, level + 1\n"
4427 " FROM pg_catalog.pg_inherits i\n"
4428 " JOIN d ON i.inhparent = d.oid)\n"
4429 " SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.pg_table_size("
4430 "d.oid))) AS tps,\n"
4431 " pg_catalog.pg_size_pretty(sum("
4432 "\n CASE WHEN d.level = 1"
4433 " THEN pg_catalog.pg_table_size(d.oid) ELSE 0 END)) AS dps\n"
4434 " FROM d) s");
4435 }
4436 else
4437 {
4438 /* PostgreSQL 12 has pg_partition_tree function */
4440 ",\n LATERAL (SELECT pg_catalog.pg_size_pretty(sum("
4441 "\n CASE WHEN ppt.isleaf AND ppt.level = 1"
4442 "\n THEN pg_catalog.pg_table_size(ppt.relid)"
4443 " ELSE 0 END)) AS dps"
4444 ",\n pg_catalog.pg_size_pretty(sum("
4445 "pg_catalog.pg_table_size(ppt.relid))) AS tps"
4446 "\n FROM pg_catalog.pg_partition_tree(c.oid) ppt) s");
4447 }
4448 }
4449
4450 appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
4451 if (showTables)
4452 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
4453 if (showIndexes)
4454 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
4455 appendPQExpBufferStr(&buf, "''"); /* dummy */
4456 appendPQExpBufferStr(&buf, ")\n");
4457
4458 appendPQExpBufferStr(&buf, !showNested && !pattern ?
4459 " AND NOT c.relispartition\n" : "");
4460
4461 if (!pattern)
4462 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4463 " AND n.nspname !~ '^pg_toast'\n"
4464 " AND n.nspname <> 'information_schema'\n");
4465
4466 if (!validateSQLNamePattern(&buf, pattern, true, false,
4467 "n.nspname", "c.relname", NULL,
4468 "pg_catalog.pg_table_is_visible(c.oid)",
4469 NULL, 3))
4470 {
4472 return false;
4473 }
4474
4475 appendPQExpBuffer(&buf, "ORDER BY \"Schema\", %s%s\"Name\";",
4476 mixed_output ? "\"Type\" DESC, " : "",
4477 showNested || pattern ? "\"Parent name\" NULLS FIRST, " : "");
4478
4479 res = PSQLexec(buf.data);
4481 if (!res)
4482 return false;
4483
4484 initPQExpBuffer(&title);
4485 appendPQExpBufferStr(&title, tabletitle);
4486
4487 myopt.title = title.data;
4488 myopt.translate_header = true;
4489 myopt.translate_columns = translate_columns;
4490 myopt.n_translate_columns = lengthof(translate_columns);
4491
4492 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4493
4494 termPQExpBuffer(&title);
4495
4496 PQclear(res);
4497 return true;
4498}

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, _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 6430 of file describe.c.

6431{
6433 PGresult *res;
6434 printQueryOpt myopt = pset.popt;
6435 static const bool translate_columns[] = {false, false, false, false, false, false, false, false, false, false};
6436
6437 if (pset.sversion < 100000)
6438 {
6439 char sverbuf[32];
6440
6441 pg_log_error("The server (version %s) does not support publications.",
6443 sverbuf, sizeof(sverbuf)));
6444 return true;
6445 }
6446
6448
6450 "SELECT pubname AS \"%s\",\n"
6451 " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n"
6452 " puballtables AS \"%s\"",
6453 gettext_noop("Name"),
6454 gettext_noop("Owner"),
6455 gettext_noop("All tables"));
6456
6457 if (pset.sversion >= 190000)
6459 ",\n puballsequences AS \"%s\"",
6460 gettext_noop("All sequences"));
6461
6463 ",\n pubinsert AS \"%s\",\n"
6464 " pubupdate AS \"%s\",\n"
6465 " pubdelete AS \"%s\"",
6466 gettext_noop("Inserts"),
6467 gettext_noop("Updates"),
6468 gettext_noop("Deletes"));
6469 if (pset.sversion >= 110000)
6471 ",\n pubtruncate AS \"%s\"",
6472 gettext_noop("Truncates"));
6473 if (pset.sversion >= 180000)
6475 ",\n (CASE pubgencols\n"
6476 " WHEN '%c' THEN 'none'\n"
6477 " WHEN '%c' THEN 'stored'\n"
6478 " END) AS \"%s\"",
6479 PUBLISH_GENCOLS_NONE,
6480 PUBLISH_GENCOLS_STORED,
6481 gettext_noop("Generated columns"));
6482 if (pset.sversion >= 130000)
6484 ",\n pubviaroot AS \"%s\"",
6485 gettext_noop("Via root"));
6486
6488 "\nFROM pg_catalog.pg_publication\n");
6489
6490 if (!validateSQLNamePattern(&buf, pattern, false, false,
6491 NULL, "pubname", NULL,
6492 NULL,
6493 NULL, 1))
6494 {
6496 return false;
6497 }
6498
6499 appendPQExpBufferStr(&buf, "ORDER BY 1;");
6500
6501 res = PSQLexec(buf.data);
6503 if (!res)
6504 return false;
6505
6506 myopt.title = _("List of publications");
6507 myopt.translate_header = true;
6508 myopt.translate_columns = translate_columns;
6509 myopt.n_translate_columns = lengthof(translate_columns);
6510
6511 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6512
6513 PQclear(res);
6514
6515 return true;
6516}

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, _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 5236 of file describe.c.

5237{
5239 PGresult *res;
5240 printQueryOpt myopt = pset.popt;
5241 int pub_schema_tuples = 0;
5242 char **footers = NULL;
5243
5246 "SELECT n.nspname AS \"%s\",\n"
5247 " pg_catalog.pg_get_userbyid(n.nspowner) AS \"%s\"",
5248 gettext_noop("Name"),
5249 gettext_noop("Owner"));
5250
5251 if (verbose)
5252 {
5253 appendPQExpBufferStr(&buf, ",\n ");
5254 printACLColumn(&buf, "n.nspacl");
5256 ",\n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \"%s\"",
5257 gettext_noop("Description"));
5258 }
5259
5261 "\nFROM pg_catalog.pg_namespace n\n");
5262
5263 if (!showSystem && !pattern)
5265 "WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'\n");
5266
5267 if (!validateSQLNamePattern(&buf, pattern,
5268 !showSystem && !pattern, false,
5269 NULL, "n.nspname", NULL,
5270 NULL,
5271 NULL, 2))
5272 goto error_return;
5273
5274 appendPQExpBufferStr(&buf, "ORDER BY 1;");
5275
5276 res = PSQLexec(buf.data);
5277 if (!res)
5278 goto error_return;
5279
5280 myopt.title = _("List of schemas");
5281 myopt.translate_header = true;
5282
5283 if (pattern && pset.sversion >= 150000)
5284 {
5285 PGresult *result;
5286 int i;
5287
5289 "SELECT pubname \n"
5290 "FROM pg_catalog.pg_publication p\n"
5291 " JOIN pg_catalog.pg_publication_namespace pn ON p.oid = pn.pnpubid\n"
5292 " JOIN pg_catalog.pg_namespace n ON n.oid = pn.pnnspid \n"
5293 "WHERE n.nspname = '%s'\n"
5294 "ORDER BY 1",
5295 pattern);
5296 result = PSQLexec(buf.data);
5297 if (!result)
5298 goto error_return;
5299 else
5300 pub_schema_tuples = PQntuples(result);
5301
5302 if (pub_schema_tuples > 0)
5303 {
5304 /*
5305 * Allocate memory for footers. Size of footers will be 1 (for
5306 * storing "Publications:" string) + publication schema mapping
5307 * count + 1 (for storing NULL).
5308 */
5309 footers = (char **) pg_malloc((1 + pub_schema_tuples + 1) * sizeof(char *));
5310 footers[0] = pg_strdup(_("Publications:"));
5311
5312 /* Might be an empty set - that's ok */
5313 for (i = 0; i < pub_schema_tuples; i++)
5314 {
5315 printfPQExpBuffer(&buf, " \"%s\"",
5316 PQgetvalue(result, i, 0));
5317
5318 footers[i + 1] = pg_strdup(buf.data);
5319 }
5320
5321 footers[i + 1] = NULL;
5322 myopt.footers = footers;
5323 }
5324
5325 PQclear(result);
5326 }
5327
5328 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5329
5331 PQclear(res);
5332
5333 /* Free the memory allocated for the footer */
5334 if (footers)
5335 {
5336 char **footer = NULL;
5337
5338 for (footer = footers; *footer; footer++)
5339 pg_free(*footer);
5340
5341 pg_free(footers);
5342 }
5343
5344 return true;
5345
5346error_return:
5348 return false;
5349}
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void pg_free(void *ptr)
Definition: fe_memutils.c:105
char ** footers
Definition: print.h:190

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, _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 4041 of file describe.c.

4042{
4043 bool showTables = strchr(tabtypes, 't') != NULL;
4044 bool showIndexes = strchr(tabtypes, 'i') != NULL;
4045 bool showViews = strchr(tabtypes, 'v') != NULL;
4046 bool showMatViews = strchr(tabtypes, 'm') != NULL;
4047 bool showSeq = strchr(tabtypes, 's') != NULL;
4048 bool showForeign = strchr(tabtypes, 'E') != NULL;
4049
4050 int ntypes;
4052 PGresult *res;
4053 printQueryOpt myopt = pset.popt;
4054 int cols_so_far;
4055 bool translate_columns[] = {false, false, true, false, false, false, false, false, false};
4056
4057 /* Count the number of explicitly-requested relation types */
4058 ntypes = showTables + showIndexes + showViews + showMatViews +
4059 showSeq + showForeign;
4060 /* If none, we default to \dtvmsE (but see also command.c) */
4061 if (ntypes == 0)
4062 showTables = showViews = showMatViews = showSeq = showForeign = true;
4063
4065
4067 "SELECT n.nspname as \"%s\",\n"
4068 " c.relname as \"%s\",\n"
4069 " CASE c.relkind"
4070 " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
4071 " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
4072 " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
4073 " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'"
4074 " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
4075 " WHEN " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'"
4076 " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
4077 " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
4078 " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'"
4079 " END as \"%s\",\n"
4080 " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
4081 gettext_noop("Schema"),
4082 gettext_noop("Name"),
4083 gettext_noop("table"),
4084 gettext_noop("view"),
4085 gettext_noop("materialized view"),
4086 gettext_noop("index"),
4087 gettext_noop("sequence"),
4088 gettext_noop("TOAST table"),
4089 gettext_noop("foreign table"),
4090 gettext_noop("partitioned table"),
4091 gettext_noop("partitioned index"),
4092 gettext_noop("Type"),
4093 gettext_noop("Owner"));
4094 cols_so_far = 4;
4095
4096 if (showIndexes)
4097 {
4099 ",\n c2.relname as \"%s\"",
4100 gettext_noop("Table"));
4101 cols_so_far++;
4102 }
4103
4104 if (verbose)
4105 {
4106 /*
4107 * Show whether a relation is permanent, temporary, or unlogged.
4108 */
4110 ",\n CASE c.relpersistence "
4111 "WHEN " CppAsString2(RELPERSISTENCE_PERMANENT) " THEN '%s' "
4112 "WHEN " CppAsString2(RELPERSISTENCE_TEMP) " THEN '%s' "
4113 "WHEN " CppAsString2(RELPERSISTENCE_UNLOGGED) " THEN '%s' "
4114 "END as \"%s\"",
4115 gettext_noop("permanent"),
4116 gettext_noop("temporary"),
4117 gettext_noop("unlogged"),
4118 gettext_noop("Persistence"));
4119 translate_columns[cols_so_far] = true;
4120
4121 /*
4122 * We don't bother to count cols_so_far below here, as there's no need
4123 * to; this might change with future additions to the output columns.
4124 */
4125
4126 /*
4127 * Access methods exist for tables, materialized views and indexes.
4128 * This has been introduced in PostgreSQL 12 for tables.
4129 */
4130 if (pset.sversion >= 120000 && !pset.hide_tableam &&
4131 (showTables || showMatViews || showIndexes))
4133 ",\n am.amname as \"%s\"",
4134 gettext_noop("Access method"));
4135
4137 ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\""
4138 ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
4139 gettext_noop("Size"),
4140 gettext_noop("Description"));
4141 }
4142
4144 "\nFROM pg_catalog.pg_class c"
4145 "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
4146
4147 if (pset.sversion >= 120000 && !pset.hide_tableam &&
4148 (showTables || showMatViews || showIndexes))
4150 "\n LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam");
4151
4152 if (showIndexes)
4154 "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid"
4155 "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
4156
4157 appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN (");
4158 if (showTables)
4159 {
4160 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) ","
4161 CppAsString2(RELKIND_PARTITIONED_TABLE) ",");
4162 /* with 'S' or a pattern, allow 't' to match TOAST tables too */
4163 if (showSystem || pattern)
4164 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ",");
4165 }
4166 if (showViews)
4167 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ",");
4168 if (showMatViews)
4169 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ",");
4170 if (showIndexes)
4171 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) ","
4172 CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
4173 if (showSeq)
4174 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ",");
4175 if (showSystem || pattern)
4176 appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */
4177 if (showForeign)
4178 appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ",");
4179
4180 appendPQExpBufferStr(&buf, "''"); /* dummy */
4181 appendPQExpBufferStr(&buf, ")\n");
4182
4183 if (!showSystem && !pattern)
4184 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
4185 " AND n.nspname !~ '^pg_toast'\n"
4186 " AND n.nspname <> 'information_schema'\n");
4187
4188 if (!validateSQLNamePattern(&buf, pattern, true, false,
4189 "n.nspname", "c.relname", NULL,
4190 "pg_catalog.pg_table_is_visible(c.oid)",
4191 NULL, 3))
4192 {
4194 return false;
4195 }
4196
4197 appendPQExpBufferStr(&buf, "ORDER BY 1,2;");
4198
4199 res = PSQLexec(buf.data);
4201 if (!res)
4202 return false;
4203
4204 /*
4205 * Most functions in this file are content to print an empty table when
4206 * there are no matching objects. We intentionally deviate from that
4207 * here, but only in !quiet mode, for historical reasons.
4208 */
4209 if (PQntuples(res) == 0 && !pset.quiet)
4210 {
4211 if (pattern)
4212 {
4213 if (ntypes != 1)
4214 pg_log_error("Did not find any relations named \"%s\".",
4215 pattern);
4216 else if (showTables)
4217 pg_log_error("Did not find any tables named \"%s\".",
4218 pattern);
4219 else if (showIndexes)
4220 pg_log_error("Did not find any indexes named \"%s\".",
4221 pattern);
4222 else if (showViews)
4223 pg_log_error("Did not find any views named \"%s\".",
4224 pattern);
4225 else if (showMatViews)
4226 pg_log_error("Did not find any materialized views named \"%s\".",
4227 pattern);
4228 else if (showSeq)
4229 pg_log_error("Did not find any sequences named \"%s\".",
4230 pattern);
4231 else if (showForeign)
4232 pg_log_error("Did not find any foreign tables named \"%s\".",
4233 pattern);
4234 else /* should not get here */
4235 pg_log_error_internal("Did not find any ??? named \"%s\".",
4236 pattern);
4237 }
4238 else
4239 {
4240 if (ntypes != 1)
4241 pg_log_error("Did not find any relations.");
4242 else if (showTables)
4243 pg_log_error("Did not find any tables.");
4244 else if (showIndexes)
4245 pg_log_error("Did not find any indexes.");
4246 else if (showViews)
4247 pg_log_error("Did not find any views.");
4248 else if (showMatViews)
4249 pg_log_error("Did not find any materialized views.");
4250 else if (showSeq)
4251 pg_log_error("Did not find any sequences.");
4252 else if (showForeign)
4253 pg_log_error("Did not find any foreign tables.");
4254 else /* should not get here */
4255 pg_log_error_internal("Did not find any ??? relations.");
4256 }
4257 }
4258 else
4259 {
4260 myopt.title =
4261 (ntypes != 1) ? _("List of relations") :
4262 (showTables) ? _("List of tables") :
4263 (showIndexes) ? _("List of indexes") :
4264 (showViews) ? _("List of views") :
4265 (showMatViews) ? _("List of materialized views") :
4266 (showSeq) ? _("List of sequences") :
4267 (showForeign) ? _("List of foreign tables") :
4268 "List of ???"; /* should not get here */
4269 myopt.translate_header = true;
4270 myopt.translate_columns = translate_columns;
4271 myopt.n_translate_columns = lengthof(translate_columns);
4272
4273 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
4274 }
4275
4276 PQclear(res);
4277 return true;
4278}
#define pg_log_error_internal(...)
Definition: logging.h:160
bool hide_tableam
Definition: settings.h:171

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, CppAsString2, gettext_noop, _psqlSettings::hide_tableam, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, pg_log_error, pg_log_error_internal, _psqlSettings::popt, PQclear, PQntuples, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, _psqlSettings::quiet, _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 5734 of file describe.c.

5735{
5737 PGresult *res;
5738 printQueryOpt myopt = pset.popt;
5739
5740 if (verbose)
5741 return listTSConfigsVerbose(pattern);
5742
5744
5746 "SELECT\n"
5747 " n.nspname as \"%s\",\n"
5748 " c.cfgname as \"%s\",\n"
5749 " pg_catalog.obj_description(c.oid, 'pg_ts_config') as \"%s\"\n"
5750 "FROM pg_catalog.pg_ts_config c\n"
5751 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace\n",
5752 gettext_noop("Schema"),
5753 gettext_noop("Name"),
5754 gettext_noop("Description")
5755 );
5756
5757 if (!validateSQLNamePattern(&buf, pattern, false, false,
5758 "n.nspname", "c.cfgname", NULL,
5759 "pg_catalog.pg_ts_config_is_visible(c.oid)",
5760 NULL, 3))
5761 {
5763 return false;
5764 }
5765
5766 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5767
5768 res = PSQLexec(buf.data);
5770 if (!res)
5771 return false;
5772
5773 myopt.title = _("List of text search configurations");
5774 myopt.translate_header = true;
5775
5776 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5777
5778 PQclear(res);
5779 return true;
5780}
static bool listTSConfigsVerbose(const char *pattern)
Definition: describe.c:5783

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), listTSConfigsVerbose(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 5604 of file describe.c.

5605{
5607 PGresult *res;
5608 printQueryOpt myopt = pset.popt;
5609
5611
5613 "SELECT\n"
5614 " n.nspname as \"%s\",\n"
5615 " d.dictname as \"%s\",\n",
5616 gettext_noop("Schema"),
5617 gettext_noop("Name"));
5618
5619 if (verbose)
5620 {
5622 " ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM\n"
5623 " pg_catalog.pg_ts_template t\n"
5624 " LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace\n"
5625 " WHERE d.dicttemplate = t.oid ) AS \"%s\",\n"
5626 " d.dictinitoption as \"%s\",\n",
5627 gettext_noop("Template"),
5628 gettext_noop("Init options"));
5629 }
5630
5632 " pg_catalog.obj_description(d.oid, 'pg_ts_dict') as \"%s\"\n",
5633 gettext_noop("Description"));
5634
5635 appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_dict d\n"
5636 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace\n");
5637
5638 if (!validateSQLNamePattern(&buf, pattern, false, false,
5639 "n.nspname", "d.dictname", NULL,
5640 "pg_catalog.pg_ts_dict_is_visible(d.oid)",
5641 NULL, 3))
5642 {
5644 return false;
5645 }
5646
5647 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5648
5649 res = PSQLexec(buf.data);
5651 if (!res)
5652 return false;
5653
5654 myopt.title = _("List of text search dictionaries");
5655 myopt.translate_header = true;
5656
5657 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5658
5659 PQclear(res);
5660 return true;
5661}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 5357 of file describe.c.

5358{
5360 PGresult *res;
5361 printQueryOpt myopt = pset.popt;
5362
5363 if (verbose)
5364 return listTSParsersVerbose(pattern);
5365
5367
5369 "SELECT\n"
5370 " n.nspname as \"%s\",\n"
5371 " p.prsname as \"%s\",\n"
5372 " pg_catalog.obj_description(p.oid, 'pg_ts_parser') as \"%s\"\n"
5373 "FROM pg_catalog.pg_ts_parser p\n"
5374 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace\n",
5375 gettext_noop("Schema"),
5376 gettext_noop("Name"),
5377 gettext_noop("Description")
5378 );
5379
5380 if (!validateSQLNamePattern(&buf, pattern, false, false,
5381 "n.nspname", "p.prsname", NULL,
5382 "pg_catalog.pg_ts_parser_is_visible(p.oid)",
5383 NULL, 3))
5384 {
5386 return false;
5387 }
5388
5389 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5390
5391 res = PSQLexec(buf.data);
5393 if (!res)
5394 return false;
5395
5396 myopt.title = _("List of text search parsers");
5397 myopt.translate_header = true;
5398
5399 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5400
5401 PQclear(res);
5402 return true;
5403}
static bool listTSParsersVerbose(const char *pattern)
Definition: describe.c:5409

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), listTSParsersVerbose(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 5669 of file describe.c.

5670{
5672 PGresult *res;
5673 printQueryOpt myopt = pset.popt;
5674
5676
5677 if (verbose)
5679 "SELECT\n"
5680 " n.nspname AS \"%s\",\n"
5681 " t.tmplname AS \"%s\",\n"
5682 " t.tmplinit::pg_catalog.regproc AS \"%s\",\n"
5683 " t.tmpllexize::pg_catalog.regproc AS \"%s\",\n"
5684 " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5685 gettext_noop("Schema"),
5686 gettext_noop("Name"),
5687 gettext_noop("Init"),
5688 gettext_noop("Lexize"),
5689 gettext_noop("Description"));
5690 else
5692 "SELECT\n"
5693 " n.nspname AS \"%s\",\n"
5694 " t.tmplname AS \"%s\",\n"
5695 " pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \"%s\"\n",
5696 gettext_noop("Schema"),
5697 gettext_noop("Name"),
5698 gettext_noop("Description"));
5699
5700 appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_ts_template t\n"
5701 "LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace\n");
5702
5703 if (!validateSQLNamePattern(&buf, pattern, false, false,
5704 "n.nspname", "t.tmplname", NULL,
5705 "pg_catalog.pg_ts_template_is_visible(t.oid)",
5706 NULL, 3))
5707 {
5709 return false;
5710 }
5711
5712 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
5713
5714 res = PSQLexec(buf.data);
5716 if (!res)
5717 return false;
5718
5719 myopt.title = _("List of text search templates");
5720 myopt.translate_header = true;
5721
5722 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
5723
5724 PQclear(res);
5725 return true;
5726}

References _, appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 6085 of file describe.c.

6086{
6088 PGresult *res;
6089 printQueryOpt myopt = pset.popt;
6090
6093 "SELECT um.srvname AS \"%s\",\n"
6094 " um.usename AS \"%s\"",
6095 gettext_noop("Server"),
6096 gettext_noop("User name"));
6097
6098 if (verbose)
6100 ",\n CASE WHEN umoptions IS NULL THEN '' ELSE "
6101 " '(' || pg_catalog.array_to_string(ARRAY(SELECT "
6102 " pg_catalog.quote_ident(option_name) || ' ' || "
6103 " pg_catalog.quote_literal(option_value) FROM "
6104 " pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' "
6105 " END AS \"%s\"",
6106 gettext_noop("FDW options"));
6107
6108 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_user_mappings um\n");
6109
6110 if (!validateSQLNamePattern(&buf, pattern, false, false,
6111 NULL, "um.srvname", "um.usename", NULL,
6112 NULL, 1))
6113 {
6115 return false;
6116 }
6117
6118 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
6119
6120 res = PSQLexec(buf.data);
6122 if (!res)
6123 return false;
6124
6125 myopt.title = _("List of user mappings");
6126 myopt.translate_header = true;
6127
6128 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
6129
6130 PQclear(res);
6131 return true;
6132}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), _psqlSettings::logfile, _psqlSettings::popt, PQclear, printfPQExpBuffer(), printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 1295 of file describe.c.

1296{
1298 PGresult *res;
1299 printQueryOpt myopt = pset.popt;
1300 static const bool translate_columns[] = {false, false, true, false};
1301
1303
1305 "SELECT DISTINCT tt.nspname AS \"%s\", tt.name AS \"%s\", tt.object AS \"%s\", d.description AS \"%s\"\n"
1306 "FROM (\n",
1307 gettext_noop("Schema"),
1308 gettext_noop("Name"),
1309 gettext_noop("Object"),
1310 gettext_noop("Description"));
1311
1312 /* Table constraint descriptions */
1314 " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
1315 " n.nspname as nspname,\n"
1316 " CAST(pgc.conname AS pg_catalog.text) as name,"
1317 " CAST('%s' AS pg_catalog.text) as object\n"
1318 " FROM pg_catalog.pg_constraint pgc\n"
1319 " JOIN pg_catalog.pg_class c "
1320 "ON c.oid = pgc.conrelid\n"
1321 " LEFT JOIN pg_catalog.pg_namespace n "
1322 " ON n.oid = c.relnamespace\n",
1323 gettext_noop("table constraint"));
1324
1325 if (!showSystem && !pattern)
1326 appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1327 " AND n.nspname <> 'information_schema'\n");
1328
1329 if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
1330 false, "n.nspname", "pgc.conname", NULL,
1331 "pg_catalog.pg_table_is_visible(c.oid)",
1332 NULL, 3))
1333 goto error_return;
1334
1335 /* Domain constraint descriptions */
1337 "UNION ALL\n"
1338 " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n"
1339 " n.nspname as nspname,\n"
1340 " CAST(pgc.conname AS pg_catalog.text) as name,"
1341 " CAST('%s' AS pg_catalog.text) as object\n"
1342 " FROM pg_catalog.pg_constraint pgc\n"
1343 " JOIN pg_catalog.pg_type t "
1344 "ON t.oid = pgc.contypid\n"
1345 " LEFT JOIN pg_catalog.pg_namespace n "
1346 " ON n.oid = t.typnamespace\n",
1347 gettext_noop("domain constraint"));
1348
1349 if (!showSystem && !pattern)
1350 appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1351 " AND n.nspname <> 'information_schema'\n");
1352
1353 if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern,
1354 false, "n.nspname", "pgc.conname", NULL,
1355 "pg_catalog.pg_type_is_visible(t.oid)",
1356 NULL, 3))
1357 goto error_return;
1358
1359 /* Operator class descriptions */
1361 "UNION ALL\n"
1362 " SELECT o.oid as oid, o.tableoid as tableoid,\n"
1363 " n.nspname as nspname,\n"
1364 " CAST(o.opcname AS pg_catalog.text) as name,\n"
1365 " CAST('%s' AS pg_catalog.text) as object\n"
1366 " FROM pg_catalog.pg_opclass o\n"
1367 " JOIN pg_catalog.pg_am am ON "
1368 "o.opcmethod = am.oid\n"
1369 " JOIN pg_catalog.pg_namespace n ON "
1370 "n.oid = o.opcnamespace\n",
1371 gettext_noop("operator class"));
1372
1373 if (!showSystem && !pattern)
1374 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1375 " AND n.nspname <> 'information_schema'\n");
1376
1377 if (!validateSQLNamePattern(&buf, pattern, true, false,
1378 "n.nspname", "o.opcname", NULL,
1379 "pg_catalog.pg_opclass_is_visible(o.oid)",
1380 NULL, 3))
1381 goto error_return;
1382
1383 /* Operator family descriptions */
1385 "UNION ALL\n"
1386 " SELECT opf.oid as oid, opf.tableoid as tableoid,\n"
1387 " n.nspname as nspname,\n"
1388 " CAST(opf.opfname AS pg_catalog.text) AS name,\n"
1389 " CAST('%s' AS pg_catalog.text) as object\n"
1390 " FROM pg_catalog.pg_opfamily opf\n"
1391 " JOIN pg_catalog.pg_am am "
1392 "ON opf.opfmethod = am.oid\n"
1393 " JOIN pg_catalog.pg_namespace n "
1394 "ON opf.opfnamespace = n.oid\n",
1395 gettext_noop("operator family"));
1396
1397 if (!showSystem && !pattern)
1398 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1399 " AND n.nspname <> 'information_schema'\n");
1400
1401 if (!validateSQLNamePattern(&buf, pattern, true, false,
1402 "n.nspname", "opf.opfname", NULL,
1403 "pg_catalog.pg_opfamily_is_visible(opf.oid)",
1404 NULL, 3))
1405 goto error_return;
1406
1407 /* Rule descriptions (ignore rules for views) */
1409 "UNION ALL\n"
1410 " SELECT r.oid as oid, r.tableoid as tableoid,\n"
1411 " n.nspname as nspname,\n"
1412 " CAST(r.rulename AS pg_catalog.text) as name,"
1413 " CAST('%s' AS pg_catalog.text) as object\n"
1414 " FROM pg_catalog.pg_rewrite r\n"
1415 " JOIN pg_catalog.pg_class c ON c.oid = r.ev_class\n"
1416 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
1417 " WHERE r.rulename != '_RETURN'\n",
1418 gettext_noop("rule"));
1419
1420 if (!showSystem && !pattern)
1421 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1422 " AND n.nspname <> 'information_schema'\n");
1423
1424 if (!validateSQLNamePattern(&buf, pattern, true, false,
1425 "n.nspname", "r.rulename", NULL,
1426 "pg_catalog.pg_table_is_visible(c.oid)",
1427 NULL, 3))
1428 goto error_return;
1429
1430 /* Trigger descriptions */
1432 "UNION ALL\n"
1433 " SELECT t.oid as oid, t.tableoid as tableoid,\n"
1434 " n.nspname as nspname,\n"
1435 " CAST(t.tgname AS pg_catalog.text) as name,"
1436 " CAST('%s' AS pg_catalog.text) as object\n"
1437 " FROM pg_catalog.pg_trigger t\n"
1438 " JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid\n"
1439 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n",
1440 gettext_noop("trigger"));
1441
1442 if (!showSystem && !pattern)
1443 appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n"
1444 " AND n.nspname <> 'information_schema'\n");
1445
1446 if (!validateSQLNamePattern(&buf, pattern, !showSystem && !pattern, false,
1447 "n.nspname", "t.tgname", NULL,
1448 "pg_catalog.pg_table_is_visible(c.oid)",
1449 NULL, 3))
1450 goto error_return;
1451
1453 ") AS tt\n"
1454 " JOIN pg_catalog.pg_description d ON (tt.oid = d.objoid AND tt.tableoid = d.classoid AND d.objsubid = 0)\n");
1455
1456 appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 3;");
1457
1458 res = PSQLexec(buf.data);
1460 if (!res)
1461 return false;
1462
1463 myopt.title = _("Object descriptions");
1464 myopt.translate_header = true;
1465 myopt.translate_columns = translate_columns;
1466 myopt.n_translate_columns = lengthof(translate_columns);
1467
1468 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1469
1470 PQclear(res);
1471 return true;
1472
1473error_return:
1475 return false;
1476}

References _, appendPQExpBuffer(), appendPQExpBufferStr(), buf, gettext_noop, initPQExpBuffer(), lengthof, _psqlSettings::logfile, printQueryOpt::n_translate_columns, _psqlSettings::popt, PQclear, printQuery(), pset, PSQLexec(), _psqlSettings::queryFout, 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 1050 of file describe.c.

1051{
1053 PGresult *res;
1054 printQueryOpt myopt = pset.popt;
1055 static const bool translate_columns[] = {false, false, true, false, false, false};
1056
1058
1059 /*
1060 * we ignore indexes and toast tables since they have no meaningful rights
1061 */
1063 "SELECT n.nspname as \"%s\",\n"
1064 " c.relname as \"%s\",\n"
1065 " CASE c.relkind"
1066 " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'"
1067 " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'"
1068 " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'"
1069 " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'"
1070 " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'"
1071 " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'"
1072 " END as \"%s\",\n"
1073 " ",
1074 gettext_noop("Schema"),
1075 gettext_noop("Name"),
1076 gettext_noop("table"),
1077 gettext_noop("view"),
1078 gettext_noop("materialized view"),
1079 gettext_noop("sequence"),
1080 gettext_noop("foreign table"),
1081 gettext_noop("partitioned table"),
1082 gettext_noop("Type"));
1083
1084 printACLColumn(&buf, "c.relacl");
1085
1086 /*
1087 * The formatting of attacl should match printACLColumn(). However, we
1088 * need no special case for an empty attacl, because the backend always
1089 * optimizes that back to NULL.
1090 */
1092 ",\n pg_catalog.array_to_string(ARRAY(\n"
1093 " SELECT attname || E':\\n ' || pg_catalog.array_to_string(attacl, E'\\n ')\n"
1094 " FROM pg_catalog.pg_attribute a\n"
1095 " WHERE attrelid = c.oid AND NOT attisdropped AND attacl IS NOT NULL\n"
1096 " ), E'\\n') AS \"%s\"",
1097 gettext_noop("Column privileges"));
1098
1099 if (pset.sversion >= 90500 && pset.sversion < 100000)
1101 ",\n pg_catalog.array_to_string(ARRAY(\n"
1102 " SELECT polname\n"
1103 " || CASE WHEN polcmd != '*' THEN\n"
1104 " E' (' || polcmd::pg_catalog.text || E'):'\n"
1105 " ELSE E':'\n"
1106 " END\n"
1107 " || CASE WHEN polqual IS NOT NULL THEN\n"
1108 " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
1109 " ELSE E''\n"
1110 " END\n"
1111 " || CASE WHEN polwithcheck IS NOT NULL THEN\n"
1112 " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
1113 " ELSE E''\n"
1114 " END"
1115 " || CASE WHEN polroles <> '{0}' THEN\n"
1116 " E'\\n to: ' || pg_catalog.array_to_string(\n"
1117 " ARRAY(\n"
1118 " SELECT rolname\n"
1119 " FROM pg_catalog.pg_roles\n"
1120 " WHERE oid = ANY (polroles)\n"
1121 " ORDER BY 1\n"
1122 " ), E', ')\n"
1123 " ELSE E''\n"
1124 " END\n"
1125 " FROM pg_catalog.pg_policy pol\n"
1126 " WHERE polrelid = c.oid), E'\\n')\n"
1127 " AS \"%s\"",
1128 gettext_noop("Policies"));
1129
1130 if (pset.sversion >= 100000)
1132 ",\n pg_catalog.array_to_string(ARRAY(\n"
1133 " SELECT polname\n"
1134 " || CASE WHEN NOT polpermissive THEN\n"
1135 " E' (RESTRICTIVE)'\n"
1136 " ELSE '' END\n"
1137 " || CASE WHEN polcmd != '*' THEN\n"
1138 " E' (' || polcmd::pg_catalog.text || E'):'\n"
1139 " ELSE E':'\n"
1140 " END\n"
1141 " || CASE WHEN polqual IS NOT NULL THEN\n"
1142 " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n"
1143 " ELSE E''\n"
1144 " END\n"
1145 " || CASE WHEN polwithcheck IS NOT NULL THEN\n"
1146 " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n"
1147 " ELSE E''\n"
1148 " END"
1149 " || CASE WHEN polroles <> '{0}' THEN\n"
1150 " E'\\n to: ' || pg_catalog.array_to_string(\n"
1151 " ARRAY(\n"
1152 " SELECT rolname\n"
1153 " FROM pg_catalog.pg_roles\n"
1154 " WHERE oid = ANY (polroles)\n"
1155 " ORDER BY 1\n"
1156 " ), E', ')\n"
1157 " ELSE E''\n"
1158 " END\n"
1159 " FROM pg_catalog.pg_policy pol\n"
1160 " WHERE polrelid = c.oid), E'\\n')\n"
1161 " AS \"%s\"",
1162 gettext_noop("Policies"));
1163
1164 appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n"
1165 " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
1166 "WHERE c.relkind IN ("
1167 CppAsString2(RELKIND_RELATION) ","
1168 CppAsString2(RELKIND_VIEW) ","
1169 CppAsString2(RELKIND_MATVIEW) ","
1170 CppAsString2(RELKIND_SEQUENCE) ","
1171 CppAsString2(RELKIND_FOREIGN_TABLE) ","
1172 CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
1173
1174 if (!showSystem && !pattern)
1175 appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n"
1176 " AND n.nspname <> 'information_schema'\n");
1177
1178 if (!validateSQLNamePattern(&buf, pattern, true, false,
1179 "n.nspname", "c.relname", NULL,
1180 "pg_catalog.pg_table_is_visible(c.oid)",
1181 NULL, 3))
1182 goto error_return;
1183
1184 appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
1185
1186 res = PSQLexec(buf.data);
1187 if (!res)
1188 goto error_return;
1189
1190 printfPQExpBuffer(&buf, _("Access privileges"));
1191 myopt.title = buf.data;
1192 myopt.translate_header = true;
1193 myopt.translate_columns = translate_columns;
1194 myopt.n_translate_columns = lengthof(translate_columns);
1195
1196 printQuery(res, &myopt, pset.queryFout, false, pset.logfile);
1197
1199 PQclear(res);
1200 return true;
1201
1202error_return:
1204 return false;
1205}

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, _psqlSettings::sversion, termPQExpBuffer(), printQueryOpt::title, printQueryOpt::translate_columns, printQueryOpt::translate_header, and validateSQLNamePattern().

Referenced by exec_command_d(), and exec_command_z().