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

Go to the source code of this file.

Functions

bool describeAggregates (const char *pattern, bool verbose, bool showSystem)
 
bool describeAccessMethods (const char *pattern, bool verbose)
 
bool describeTablespaces (const char *pattern, bool verbose)
 
bool describeFunctions (const char *functypes, const char *func_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
 
bool describeTypes (const char *pattern, bool verbose, bool showSystem)
 
bool describeOperators (const char *oper_pattern, char **arg_patterns, int num_arg_patterns, bool verbose, bool showSystem)
 
bool describeRoles (const char *pattern, bool verbose, bool showSystem)
 
bool listDbRoleSettings (const char *pattern, const char *pattern2)
 
bool describeRoleGrants (const char *pattern, bool showSystem)
 
bool permissionsList (const char *pattern, bool showSystem)
 
bool listDefaultACLs (const char *pattern)
 
bool objectDescription (const char *pattern, bool showSystem)
 
bool describeTableDetails (const char *pattern, bool verbose, bool showSystem)
 
bool listTSConfigs (const char *pattern, bool verbose)
 
bool listTSParsers (const char *pattern, bool verbose)
 
bool listTSDictionaries (const char *pattern, bool verbose)
 
bool listTSTemplates (const char *pattern, bool verbose)
 
bool listAllDbs (const char *pattern, bool verbose)
 
bool listTables (const char *tabtypes, const char *pattern, bool verbose, bool showSystem)
 
bool listPartitionedTables (const char *reltypes, const char *pattern, bool verbose)
 
bool listDomains (const char *pattern, bool verbose, bool showSystem)
 
bool listConversions (const char *pattern, bool verbose, bool showSystem)
 
bool describeConfigurationParameters (const char *pattern, bool verbose, bool showSystem)
 
bool listCasts (const char *pattern, bool verbose)
 
bool listCollations (const char *pattern, bool verbose, bool showSystem)
 
bool listSchemas (const char *pattern, bool verbose, bool showSystem)
 
bool listForeignDataWrappers (const char *pattern, bool verbose)
 
bool listForeignServers (const char *pattern, bool verbose)
 
bool listUserMappings (const char *pattern, bool verbose)
 
bool listForeignTables (const char *pattern, bool verbose)
 
bool listLanguages (const char *pattern, bool verbose, bool showSystem)
 
bool listExtensions (const char *pattern)
 
bool listExtensionContents (const char *pattern)
 
bool listExtendedStats (const char *pattern)
 
bool listEventTriggers (const char *pattern, bool verbose)
 
bool listPublications (const char *pattern)
 
bool describePublications (const char *pattern)
 
bool describeSubscriptions (const char *pattern, bool verbose)
 
bool listOperatorClasses (const char *access_method_pattern, const char *type_pattern, bool verbose)
 
bool listOperatorFamilies (const char *access_method_pattern, const char *type_pattern, bool verbose)
 
bool listOpFamilyOperators (const char *access_method_pattern, const char *family_pattern, bool verbose)
 
bool listOpFamilyFunctions (const char *access_method_pattern, const char *family_pattern, bool verbose)
 
bool listLargeObjects (bool verbose)
 

Function Documentation

◆ describeAccessMethods()

bool describeAccessMethods ( const char *  pattern,
bool  verbose 
)

Definition at line 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:1184
#define CppAsString2(x)
Definition: c.h:423
#define lengthof(array)
Definition: c.h:790
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:260

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