printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " p.proname AS \"%s\",\n" " pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n" " CASE WHEN p.pronargs = 0\n" " THEN CAST('*' AS pg_catalog.text)\n" " ELSE pg_catalog.pg_get_function_arguments(p.oid)\n" " END AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Result data type"),
gettext_noop("Argument data types"));
if (pset.sversion >= 110000)
appendPQExpBuffer(&buf, " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n" "FROM pg_catalog.pg_proc p\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" "WHERE p.prokind = " CppAsString2(PROKIND_AGGREGATE) "\n",
gettext_noop("Description")); else
appendPQExpBuffer(&buf, " pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n" "FROM pg_catalog.pg_proc p\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n" "WHERE p.proisagg\n",
gettext_noop("Description"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
pg_log_error("The server (version %s) does not support access methods.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT amname AS \"%s\",\n" " CASE amtype" " WHEN " CppAsString2(AMTYPE_INDEX) " THEN '%s'" " WHEN " CppAsString2(AMTYPE_TABLE) " THEN '%s'" " END AS \"%s\"",
gettext_noop("Name"),
gettext_noop("Index"),
gettext_noop("Table"),
gettext_noop("Type"));
if (verbose)
{
appendPQExpBuffer(&buf, ",\n amhandler AS \"%s\",\n" " pg_catalog.obj_description(oid, 'pg_am') AS \"%s\"",
gettext_noop("Handler"),
gettext_noop("Description"));
}
if (strlen(functypes) != strspn(functypes, df_options))
{
pg_log_error("\\df only takes [%s] as options", df_options); returntrue;
}
if (showProcedure && pset.sversion < 110000)
{ char sverbuf[32];
pg_log_error("\\df does not take a \"%c\" option with server version %s", 'p',
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " p.proname as \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
if (pset.sversion >= 110000)
appendPQExpBuffer(&buf, " pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n" " pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n" " CASE p.prokind\n" " WHEN " CppAsString2(PROKIND_AGGREGATE) " THEN '%s'\n" " WHEN " CppAsString2(PROKIND_WINDOW) " THEN '%s'\n" " WHEN " CppAsString2(PROKIND_PROCEDURE) " THEN '%s'\n" " ELSE '%s'\n" " END as \"%s\"",
gettext_noop("Result data type"),
gettext_noop("Argument data types"), /* translator: "agg" is short for "aggregate" */
gettext_noop("agg"),
gettext_noop("window"),
gettext_noop("proc"),
gettext_noop("func"),
gettext_noop("Type")); else
appendPQExpBuffer(&buf, " pg_catalog.pg_get_function_result(p.oid) as \"%s\",\n" " pg_catalog.pg_get_function_arguments(p.oid) as \"%s\",\n" " CASE\n" " WHEN p.proisagg THEN '%s'\n" " WHEN p.proiswindow THEN '%s'\n" " WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s'\n" " ELSE '%s'\n" " END as \"%s\"",
gettext_noop("Result data type"),
gettext_noop("Argument data types"), /* translator: "agg" is short for "aggregate" */
gettext_noop("agg"),
gettext_noop("window"),
gettext_noop("trigger"),
gettext_noop("func"),
gettext_noop("Type"));
if (verbose)
{
appendPQExpBuffer(&buf, ",\n CASE\n" " WHEN p.provolatile = "
CppAsString2(PROVOLATILE_IMMUTABLE) " THEN '%s'\n" " WHEN p.provolatile = "
CppAsString2(PROVOLATILE_STABLE) " THEN '%s'\n" " WHEN p.provolatile = "
CppAsString2(PROVOLATILE_VOLATILE) " THEN '%s'\n" " END as \"%s\"",
gettext_noop("immutable"),
gettext_noop("stable"),
gettext_noop("volatile"),
gettext_noop("Volatility")); if (pset.sversion >= 90600)
appendPQExpBuffer(&buf, ",\n CASE\n" " WHEN p.proparallel = "
CppAsString2(PROPARALLEL_RESTRICTED) " THEN '%s'\n" " WHEN p.proparallel = "
CppAsString2(PROPARALLEL_SAFE) " THEN '%s'\n" " WHEN p.proparallel = "
CppAsString2(PROPARALLEL_UNSAFE) " THEN '%s'\n" " END as \"%s\"",
gettext_noop("restricted"),
gettext_noop("safe"),
gettext_noop("unsafe"),
gettext_noop("Parallel"));
appendPQExpBuffer(&buf, ",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\"" ",\n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \"%s\"" ",\n CASE WHEN p.proleakproof THEN '%s' ELSE '%s' END as \"%s\"",
gettext_noop("Owner"),
gettext_noop("definer"),
gettext_noop("invoker"),
gettext_noop("Security"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Leakproof?"));
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "p.proacl");
appendPQExpBuffer(&buf, ",\n l.lanname as \"%s\"",
gettext_noop("Language"));
appendPQExpBuffer(&buf, ",\n CASE WHEN l.lanname IN ('internal', 'c') THEN p.prosrc END as \"%s\"",
gettext_noop("Internal name"));
appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
gettext_noop("Description"));
}
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_proc p" "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n");
for (int i = 0; i < num_arg_patterns; i++)
{
appendPQExpBuffer(&buf, " LEFT JOIN pg_catalog.pg_type t%d ON t%d.oid = p.proargtypes[%d]\n" " LEFT JOIN pg_catalog.pg_namespace nt%d ON nt%d.oid = t%d.typnamespace\n",
i, i, i, i, i, i);
}
if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
have_where = false;
/* filter by function type, if requested */ if (showNormal && showAggregate && showProcedure && showTrigger && showWindow) /* Do nothing */ ; elseif (showNormal)
{ if (!showAggregate)
{ if (have_where)
appendPQExpBufferStr(&buf, " AND "); else
{
appendPQExpBufferStr(&buf, "WHERE ");
have_where = true;
} if (pset.sversion >= 110000)
appendPQExpBufferStr(&buf, "p.prokind <> "
CppAsString2(PROKIND_AGGREGATE) "\n"); else
appendPQExpBufferStr(&buf, "NOT p.proisagg\n");
} if (!showProcedure && pset.sversion >= 110000)
{ if (have_where)
appendPQExpBufferStr(&buf, " AND "); else
{
appendPQExpBufferStr(&buf, "WHERE ");
have_where = true;
}
appendPQExpBufferStr(&buf, "p.prokind <> "
CppAsString2(PROKIND_PROCEDURE) "\n");
} if (!showTrigger)
{ if (have_where)
appendPQExpBufferStr(&buf, " AND "); else
{
appendPQExpBufferStr(&buf, "WHERE ");
have_where = true;
}
appendPQExpBufferStr(&buf, "p.prorettype <> 'pg_catalog.trigger'::pg_catalog.regtype\n");
} if (!showWindow)
{ if (have_where)
appendPQExpBufferStr(&buf, " AND "); else
{
appendPQExpBufferStr(&buf, "WHERE ");
have_where = true;
} if (pset.sversion >= 110000)
appendPQExpBufferStr(&buf, "p.prokind <> "
CppAsString2(PROKIND_WINDOW) "\n"); else
appendPQExpBufferStr(&buf, "NOT p.proiswindow\n");
}
} else
{ bool needs_or = false;
appendPQExpBufferStr(&buf, "WHERE (\n ");
have_where = true; /* Note: at least one of these must be true ... */ if (showAggregate)
{ if (pset.sversion >= 110000)
appendPQExpBufferStr(&buf, "p.prokind = "
CppAsString2(PROKIND_AGGREGATE) "\n"); else
appendPQExpBufferStr(&buf, "p.proisagg\n");
needs_or = true;
} if (showTrigger)
{ if (needs_or)
appendPQExpBufferStr(&buf, " OR ");
appendPQExpBufferStr(&buf, "p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype\n");
needs_or = true;
} if (showProcedure)
{ if (needs_or)
appendPQExpBufferStr(&buf, " OR ");
appendPQExpBufferStr(&buf, "p.prokind = "
CppAsString2(PROKIND_PROCEDURE) "\n");
needs_or = true;
} if (showWindow)
{ if (needs_or)
appendPQExpBufferStr(&buf, " OR "); if (pset.sversion >= 110000)
appendPQExpBufferStr(&buf, "p.prokind = "
CppAsString2(PROKIND_WINDOW) "\n"); else
appendPQExpBufferStr(&buf, "p.proiswindow\n");
}
appendPQExpBufferStr(&buf, " )\n");
}
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " pg_catalog.format_type(t.oid, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name")); if (verbose)
{
appendPQExpBuffer(&buf, " t.typname AS \"%s\",\n" " CASE WHEN t.typrelid != 0\n" " THEN CAST('tuple' AS pg_catalog.text)\n" " WHEN t.typlen < 0\n" " THEN CAST('var' AS pg_catalog.text)\n" " ELSE CAST(t.typlen AS pg_catalog.text)\n" " END AS \"%s\",\n" " pg_catalog.array_to_string(\n" " ARRAY(\n" " SELECT e.enumlabel\n" " FROM pg_catalog.pg_enum e\n" " WHERE e.enumtypid = t.oid\n" " ORDER BY e.enumsortorder\n" " ),\n" " E'\\n'\n" " ) AS \"%s\",\n" " pg_catalog.pg_get_userbyid(t.typowner) AS \"%s\",\n",
gettext_noop("Internal name"),
gettext_noop("Size"),
gettext_noop("Elements"),
gettext_noop("Owner"));
printACLColumn(&buf, "t.typacl");
appendPQExpBufferStr(&buf, ",\n ");
}
appendPQExpBuffer(&buf, " pg_catalog.obj_description(t.oid, 'pg_type') as \"%s\"\n",
gettext_noop("Description"));
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_type t\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
/* *donotincludearraytypesunlessthepatterncontains[]
*/ if (pattern == NULL || strstr(pattern, "[]") == NULL)
appendPQExpBufferStr(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n");
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* Match name pattern against either internal or external name */ if (!validateSQLNamePattern(&buf, map_typename_pattern(pattern), true, false, "n.nspname", "t.typname", "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3))
{
termPQExpBuffer(&buf); returnfalse;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
myopt.title = _("List of data types");
myopt.translate_header = true;
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " o.oprname AS \"%s\",\n" " CASE WHEN o.oprkind='l' THEN NULL ELSE pg_catalog.format_type(o.oprleft, NULL) END AS \"%s\",\n" " CASE WHEN o.oprkind='r' THEN NULL ELSE pg_catalog.format_type(o.oprright, NULL) END AS \"%s\",\n" " pg_catalog.format_type(o.oprresult, NULL) AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Left arg type"),
gettext_noop("Right arg type"),
gettext_noop("Result type"));
if (verbose)
appendPQExpBuffer(&buf, " o.oprcode AS \"%s\",\n" " CASE WHEN p.proleakproof THEN '%s' ELSE '%s' END AS \"%s\",\n",
gettext_noop("Function"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Leakproof?"));
appendPQExpBuffer(&buf, " coalesce(pg_catalog.obj_description(o.oid, 'pg_operator'),\n" " pg_catalog.obj_description(o.oprcode, 'pg_proc')) AS \"%s\"\n" "FROM pg_catalog.pg_operator o\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = o.oprnamespace\n",
gettext_noop("Description"));
if (num_arg_patterns >= 2)
{
num_arg_patterns = 2; /* ignore any additional arguments */
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprleft\n" " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n" " LEFT JOIN pg_catalog.pg_type t1 ON t1.oid = o.oprright\n" " LEFT JOIN pg_catalog.pg_namespace nt1 ON nt1.oid = t1.typnamespace\n");
} elseif (num_arg_patterns == 1)
{
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_type t0 ON t0.oid = o.oprright\n" " LEFT JOIN pg_catalog.pg_namespace nt0 ON nt0.oid = t0.typnamespace\n");
}
if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_proc p ON p.oid = o.oprcode\n");
if (!showSystem && !oper_pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* *weignoreindexesandtoasttablessincetheyhavenomeaningfulrights
*/
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " c.relname as \"%s\",\n" " CASE c.relkind" " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'" " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'" " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'" " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" " END as \"%s\",\n" " ",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("table"),
gettext_noop("view"),
gettext_noop("materialized view"),
gettext_noop("sequence"),
gettext_noop("foreign table"),
gettext_noop("partitioned table"),
gettext_noop("Type"));
printACLColumn(&buf, "c.relacl");
/* *TheformattingofattaclshouldmatchprintACLColumn().However,we *neednospecialcaseforanemptyattacl,becausethebackendalways *optimizesthatbacktoNULL.
*/
appendPQExpBuffer(&buf, ",\n pg_catalog.array_to_string(ARRAY(\n" " SELECT attname || E':\\n ' || pg_catalog.array_to_string(attacl, E'\\n ')\n" " FROM pg_catalog.pg_attribute a\n" " WHERE attrelid = c.oid AND NOT attisdropped AND attacl IS NOT NULL\n" " ), E'\\n') AS \"%s\"",
gettext_noop("Column privileges"));
if (pset.sversion >= 90500 && pset.sversion < 100000)
appendPQExpBuffer(&buf, ",\n pg_catalog.array_to_string(ARRAY(\n" " SELECT polname\n" " || CASE WHEN polcmd != '*' THEN\n" " E' (' || polcmd::pg_catalog.text || E'):'\n" " ELSE E':'\n" " END\n" " || CASE WHEN polqual IS NOT NULL THEN\n" " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n" " ELSE E''\n" " END\n" " || CASE WHEN polwithcheck IS NOT NULL THEN\n" " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n" " ELSE E''\n" " END" " || CASE WHEN polroles <> '{0}' THEN\n" " E'\\n to: ' || pg_catalog.array_to_string(\n" " ARRAY(\n" " SELECT rolname\n" " FROM pg_catalog.pg_roles\n" " WHERE oid = ANY (polroles)\n" " ORDER BY 1\n" " ), E', ')\n" " ELSE E''\n" " END\n" " FROM pg_catalog.pg_policy pol\n" " WHERE polrelid = c.oid), E'\\n')\n" " AS \"%s\"",
gettext_noop("Policies"));
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf, ",\n pg_catalog.array_to_string(ARRAY(\n" " SELECT polname\n" " || CASE WHEN NOT polpermissive THEN\n" " E' (RESTRICTIVE)'\n" " ELSE '' END\n" " || CASE WHEN polcmd != '*' THEN\n" " E' (' || polcmd::pg_catalog.text || E'):'\n" " ELSE E':'\n" " END\n" " || CASE WHEN polqual IS NOT NULL THEN\n" " E'\\n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid)\n" " ELSE E''\n" " END\n" " || CASE WHEN polwithcheck IS NOT NULL THEN\n" " E'\\n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid)\n" " ELSE E''\n" " END" " || CASE WHEN polroles <> '{0}' THEN\n" " E'\\n to: ' || pg_catalog.array_to_string(\n" " ARRAY(\n" " SELECT rolname\n" " FROM pg_catalog.pg_roles\n" " WHERE oid = ANY (polroles)\n" " ORDER BY 1\n" " ), E', ')\n" " ELSE E''\n" " END\n" " FROM pg_catalog.pg_policy pol\n" " WHERE polrelid = c.oid), E'\\n')\n" " AS \"%s\"",
gettext_noop("Policies"));
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n" "WHERE c.relkind IN ("
CppAsString2(RELKIND_RELATION) ","
CppAsString2(RELKIND_VIEW) ","
CppAsString2(RELKIND_MATVIEW) ","
CppAsString2(RELKIND_SEQUENCE) ","
CppAsString2(RELKIND_FOREIGN_TABLE) ","
CppAsString2(RELKIND_PARTITIONED_TABLE) ")\n");
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
printfPQExpBuffer(&buf, "SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \"%s\",\n" " n.nspname AS \"%s\",\n" " CASE d.defaclobjtype " " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s'" " WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \"%s\",\n" " ",
gettext_noop("Owner"),
gettext_noop("Schema"),
DEFACLOBJ_RELATION,
gettext_noop("table"),
DEFACLOBJ_SEQUENCE,
gettext_noop("sequence"),
DEFACLOBJ_FUNCTION,
gettext_noop("function"),
DEFACLOBJ_TYPE,
gettext_noop("type"),
DEFACLOBJ_NAMESPACE,
gettext_noop("schema"),
DEFACLOBJ_LARGEOBJECT,
gettext_noop("large object"),
gettext_noop("Type"));
printACLColumn(&buf, "d.defaclacl");
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_default_acl d\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace\n");
appendPQExpBuffer(&buf, "SELECT DISTINCT tt.nspname AS \"%s\", tt.name AS \"%s\", tt.object AS \"%s\", d.description AS \"%s\"\n" "FROM (\n",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Object"),
gettext_noop("Description"));
/* Table constraint descriptions */
appendPQExpBuffer(&buf, " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n" " n.nspname as nspname,\n" " CAST(pgc.conname AS pg_catalog.text) as name," " CAST('%s' AS pg_catalog.text) as object\n" " FROM pg_catalog.pg_constraint pgc\n" " JOIN pg_catalog.pg_class c " "ON c.oid = pgc.conrelid\n" " LEFT JOIN pg_catalog.pg_namespace n " " ON n.oid = c.relnamespace\n",
gettext_noop("table constraint"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* Domain constraint descriptions */
appendPQExpBuffer(&buf, "UNION ALL\n" " SELECT pgc.oid as oid, pgc.tableoid AS tableoid,\n" " n.nspname as nspname,\n" " CAST(pgc.conname AS pg_catalog.text) as name," " CAST('%s' AS pg_catalog.text) as object\n" " FROM pg_catalog.pg_constraint pgc\n" " JOIN pg_catalog.pg_type t " "ON t.oid = pgc.contypid\n" " LEFT JOIN pg_catalog.pg_namespace n " " ON n.oid = t.typnamespace\n",
gettext_noop("domain constraint"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* Operator class descriptions */
appendPQExpBuffer(&buf, "UNION ALL\n" " SELECT o.oid as oid, o.tableoid as tableoid,\n" " n.nspname as nspname,\n" " CAST(o.opcname AS pg_catalog.text) as name,\n" " CAST('%s' AS pg_catalog.text) as object\n" " FROM pg_catalog.pg_opclass o\n" " JOIN pg_catalog.pg_am am ON " "o.opcmethod = am.oid\n" " JOIN pg_catalog.pg_namespace n ON " "n.oid = o.opcnamespace\n",
gettext_noop("operator class"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* Rule descriptions (ignore rules for views) */
appendPQExpBuffer(&buf, "UNION ALL\n" " SELECT r.oid as oid, r.tableoid as tableoid,\n" " n.nspname as nspname,\n" " CAST(r.rulename AS pg_catalog.text) as name," " CAST('%s' AS pg_catalog.text) as object\n" " FROM pg_catalog.pg_rewrite r\n" " JOIN pg_catalog.pg_class c ON c.oid = r.ev_class\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n" " WHERE r.rulename != '_RETURN'\n",
gettext_noop("rule"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
/* Trigger descriptions */
appendPQExpBuffer(&buf, "UNION ALL\n" " SELECT t.oid as oid, t.tableoid as tableoid,\n" " n.nspname as nspname,\n" " CAST(t.tgname AS pg_catalog.text) as name," " CAST('%s' AS pg_catalog.text) as object\n" " FROM pg_catalog.pg_trigger t\n" " JOIN pg_catalog.pg_class c ON c.oid = t.tgrelid\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n",
gettext_noop("trigger"));
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE n.nspname <> 'pg_catalog'\n" " AND n.nspname <> 'information_schema'\n");
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
if (PQntuples(res) == 0)
{ if (!pset.quiet)
{ if (pattern)
pg_log_error("Did not find any relation named \"%s\".",
pattern); else
pg_log_error("Did not find any relations.");
}
PQclear(res); returnfalse;
}
for (i = 0; i < PQntuples(res); i++)
{ constchar *oid; constchar *nspname; constchar *relname;
oid = PQgetvalue(res, i, 0);
nspname = PQgetvalue(res, i, 1);
relname = PQgetvalue(res, i, 2);
if (!describeOneTableDetails(nspname, relname, oid, verbose))
{
PQclear(res); returnfalse;
} if (cancel_pressed)
{
PQclear(res); returnfalse;
}
}
res = PSQLexec(buf.data); if (!res) goto error_return;
/* Did we get anything? */ if (PQntuples(res) == 0)
{ if (!pset.quiet)
pg_log_error("Did not find any relation with OID %s.", oid); goto error_return;
}
if (pset.sversion >= 100000)
{
printfPQExpBuffer(&buf, "SELECT pg_catalog.format_type(seqtypid, NULL) AS \"%s\",\n" " seqstart AS \"%s\",\n" " seqmin AS \"%s\",\n" " seqmax AS \"%s\",\n" " seqincrement AS \"%s\",\n" " CASE WHEN seqcycle THEN '%s' ELSE '%s' END AS \"%s\",\n" " seqcache AS \"%s\"\n",
gettext_noop("Type"),
gettext_noop("Start"),
gettext_noop("Minimum"),
gettext_noop("Maximum"),
gettext_noop("Increment"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Cycles?"),
gettext_noop("Cache"));
appendPQExpBuffer(&buf, "FROM pg_catalog.pg_sequence\n" "WHERE seqrelid = '%s';",
oid);
} else
{
printfPQExpBuffer(&buf, "SELECT 'bigint' AS \"%s\",\n" " start_value AS \"%s\",\n" " min_value AS \"%s\",\n" " max_value AS \"%s\",\n" " increment_by AS \"%s\",\n" " CASE WHEN is_cycled THEN '%s' ELSE '%s' END AS \"%s\",\n" " cache_value AS \"%s\"\n",
gettext_noop("Type"),
gettext_noop("Start"),
gettext_noop("Minimum"),
gettext_noop("Maximum"),
gettext_noop("Increment"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Cycles?"),
gettext_noop("Cache"));
appendPQExpBuffer(&buf, "FROM %s", fmtId(schemaname)); /* must be separate because fmtId isn't reentrant */
appendPQExpBuffer(&buf, ".%s;", fmtId(relationname));
}
res = PSQLexec(buf.data); if (!res) goto error_return;
/* Get the column that owns this sequence */
printfPQExpBuffer(&buf, "SELECT pg_catalog.quote_ident(nspname) || '.' ||" "\n pg_catalog.quote_ident(relname) || '.' ||" "\n pg_catalog.quote_ident(attname)," "\n d.deptype" "\nFROM pg_catalog.pg_class c" "\nINNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid" "\nINNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace" "\nINNER JOIN pg_catalog.pg_attribute a ON (" "\n a.attrelid=c.oid AND" "\n a.attnum=d.refobjsubid)" "\nWHERE d.classid='pg_catalog.pg_class'::pg_catalog.regclass" "\n AND d.refclassid='pg_catalog.pg_class'::pg_catalog.regclass" "\n AND d.objid='%s'" "\n AND d.deptype IN ('a', 'i')",
oid);
for (i = 0; i < cols; i++)
printTableAddHeader(&cont, headers[i], true, 'l');
/* Generate table cells to be printed */ for (i = 0; i < numrows; i++)
{ /* Column */
printTableAddCell(&cont, PQgetvalue(res, i, attname_col), false, false);
/* Type */
printTableAddCell(&cont, PQgetvalue(res, i, atttype_col), false, false);
/* Info for index columns */ if (isindexkey_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, isindexkey_col), true, false); if (indexdef_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, indexdef_col), false, false);
/* FDW options for foreign table columns */ if (fdwopts_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, fdwopts_col), false, false);
/* Storage mode, if relevant */ if (attstorage_col >= 0)
{ char *storage = PQgetvalue(res, i, attstorage_col);
/* these strings are literal in our syntax, so not translated. */
printTableAddCell(&cont, (storage[0] == TYPSTORAGE_PLAIN ? "plain" :
(storage[0] == TYPSTORAGE_MAIN ? "main" :
(storage[0] == TYPSTORAGE_EXTENDED ? "extended" :
(storage[0] == TYPSTORAGE_EXTERNAL ? "external" : "???")))), false, false);
}
/* Column compression, if relevant */ if (attcompression_col >= 0)
{ char *compression = PQgetvalue(res, i, attcompression_col);
/* these strings are literal in our syntax, so not translated. */
printTableAddCell(&cont, (compression[0] == 'p' ? "pglz" :
(compression[0] == 'l' ? "lz4" :
(compression[0] == '\0' ? "" : "???"))), false, false);
}
/* Statistics target, if the relkind supports this feature */ if (attstattarget_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, attstattarget_col), false, false);
/* Column comments, if the relkind supports this feature */ if (attdescr_col >= 0)
printTableAddCell(&cont, PQgetvalue(res, i, attdescr_col), false, false);
}
/* Make footers */
if (tableinfo.ispartition)
{ /* Footer information for a partition child table */
PGresult *result;
PQclear(result);
} /* If you add relkinds here, see also "Finish printing..." stanza below */ elseif (tableinfo.relkind == RELKIND_RELATION ||
tableinfo.relkind == RELKIND_MATVIEW ||
tableinfo.relkind == RELKIND_FOREIGN_TABLE ||
tableinfo.relkind == RELKIND_PARTITIONED_TABLE ||
tableinfo.relkind == RELKIND_PARTITIONED_INDEX ||
tableinfo.relkind == RELKIND_TOASTVALUE)
{ /* Footer information about a table */
PGresult *result = NULL; int tuples = 0;
/* print indexes */ if (tableinfo.hasindex)
{
printfPQExpBuffer(&buf, "SELECT c2.relname, i.indisprimary, i.indisunique, " "i.indisclustered, i.indisvalid, " "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true),\n " "pg_catalog.pg_get_constraintdef(con.oid, true), " "contype, condeferrable, condeferred"); if (pset.sversion >= 90400)
appendPQExpBufferStr(&buf, ", i.indisreplident"); else
appendPQExpBufferStr(&buf, ", false AS indisreplident");
appendPQExpBufferStr(&buf, ", c2.reltablespace"); if (pset.sversion >= 180000)
appendPQExpBufferStr(&buf, ", con.conperiod"); else
appendPQExpBufferStr(&buf, ", false AS conperiod");
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n" " LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ("
CppAsString2(CONSTRAINT_PRIMARY) ","
CppAsString2(CONSTRAINT_UNIQUE) ","
CppAsString2(CONSTRAINT_EXCLUSION) "))\n" "WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n" "ORDER BY i.indisprimary DESC, c2.relname;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; else
tuples = PQntuples(result);
if (tuples > 0)
{
printTableAddFooter(&cont, _("Indexes:")); for (i = 0; i < tuples; i++)
{ /* untranslated index name */
printfPQExpBuffer(&buf, " \"%s\"",
PQgetvalue(result, i, 0));
/* *IfexclusionconstraintorPK/UNIQUEconstraintWITHOUT *OVERLAPS,printtheconstraintdef
*/ if (strcmp(PQgetvalue(result, i, 7), "x") == 0 ||
strcmp(PQgetvalue(result, i, 12), "t") == 0)
{
appendPQExpBuffer(&buf, " %s",
PQgetvalue(result, i, 6));
} else
{ constchar *indexdef; constchar *usingpos;
/* Label as primary key or unique (but not both) */ if (strcmp(PQgetvalue(result, i, 1), "t") == 0)
appendPQExpBufferStr(&buf, " PRIMARY KEY,"); elseif (strcmp(PQgetvalue(result, i, 2), "t") == 0)
{ if (strcmp(PQgetvalue(result, i, 7), "u") == 0)
appendPQExpBufferStr(&buf, " UNIQUE CONSTRAINT,"); else
appendPQExpBufferStr(&buf, " UNIQUE,");
}
/* Everything after "USING" is echoed verbatim */
indexdef = PQgetvalue(result, i, 5);
usingpos = strstr(indexdef, " USING "); if (usingpos)
indexdef = usingpos + 7;
appendPQExpBuffer(&buf, " %s", indexdef);
/* Need these for deferrable PK/UNIQUE indexes */ if (strcmp(PQgetvalue(result, i, 8), "t") == 0)
appendPQExpBufferStr(&buf, " DEFERRABLE");
if (strcmp(PQgetvalue(result, i, 9), "t") == 0)
appendPQExpBufferStr(&buf, " INITIALLY DEFERRED");
}
/* Add these for all cases */ if (strcmp(PQgetvalue(result, i, 3), "t") == 0)
appendPQExpBufferStr(&buf, " CLUSTER");
if (strcmp(PQgetvalue(result, i, 4), "t") != 0)
appendPQExpBufferStr(&buf, " INVALID");
if (strcmp(PQgetvalue(result, i, 10), "t") == 0)
appendPQExpBufferStr(&buf, " REPLICA IDENTITY");
printTableAddFooter(&cont, buf.data);
/* Print tablespace of the index on the same line */
add_tablespace_footer(&cont, RELKIND_INDEX,
atooid(PQgetvalue(result, i, 11)), false);
}
}
PQclear(result);
}
if (tuples > 0)
{
printTableAddFooter(&cont, _("Check constraints:")); for (i = 0; i < tuples; i++)
{ /* untranslated constraint name and def */
printfPQExpBuffer(&buf, " \"%s\" %s",
PQgetvalue(result, i, 0),
PQgetvalue(result, i, 1));
/* print incoming foreign-key references */ if (pset.sversion >= 120000)
{
printfPQExpBuffer(&buf, "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n" " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n" " FROM pg_catalog.pg_constraint c\n" " WHERE confrelid IN (SELECT pg_catalog.pg_partition_ancestors('%s')\n" " UNION ALL VALUES ('%s'::pg_catalog.regclass))\n" " AND contype = " CppAsString2(CONSTRAINT_FOREIGN) " AND conparentid = 0\n" "ORDER BY conname;",
oid, oid);
} else
{
printfPQExpBuffer(&buf, "SELECT conname, conrelid::pg_catalog.regclass AS ontable,\n" " pg_catalog.pg_get_constraintdef(oid, true) AS condef\n" " FROM pg_catalog.pg_constraint\n" " WHERE confrelid = %s AND contype = " CppAsString2(CONSTRAINT_FOREIGN) "\n" "ORDER BY conname;",
oid);
}
result = PSQLexec(buf.data); if (!result) goto error_return; else
tuples = PQntuples(result);
if (tuples > 0)
{ int i_conname = PQfnumber(result, "conname"),
i_ontable = PQfnumber(result, "ontable"),
i_condef = PQfnumber(result, "condef");
printTableAddFooter(&cont, _("Referenced by:")); for (i = 0; i < tuples; i++)
{
printfPQExpBuffer(&buf, " TABLE \"%s\" CONSTRAINT \"%s\" %s",
PQgetvalue(result, i, i_ontable),
PQgetvalue(result, i, i_conname),
PQgetvalue(result, i, i_condef));
/* print any row-level policies */ if (pset.sversion >= 90500)
{
printfPQExpBuffer(&buf, "SELECT pol.polname,"); if (pset.sversion >= 100000)
appendPQExpBufferStr(&buf, " pol.polpermissive,\n"); else
appendPQExpBufferStr(&buf, " 't' as polpermissive,\n");
appendPQExpBuffer(&buf, " CASE WHEN pol.polroles = '{0}' THEN NULL ELSE pg_catalog.array_to_string(array(select rolname from pg_catalog.pg_roles where oid = any (pol.polroles) order by 1),',') END,\n" " pg_catalog.pg_get_expr(pol.polqual, pol.polrelid),\n" " pg_catalog.pg_get_expr(pol.polwithcheck, pol.polrelid),\n" " CASE pol.polcmd\n" " WHEN 'r' THEN 'SELECT'\n" " WHEN 'a' THEN 'INSERT'\n" " WHEN 'w' THEN 'UPDATE'\n" " WHEN 'd' THEN 'DELETE'\n" " END AS cmd\n" "FROM pg_catalog.pg_policy pol\n" "WHERE pol.polrelid = '%s' ORDER BY 1;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; else
tuples = PQntuples(result);
appendPQExpBuffer(&buf, " ON %s FROM %s",
PQgetvalue(result, i, 4),
PQgetvalue(result, i, 1));
/* Show the stats target if it's not default */ if (!PQgetisnull(result, i, 8) &&
strcmp(PQgetvalue(result, i, 8), "-1") != 0)
appendPQExpBuffer(&buf, "; STATISTICS %s",
PQgetvalue(result, i, 8));
printTableAddFooter(&cont, buf.data);
}
}
PQclear(result);
} elseif (pset.sversion >= 100000)
{
printfPQExpBuffer(&buf, "SELECT oid, " "stxrelid::pg_catalog.regclass, " "stxnamespace::pg_catalog.regnamespace AS nsp, " "stxname,\n" " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(attname),', ')\n" " FROM pg_catalog.unnest(stxkeys) s(attnum)\n" " JOIN pg_catalog.pg_attribute a ON (stxrelid = a.attrelid AND\n" " a.attnum = s.attnum AND NOT attisdropped)) AS columns,\n" " " CppAsString2(STATS_EXT_NDISTINCT) " = any(stxkind) AS ndist_enabled,\n" " " CppAsString2(STATS_EXT_DEPENDENCIES) " = any(stxkind) AS deps_enabled,\n" " " CppAsString2(STATS_EXT_MCV) " = any(stxkind) AS mcv_enabled,\n");
if (pset.sversion >= 130000)
appendPQExpBufferStr(&buf, " stxstattarget\n"); else
appendPQExpBufferStr(&buf, " -1 AS stxstattarget\n");
appendPQExpBuffer(&buf, "FROM pg_catalog.pg_statistic_ext\n" "WHERE stxrelid = '%s'\n" "ORDER BY 1;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; else
tuples = PQntuples(result);
if (tuples > 0)
{
printTableAddFooter(&cont, _("Statistics objects:"));
for (i = 0; i < tuples; i++)
{ bool gotone = false;
printfPQExpBuffer(&buf, " ");
/* statistics object name (qualified with namespace) */
appendPQExpBuffer(&buf, "\"%s.%s\" (",
PQgetvalue(result, i, 2),
PQgetvalue(result, i, 3));
/* options */ if (strcmp(PQgetvalue(result, i, 5), "t") == 0)
{
appendPQExpBufferStr(&buf, "ndistinct");
gotone = true;
}
if (strcmp(PQgetvalue(result, i, 6), "t") == 0)
{
appendPQExpBuffer(&buf, "%sdependencies", gotone ? ", " : "");
gotone = true;
}
if (strcmp(PQgetvalue(result, i, 7), "t") == 0)
{
appendPQExpBuffer(&buf, "%smcv", gotone ? ", " : "");
}
appendPQExpBuffer(&buf, ") ON %s FROM %s",
PQgetvalue(result, i, 4),
PQgetvalue(result, i, 1));
/* Show the stats target if it's not default */ if (strcmp(PQgetvalue(result, i, 8), "-1") != 0)
appendPQExpBuffer(&buf, "; STATISTICS %s",
PQgetvalue(result, i, 8));
/* *Ifverbose,printNOTNULLconstraints.
*/ if (verbose)
{
printfPQExpBuffer(&buf, "SELECT c.conname, a.attname, c.connoinherit,\n" " c.conislocal, c.coninhcount <> 0,\n" " c.convalidated\n" "FROM pg_catalog.pg_constraint c JOIN\n" " pg_catalog.pg_attribute a ON\n" " (a.attrelid = c.conrelid AND a.attnum = c.conkey[1])\n" "WHERE c.contype = " CppAsString2(CONSTRAINT_NOTNULL) " AND\n" " c.conrelid = '%s'::pg_catalog.regclass\n" "ORDER BY a.attnum",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; else
tuples = PQntuples(result);
if (tuples > 0)
printTableAddFooter(&cont, _("Not-null constraints:"));
/* Might be an empty set - that's ok */ for (i = 0; i < tuples; i++)
{ bool islocal = PQgetvalue(result, i, 3)[0] == 't'; bool inherited = PQgetvalue(result, i, 4)[0] == 't'; bool validated = PQgetvalue(result, i, 5)[0] == 't';
printfPQExpBuffer(&buf, " \"%s\" NOT NULL \"%s\"%s%s",
PQgetvalue(result, i, 0),
PQgetvalue(result, i, 1),
PQgetvalue(result, i, 2)[0] == 't' ? " NO INHERIT" :
islocal && inherited ? _(" (local, inherited)") :
inherited ? _(" (inherited)") : "",
!validated ? " NOT VALID" : "");
/* Get view_def if table is a view or materialized view */ if ((tableinfo.relkind == RELKIND_VIEW ||
tableinfo.relkind == RELKIND_MATVIEW) && verbose)
{
PGresult *result;
printfPQExpBuffer(&buf, "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true);",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return;
if (PQntuples(result) > 0)
view_def = pg_strdup(PQgetvalue(result, 0, 0));
PQclear(result);
}
if (view_def)
{
PGresult *result = NULL;
/* Footer information about a view */
printTableAddFooter(&cont, _("View definition:"));
printTableAddFooter(&cont, view_def);
/* print rules */ if (tableinfo.hasrules)
{
printfPQExpBuffer(&buf, "SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true))\n" "FROM pg_catalog.pg_rewrite r\n" "WHERE r.ev_class = '%s' AND r.rulename != '_RETURN' ORDER BY 1;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return;
if (PQntuples(result) > 0)
{
printTableAddFooter(&cont, _("Rules:")); for (i = 0; i < PQntuples(result); i++)
{ constchar *ruledef;
/* Everything after "CREATE RULE" is echoed verbatim */
ruledef = PQgetvalue(result, i, 1);
ruledef += 12;
/* *Detectwhethereachtriggerisinherited,andifso,getthename *ofthetopmosttableit'sinheritedfrom.Wehavenoeasywayto *dothatpre-v13,forlackofthetgparentidcolumn.Evenwith *tgparentid,astraightforwardsearchforthetopmostparentwould *requirearecursiveCTE,whichseemsundulyexpensive.Wecheata *bitbyassumingparenttriggerswillmatchbytgname;then,joining *withpg_partition_ancestors()allowstheplannertomakeuseof *pg_trigger_tgrelid_tgname_indexifitwishes.Weensurewefind *thecorrecttopmostparentbystoppingatthefirst-in-partition- *ancestry-ordertriggerthathastgparentid=0.(Theremightbe *unrelated,non-inheritedtriggerswiththesamenamefurtherupthe *stack,sothisisimportant.)
*/ if (pset.sversion >= 130000)
appendPQExpBufferStr(&buf, " CASE WHEN t.tgparentid != 0 THEN\n" " (SELECT u.tgrelid::pg_catalog.regclass\n" " FROM pg_catalog.pg_trigger AS u,\n" " pg_catalog.pg_partition_ancestors(t.tgrelid) WITH ORDINALITY AS a(relid, depth)\n" " WHERE u.tgname = t.tgname AND u.tgrelid = a.relid\n" " AND u.tgparentid = 0\n" " ORDER BY a.depth LIMIT 1)\n" " END AS parent\n"); else
appendPQExpBufferStr(&buf, " NULL AS parent\n");
/* print foreign server name */ if (tableinfo.relkind == RELKIND_FOREIGN_TABLE)
{ char *ftoptions;
/* Footer information about foreign table */
printfPQExpBuffer(&buf, "SELECT s.srvname,\n" " pg_catalog.array_to_string(ARRAY(\n" " SELECT pg_catalog.quote_ident(option_name)" " || ' ' || pg_catalog.quote_literal(option_value)\n" " FROM pg_catalog.pg_options_to_table(ftoptions)), ', ')\n" "FROM pg_catalog.pg_foreign_table f,\n" " pg_catalog.pg_foreign_server s\n" "WHERE f.ftrelid = '%s' AND s.oid = f.ftserver;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; elseif (PQntuples(result) != 1)
{
PQclear(result); goto error_return;
}
/* Print server name */
printfPQExpBuffer(&buf, _("Server: %s"),
PQgetvalue(result, 0, 0));
printTableAddFooter(&cont, buf.data);
/* Print per-table FDW options, if any */
ftoptions = PQgetvalue(result, 0, 1); if (ftoptions && ftoptions[0] != '\0')
{
printfPQExpBuffer(&buf, _("FDW options: (%s)"), ftoptions);
printTableAddFooter(&cont, buf.data);
}
PQclear(result);
}
/* print tables inherited from (exclude partitioned parents) */
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhparent AND i.inhrelid = '%s'\n" " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_TABLE) " AND c.relkind != " CppAsString2(RELKIND_PARTITIONED_INDEX) "\nORDER BY inhseqno;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return; else
{ constchar *s = _("Inherits"); int sw = pg_wcswidth(s, strlen(s), pset.encoding);
tuples = PQntuples(result);
for (i = 0; i < tuples; i++)
{ if (i == 0)
printfPQExpBuffer(&buf, "%s: %s",
s, PQgetvalue(result, i, 0)); else
printfPQExpBuffer(&buf, "%*s %s",
sw, "", PQgetvalue(result, i, 0)); if (i < tuples - 1)
appendPQExpBufferChar(&buf, ',');
printTableAddFooter(&cont, buf.data);
}
PQclear(result);
}
/* print child tables (with additional info if partitions) */ if (pset.sversion >= 140000)
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass, c.relkind," " inhdetachpending," " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," " c.oid::pg_catalog.regclass::pg_catalog.text;",
oid); elseif (pset.sversion >= 100000)
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass, c.relkind," " false AS inhdetachpending," " pg_catalog.pg_get_expr(c.relpartbound, c.oid)\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" "ORDER BY pg_catalog.pg_get_expr(c.relpartbound, c.oid) = 'DEFAULT'," " c.oid::pg_catalog.regclass::pg_catalog.text;",
oid); else
printfPQExpBuffer(&buf, "SELECT c.oid::pg_catalog.regclass, c.relkind," " false AS inhdetachpending, NULL\n" "FROM pg_catalog.pg_class c, pg_catalog.pg_inherits i\n" "WHERE c.oid = i.inhrelid AND i.inhparent = '%s'\n" "ORDER BY c.oid::pg_catalog.regclass::pg_catalog.text;",
oid);
result = PSQLexec(buf.data); if (!result) goto error_return;
tuples = PQntuples(result);
/* *Forapartitionedtablewithnopartitions,alwaysprintthenumber *ofpartitionsaszero,evenwhenverboseoutputisexpected. *Otherwise,wewillnotprint"Partitions"sectionforapartitioned *tablewithoutanypartitions.
*/ if (is_partitioned && tuples == 0)
{
printfPQExpBuffer(&buf, _("Number of partitions: %d"), tuples);
printTableAddFooter(&cont, buf.data);
} elseif (!verbose)
{ /* print the number of child tables, if any */ if (tuples > 0)
{ if (is_partitioned)
printfPQExpBuffer(&buf, _("Number of partitions: %d (Use \\d+ to list them.)"), tuples); else
printfPQExpBuffer(&buf, _("Number of child tables: %d (Use \\d+ to list them.)"), tuples);
printTableAddFooter(&cont, buf.data);
}
} else
{ /* display the list of child tables */ constchar *ct = is_partitioned ? _("Partitions") : _("Child tables"); int ctw = pg_wcswidth(ct, strlen(ct), pset.encoding);
for (i = 0; i < tuples; i++)
{ char child_relkind = *PQgetvalue(result, i, 1);
if (i == 0)
printfPQExpBuffer(&buf, "%s: %s",
ct, PQgetvalue(result, i, 0)); else
printfPQExpBuffer(&buf, "%*s %s",
ctw, "", PQgetvalue(result, i, 0)); if (!PQgetisnull(result, i, 3))
appendPQExpBuffer(&buf, " %s", PQgetvalue(result, i, 3)); if (child_relkind == RELKIND_PARTITIONED_TABLE ||
child_relkind == RELKIND_PARTITIONED_INDEX)
appendPQExpBufferStr(&buf, ", PARTITIONED"); elseif (child_relkind == RELKIND_FOREIGN_TABLE)
appendPQExpBufferStr(&buf, ", FOREIGN"); if (strcmp(PQgetvalue(result, i, 2), "t") == 0)
appendPQExpBufferStr(&buf, " (DETACH PENDING)"); if (i < tuples - 1)
appendPQExpBufferChar(&buf, ',');
/* OIDs, if verbose and not a materialized view */ if (verbose && tableinfo.relkind != RELKIND_MATVIEW && tableinfo.hasoids)
printTableAddFooter(&cont, _("Has OIDs: yes"));
/* Tablespace info */
add_tablespace_footer(&cont, tableinfo.relkind, tableinfo.tablespace, true);
/* clean up */ if (printTableInitialized)
printTableCleanup(&cont);
termPQExpBuffer(&buf);
termPQExpBuffer(&title);
termPQExpBuffer(&tmpbuf);
free(view_def);
PQclear(res);
return retval;
}
/* *Addatablespacedescriptiontoafooter.If'newline'istrue,itisadded *inanewline;otherwiseit'sappendedtothecurrentvalueofthelast *footer.
*/ staticvoid
add_tablespace_footer(printTableContent *const cont, char relkind,
Oid tablespace, constbool newline)
{ /* relkinds for which we support tablespaces */ if (relkind == RELKIND_RELATION ||
relkind == RELKIND_MATVIEW ||
relkind == RELKIND_INDEX ||
relkind == RELKIND_PARTITIONED_TABLE ||
relkind == RELKIND_PARTITIONED_INDEX ||
relkind == RELKIND_TOASTVALUE)
{ /* *Weignorethedatabasedefaulttablespacesothatusersnotusing *tablespacesdon'tneedtoknowaboutthem.
*/ if (tablespace != 0)
{
PGresult *result = NULL;
PQExpBufferData buf;
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT spcname FROM pg_catalog.pg_tablespace\n" "WHERE oid = '%u';", tablespace);
result = PSQLexec(buf.data); if (!result)
{
termPQExpBuffer(&buf); return;
} /* Should always be the case, but.... */ if (PQntuples(result) > 0)
{ if (newline)
{ /* Add the tablespace as a new footer */
printfPQExpBuffer(&buf, _("Tablespace: \"%s\""),
PQgetvalue(result, 0, 0));
printTableAddFooter(cont, buf.data);
} else
{ /* Append the tablespace to the latest footer */
printfPQExpBuffer(&buf, "%s", cont->footer->data);
if (strcmp(PQgetvalue(res, i, 7), "") != 0)
{ if (buf.len > 0)
appendPQExpBufferChar(&buf, '\n');
appendPQExpBufferStr(&buf, _("Password valid until "));
appendPQExpBufferStr(&buf, PQgetvalue(res, i, 7));
}
attr[i] = pg_strdup(buf.data);
printTableAddCell(&cont, attr[i], false, false);
if (verbose)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false);
}
termPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT rolname AS \"%s\", datname AS \"%s\",\n" "pg_catalog.array_to_string(setconfig, E'\\n') AS \"%s\"\n" "FROM pg_catalog.pg_db_role_setting s\n" "LEFT JOIN pg_catalog.pg_database d ON d.oid = setdatabase\n" "LEFT JOIN pg_catalog.pg_roles r ON r.oid = setrole\n",
gettext_noop("Role"),
gettext_noop("Database"),
gettext_noop("Settings")); if (!validateSQLNamePattern(&buf, pattern, false, false,
NULL, "r.rolname", NULL, NULL, &havewhere, 1)) goto error_return; if (!validateSQLNamePattern(&buf, pattern2, havewhere, false,
NULL, "d.datname", NULL, NULL,
NULL, 1)) goto error_return;
appendPQExpBufferStr(&buf, "ORDER BY 1, 2;");
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
/* *Mostfunctionsinthisfilearecontenttoprintanemptytablewhen *therearenomatchingobjects.Weintentionallydeviatefromthat *here,butonlyin!quietmode,becauseofthepossibilitythattheuser *isconfusedaboutwhatthetwopatternargumentsmean.
*/ if (PQntuples(res) == 0 && !pset.quiet)
{ if (pattern && pattern2)
pg_log_error("Did not find any settings for role \"%s\" and database \"%s\".",
pattern, pattern2); elseif (pattern)
pg_log_error("Did not find any settings for role \"%s\".",
pattern); else
pg_log_error("Did not find any settings.");
} else
{
myopt.title = _("List of settings");
myopt.translate_header = true;
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT m.rolname AS \"%s\", r.rolname AS \"%s\",\n" " pg_catalog.concat_ws(', ',\n",
gettext_noop("Role name"),
gettext_noop("Member of"));
if (pset.sversion >= 160000)
appendPQExpBufferStr(&buf, " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n" " CASE WHEN pam.inherit_option THEN 'INHERIT' END,\n" " CASE WHEN pam.set_option THEN 'SET' END\n"); else
appendPQExpBufferStr(&buf, " CASE WHEN pam.admin_option THEN 'ADMIN' END,\n" " CASE WHEN m.rolinherit THEN 'INHERIT' END,\n" " 'SET'\n");
appendPQExpBuffer(&buf, " ) AS \"%s\",\n" " g.rolname AS \"%s\"\n",
gettext_noop("Options"),
gettext_noop("Grantor"));
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_roles m\n" " JOIN pg_catalog.pg_auth_members pam ON (pam.member = m.oid)\n" " LEFT JOIN pg_catalog.pg_roles r ON (pam.roleid = r.oid)\n" " LEFT JOIN pg_catalog.pg_roles g ON (pam.grantor = g.oid)\n");
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, "WHERE m.rolname !~ '^pg_'\n");
/* Count the number of explicitly-requested relation types */
ntypes = showTables + showIndexes + showViews + showMatViews +
showSeq + showForeign; /* If none, we default to \dtvmsE (but see also command.c) */ if (ntypes == 0)
showTables = showViews = showMatViews = showSeq = showForeign = true;
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " c.relname as \"%s\",\n" " CASE c.relkind" " WHEN " CppAsString2(RELKIND_RELATION) " THEN '%s'" " WHEN " CppAsString2(RELKIND_VIEW) " THEN '%s'" " WHEN " CppAsString2(RELKIND_MATVIEW) " THEN '%s'" " WHEN " CppAsString2(RELKIND_INDEX) " THEN '%s'" " WHEN " CppAsString2(RELKIND_SEQUENCE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_TOASTVALUE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_FOREIGN_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" " END as \"%s\",\n" " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("table"),
gettext_noop("view"),
gettext_noop("materialized view"),
gettext_noop("index"),
gettext_noop("sequence"),
gettext_noop("TOAST table"),
gettext_noop("foreign table"),
gettext_noop("partitioned table"),
gettext_noop("partitioned index"),
gettext_noop("Type"),
gettext_noop("Owner"));
cols_so_far = 4;
if (showIndexes)
{
appendPQExpBuffer(&buf, ",\n c2.relname as \"%s\"",
gettext_noop("Table"));
cols_so_far++;
}
if (verbose)
{ /* *Showwhetherarelationispermanent,temporary,orunlogged.
*/
appendPQExpBuffer(&buf, ",\n CASE c.relpersistence " "WHEN " CppAsString2(RELPERSISTENCE_PERMANENT) " THEN '%s' " "WHEN " CppAsString2(RELPERSISTENCE_TEMP) " THEN '%s' " "WHEN " CppAsString2(RELPERSISTENCE_UNLOGGED) " THEN '%s' " "END as \"%s\"",
gettext_noop("permanent"),
gettext_noop("temporary"),
gettext_noop("unlogged"),
gettext_noop("Persistence"));
translate_columns[cols_so_far] = true;
appendPQExpBuffer(&buf, ",\n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \"%s\"" ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
gettext_noop("Size"),
gettext_noop("Description"));
}
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c" "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
if (pset.sversion >= 120000 && !pset.hide_tableam &&
(showTables || showMatViews || showIndexes))
appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_am am ON am.oid = c.relam");
if (showIndexes)
appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid" "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); if (showTables)
{
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_RELATION) ","
CppAsString2(RELKIND_PARTITIONED_TABLE) ","); /* with 'S' or a pattern, allow 't' to match TOAST tables too */ if (showSystem || pattern)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_TOASTVALUE) ",");
} if (showViews)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_VIEW) ","); if (showMatViews)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_MATVIEW) ","); if (showIndexes)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_INDEX) ","
CppAsString2(RELKIND_PARTITIONED_INDEX) ","); if (showSeq)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_SEQUENCE) ","); if (showSystem || pattern)
appendPQExpBufferStr(&buf, "'s',"); /* was RELKIND_SPECIAL */ if (showForeign)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_FOREIGN_TABLE) ",");
if (!showSystem && !pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname !~ '^pg_toast'\n" " AND n.nspname <> 'information_schema'\n");
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
/* *Mostfunctionsinthisfilearecontenttoprintanemptytablewhen *therearenomatchingobjects.Weintentionallydeviatefromthat *here,butonlyin!quietmode,forhistoricalreasons.
*/ if (PQntuples(res) == 0 && !pset.quiet)
{ if (pattern)
{ if (ntypes != 1)
pg_log_error("Did not find any relations named \"%s\".",
pattern); elseif (showTables)
pg_log_error("Did not find any tables named \"%s\".",
pattern); elseif (showIndexes)
pg_log_error("Did not find any indexes named \"%s\".",
pattern); elseif (showViews)
pg_log_error("Did not find any views named \"%s\".",
pattern); elseif (showMatViews)
pg_log_error("Did not find any materialized views named \"%s\".",
pattern); elseif (showSeq)
pg_log_error("Did not find any sequences named \"%s\".",
pattern); elseif (showForeign)
pg_log_error("Did not find any foreign tables named \"%s\".",
pattern); else/* should not get here */
pg_log_error_internal("Did not find any ??? named \"%s\".",
pattern);
} else
{ if (ntypes != 1)
pg_log_error("Did not find any relations."); elseif (showTables)
pg_log_error("Did not find any tables."); elseif (showIndexes)
pg_log_error("Did not find any indexes."); elseif (showViews)
pg_log_error("Did not find any views."); elseif (showMatViews)
pg_log_error("Did not find any materialized views."); elseif (showSeq)
pg_log_error("Did not find any sequences."); elseif (showForeign)
pg_log_error("Did not find any foreign tables."); else/* should not get here */
pg_log_error_internal("Did not find any ??? relations.");
}
} else
{
myopt.title =
(ntypes != 1) ? _("List of relations") :
(showTables) ? _("List of tables") :
(showIndexes) ? _("List of indexes") :
(showViews) ? _("List of views") :
(showMatViews) ? _("List of materialized views") :
(showSeq) ? _("List of sequences") :
(showForeign) ? _("List of foreign tables") : "List of ???"; /* should not get here */
myopt.translate_header = true;
myopt.translate_columns = translate_columns;
myopt.n_translate_columns = lengthof(translate_columns);
/* *Note:DeclarativetablepartitioningisonlysupportedasofPg10.0.
*/ if (pset.sversion < 100000)
{ char sverbuf[32];
pg_log_error("The server (version %s) does not support declarative table partitioning.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
/* If no relation kind was selected, show them all */ if (!showTables && !showIndexes)
showTables = showIndexes = true;
if (showIndexes && !showTables)
tabletitle = _("List of partitioned indexes"); /* \dPi */ elseif (showTables && !showIndexes)
tabletitle = _("List of partitioned tables"); /* \dPt */ else
{ /* show all kinds */
tabletitle = _("List of partitioned relations");
mixed_output = true;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " c.relname as \"%s\",\n" " pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Owner"));
if (mixed_output)
{
appendPQExpBuffer(&buf, ",\n CASE c.relkind" " WHEN " CppAsString2(RELKIND_PARTITIONED_TABLE) " THEN '%s'" " WHEN " CppAsString2(RELKIND_PARTITIONED_INDEX) " THEN '%s'" " END as \"%s\"",
gettext_noop("partitioned table"),
gettext_noop("partitioned index"),
gettext_noop("Type"));
translate_columns[3] = true;
}
if (showNested || pattern)
appendPQExpBuffer(&buf, ",\n inh.inhparent::pg_catalog.regclass as \"%s\"",
gettext_noop("Parent name"));
if (showIndexes)
appendPQExpBuffer(&buf, ",\n c2.oid::pg_catalog.regclass as \"%s\"",
gettext_noop("Table"));
if (verbose)
{ /* *Tableaccessmethodswereintroducedinv12,andcanbeseton *partitionedtablessincev17.
*/
appendPQExpBuffer(&buf, ",\n am.amname as \"%s\"",
gettext_noop("Access method"));
if (showNested)
{
appendPQExpBuffer(&buf, ",\n s.dps as \"%s\"",
gettext_noop("Leaf partition size"));
appendPQExpBuffer(&buf, ",\n s.tps as \"%s\"",
gettext_noop("Total size"));
} else /* Sizes of all partitions are considered in this case. */
appendPQExpBuffer(&buf, ",\n s.tps as \"%s\"",
gettext_noop("Total size"));
appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
gettext_noop("Description"));
}
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_class c" "\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
if (showIndexes)
appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_index i ON i.indexrelid = c.oid" "\n LEFT JOIN pg_catalog.pg_class c2 ON i.indrelid = c2.oid");
if (showNested || pattern)
appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid");
if (verbose)
{
appendPQExpBufferStr(&buf, "\n LEFT JOIN pg_catalog.pg_am am ON c.relam = am.oid");
if (pset.sversion < 120000)
{
appendPQExpBufferStr(&buf, ",\n LATERAL (WITH RECURSIVE d\n" " AS (SELECT inhrelid AS oid, 1 AS level\n" " FROM pg_catalog.pg_inherits\n" " WHERE inhparent = c.oid\n" " UNION ALL\n" " SELECT inhrelid, level + 1\n" " FROM pg_catalog.pg_inherits i\n" " JOIN d ON i.inhparent = d.oid)\n" " SELECT pg_catalog.pg_size_pretty(sum(pg_catalog.pg_table_size(" "d.oid))) AS tps,\n" " pg_catalog.pg_size_pretty(sum(" "\n CASE WHEN d.level = 1" " THEN pg_catalog.pg_table_size(d.oid) ELSE 0 END)) AS dps\n" " FROM d) s");
} else
{ /* PostgreSQL 12 has pg_partition_tree function */
appendPQExpBufferStr(&buf, ",\n LATERAL (SELECT pg_catalog.pg_size_pretty(sum(" "\n CASE WHEN ppt.isleaf AND ppt.level = 1" "\n THEN pg_catalog.pg_table_size(ppt.relid)" " ELSE 0 END)) AS dps" ",\n pg_catalog.pg_size_pretty(sum(" "pg_catalog.pg_table_size(ppt.relid))) AS tps" "\n FROM pg_catalog.pg_partition_tree(c.oid) ppt) s");
}
}
appendPQExpBufferStr(&buf, "\nWHERE c.relkind IN ("); if (showTables)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_TABLE) ","); if (showIndexes)
appendPQExpBufferStr(&buf, CppAsString2(RELKIND_PARTITIONED_INDEX) ",");
appendPQExpBufferStr(&buf, "''"); /* dummy */
appendPQExpBufferStr(&buf, ")\n");
appendPQExpBufferStr(&buf, !showNested && !pattern ? " AND NOT c.relispartition\n" : "");
if (!pattern)
appendPQExpBufferStr(&buf, " AND n.nspname <> 'pg_catalog'\n" " AND n.nspname !~ '^pg_toast'\n" " AND n.nspname <> 'information_schema'\n");
printfPQExpBuffer(&buf, "SELECT n.nspname as \"%s\",\n" " t.typname as \"%s\",\n" " pg_catalog.format_type(t.typbasetype, t.typtypmod) as \"%s\",\n" " (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type bt\n" " WHERE c.oid = t.typcollation AND bt.oid = t.typbasetype AND t.typcollation <> bt.typcollation) as \"%s\",\n" " CASE WHEN t.typnotnull THEN 'not null' END as \"%s\",\n" " t.typdefault as \"%s\",\n" " pg_catalog.array_to_string(ARRAY(\n" " 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" " ), ' ') as \"%s\"",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Type"),
gettext_noop("Collation"),
gettext_noop("Nullable"),
gettext_noop("Default"),
gettext_noop("Check"));
if (verbose)
{
appendPQExpBufferStr(&buf, ",\n ");
printACLColumn(&buf, "t.typacl");
appendPQExpBuffer(&buf, ",\n d.description as \"%s\"",
gettext_noop("Description"));
}
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_type t\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_description d " "ON d.classoid = t.tableoid AND d.objoid = t.oid " "AND d.objsubid = 0\n");
printfPQExpBuffer(&buf, "SELECT n.nspname AS \"%s\",\n" " c.conname AS \"%s\",\n" " pg_catalog.pg_encoding_to_char(c.conforencoding) AS \"%s\",\n" " pg_catalog.pg_encoding_to_char(c.contoencoding) AS \"%s\",\n" " CASE WHEN c.condefault THEN '%s'\n" " ELSE '%s' END AS \"%s\"",
gettext_noop("Schema"),
gettext_noop("Name"),
gettext_noop("Source"),
gettext_noop("Destination"),
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Default?"));
if (verbose)
appendPQExpBuffer(&buf, ",\n d.description AS \"%s\"",
gettext_noop("Description"));
pg_log_error("The server (version %s) does not support event triggers.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT evtname as \"%s\", " "evtevent as \"%s\", " "pg_catalog.pg_get_userbyid(e.evtowner) as \"%s\",\n" " case evtenabled when 'O' then '%s'" " when 'R' then '%s'" " when 'A' then '%s'" " when 'D' then '%s' end as \"%s\",\n" " e.evtfoid::pg_catalog.regproc as \"%s\", " "pg_catalog.array_to_string(array(select x" " from pg_catalog.unnest(evttags) as t(x)), ', ') as \"%s\"",
gettext_noop("Name"),
gettext_noop("Event"),
gettext_noop("Owner"),
gettext_noop("enabled"),
gettext_noop("replica"),
gettext_noop("always"),
gettext_noop("disabled"),
gettext_noop("Enabled"),
gettext_noop("Function"),
gettext_noop("Tags")); if (verbose)
appendPQExpBuffer(&buf, ",\npg_catalog.obj_description(e.oid, 'pg_event_trigger') as \"%s\"",
gettext_noop("Description"));
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_event_trigger e ");
pg_log_error("The server (version %s) does not support extended statistics.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT \n" "es.stxnamespace::pg_catalog.regnamespace::pg_catalog.text AS \"%s\", \n" "es.stxname AS \"%s\", \n",
gettext_noop("Schema"),
gettext_noop("Name"));
if (pset.sversion >= 140000)
appendPQExpBuffer(&buf, "pg_catalog.format('%%s FROM %%s', \n" " pg_catalog.pg_get_statisticsobjdef_columns(es.oid), \n" " es.stxrelid::pg_catalog.regclass) AS \"%s\"",
gettext_noop("Definition")); else
appendPQExpBuffer(&buf, "pg_catalog.format('%%s FROM %%s', \n" " (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(a.attname),', ') \n" " FROM pg_catalog.unnest(es.stxkeys) s(attnum) \n" " JOIN pg_catalog.pg_attribute a \n" " ON (es.stxrelid = a.attrelid \n" " AND a.attnum = s.attnum \n" " AND NOT a.attisdropped)), \n" "es.stxrelid::pg_catalog.regclass) AS \"%s\"",
gettext_noop("Definition"));
appendPQExpBuffer(&buf, ",\nCASE WHEN " CppAsString2(STATS_EXT_NDISTINCT) " = any(es.stxkind) THEN 'defined' \n" "END AS \"%s\", \n" "CASE WHEN " CppAsString2(STATS_EXT_DEPENDENCIES) " = any(es.stxkind) THEN 'defined' \n" "END AS \"%s\"",
gettext_noop("Ndistinct"),
gettext_noop("Dependencies"));
/* *IncludetheMCVstatisticskind.
*/ if (pset.sversion >= 120000)
{
appendPQExpBuffer(&buf, ",\nCASE WHEN " CppAsString2(STATS_EXT_MCV) " = any(es.stxkind) THEN 'defined' \n" "END AS \"%s\" ",
gettext_noop("MCV"));
}
appendPQExpBufferStr(&buf, " \nFROM pg_catalog.pg_statistic_ext es \n");
printfPQExpBuffer(&buf, "SELECT pg_catalog.format_type(castsource, NULL) AS \"%s\",\n" " pg_catalog.format_type(casttarget, NULL) AS \"%s\",\n",
gettext_noop("Source type"),
gettext_noop("Target type"));
/* *Wedon'tattempttolocalize'(binarycoercible)'or'(withinout)', *becausethere'stoomuchriskofgettexttranslatingafunctionname *thathappenstomatchsomestringinthePOdatabase.
*/
appendPQExpBuffer(&buf, " CASE WHEN c.castmethod = '%c' THEN '(binary coercible)'\n" " WHEN c.castmethod = '%c' THEN '(with inout)'\n" " ELSE p.proname\n" " END AS \"%s\",\n",
COERCION_METHOD_BINARY,
COERCION_METHOD_INOUT,
gettext_noop("Function"));
appendPQExpBuffer(&buf, " CASE WHEN c.castcontext = '%c' THEN '%s'\n" " WHEN c.castcontext = '%c' THEN '%s'\n" " ELSE '%s'\n" " END AS \"%s\"",
COERCION_CODE_EXPLICIT,
gettext_noop("no"),
COERCION_CODE_ASSIGNMENT,
gettext_noop("in assignment"),
gettext_noop("yes"),
gettext_noop("Implicit?"));
if (verbose)
appendPQExpBuffer(&buf, ",\n CASE WHEN p.proleakproof THEN '%s'\n" " ELSE '%s'\n" " END AS \"%s\",\n" " d.description AS \"%s\"",
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Leakproof?"),
gettext_noop("Description"));
/* *Weneedaleftjointopg_procforbinarycasts;theothersarejust *paranoia.
*/
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p\n" " ON c.castfunc = p.oid\n" " LEFT JOIN pg_catalog.pg_type ts\n" " ON c.castsource = ts.oid\n" " LEFT JOIN pg_catalog.pg_namespace ns\n" " ON ns.oid = ts.typnamespace\n" " LEFT JOIN pg_catalog.pg_type tt\n" " ON c.casttarget = tt.oid\n" " LEFT JOIN pg_catalog.pg_namespace nt\n" " ON nt.oid = tt.typnamespace\n");
if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_description d\n" " ON d.classoid = c.tableoid AND d.objoid = " "c.oid AND d.objsubid = 0\n");
printfPQExpBuffer(&buf, "SELECT\n" " n.nspname AS \"%s\",\n" " c.collname AS \"%s\",\n",
gettext_noop("Schema"),
gettext_noop("Name"));
if (pset.sversion >= 100000)
appendPQExpBuffer(&buf, " CASE c.collprovider " "WHEN " CppAsString2(COLLPROVIDER_DEFAULT) " THEN 'default' " "WHEN " CppAsString2(COLLPROVIDER_BUILTIN) " THEN 'builtin' " "WHEN " CppAsString2(COLLPROVIDER_LIBC) " THEN 'libc' " "WHEN " CppAsString2(COLLPROVIDER_ICU) " THEN 'icu' " "END AS \"%s\",\n",
gettext_noop("Provider")); else
appendPQExpBuffer(&buf, " 'libc' AS \"%s\",\n",
gettext_noop("Provider"));
appendPQExpBuffer(&buf, " c.collcollate AS \"%s\",\n" " c.collctype AS \"%s\",\n",
gettext_noop("Collate"),
gettext_noop("Ctype"));
if (pset.sversion >= 170000)
appendPQExpBuffer(&buf, " c.colllocale AS \"%s\",\n",
gettext_noop("Locale")); elseif (pset.sversion >= 150000)
appendPQExpBuffer(&buf, " c.colliculocale AS \"%s\",\n",
gettext_noop("Locale")); else
appendPQExpBuffer(&buf, " c.collcollate AS \"%s\",\n",
gettext_noop("Locale"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf, " c.collicurules AS \"%s\",\n",
gettext_noop("ICU Rules")); else
appendPQExpBuffer(&buf, " NULL AS \"%s\",\n",
gettext_noop("ICU Rules"));
if (pset.sversion >= 120000)
appendPQExpBuffer(&buf, " CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \"%s\"",
gettext_noop("yes"), gettext_noop("no"),
gettext_noop("Deterministic?")); else
appendPQExpBuffer(&buf, " '%s' AS \"%s\"",
gettext_noop("yes"),
gettext_noop("Deterministic?"));
if (verbose)
appendPQExpBuffer(&buf, ",\n pg_catalog.obj_description(c.oid, 'pg_collation') AS \"%s\"",
gettext_noop("Description"));
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
if (PQntuples(res) == 0)
{ if (!pset.quiet)
{ if (pattern)
pg_log_error("Did not find any text search parser named \"%s\".",
pattern); else
pg_log_error("Did not find any text search parsers.");
}
PQclear(res); returnfalse;
}
for (i = 0; i < PQntuples(res); i++)
{ constchar *oid; constchar *nspname = NULL; constchar *prsname;
oid = PQgetvalue(res, i, 0); if (!PQgetisnull(res, i, 1))
nspname = PQgetvalue(res, i, 1);
prsname = PQgetvalue(res, i, 2);
if (!describeOneTSParser(oid, nspname, prsname))
{
PQclear(res); returnfalse;
}
if (cancel_pressed)
{
PQclear(res); returnfalse;
}
}
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
if (PQntuples(res) == 0)
{ if (!pset.quiet)
{ if (pattern)
pg_log_error("Did not find any text search configuration named \"%s\".",
pattern); else
pg_log_error("Did not find any text search configurations.");
}
PQclear(res); returnfalse;
}
for (i = 0; i < PQntuples(res); i++)
{ constchar *oid; constchar *cfgname; constchar *nspname = NULL; constchar *prsname; constchar *pnspname = NULL;
oid = PQgetvalue(res, i, 0);
cfgname = PQgetvalue(res, i, 1); if (!PQgetisnull(res, i, 2))
nspname = PQgetvalue(res, i, 2);
prsname = PQgetvalue(res, i, 3); if (!PQgetisnull(res, i, 4))
pnspname = PQgetvalue(res, i, 4);
if (!describeOneTSConfig(oid, nspname, cfgname, pnspname, prsname))
{
PQclear(res); returnfalse;
}
if (cancel_pressed)
{
PQclear(res); returnfalse;
}
}
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
if (PQntuples(res) == 0)
{ if (!pset.quiet)
{ if (pattern)
pg_log_error("Did not find any extension named \"%s\".",
pattern); else
pg_log_error("Did not find any extensions.");
}
PQclear(res); returnfalse;
}
for (i = 0; i < PQntuples(res); i++)
{ constchar *extname; constchar *oid;
extname = PQgetvalue(res, i, 0);
oid = PQgetvalue(res, i, 1);
if (!listOneExtensionContents(extname, oid))
{
PQclear(res); returnfalse;
} if (cancel_pressed)
{
PQclear(res); returnfalse;
}
}
if (dotcnt >= maxparts)
{
pg_log_error("improper qualified name (too many dotted names): %s",
pattern); goto error_return;
}
if (maxparts > 1 && dotcnt == maxparts - 1)
{ if (PQdb(pset.db) == NULL)
{
pg_log_error("You are currently not connected to a database."); goto error_return;
} if (strcmp(PQdb(pset.db), dbbuf.data) != 0)
{
pg_log_error("cross-database references are not implemented: %s",
pattern); goto error_return;
}
}
termPQExpBuffer(&dbbuf); returntrue;
pg_log_error("The server (version %s) does not support publications.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT pubname AS \"%s\",\n" " pg_catalog.pg_get_userbyid(pubowner) AS \"%s\",\n" " puballtables AS \"%s\",\n" " pubinsert AS \"%s\",\n" " pubupdate AS \"%s\",\n" " pubdelete AS \"%s\"",
gettext_noop("Name"),
gettext_noop("Owner"),
gettext_noop("All tables"),
gettext_noop("Inserts"),
gettext_noop("Updates"),
gettext_noop("Deletes")); if (pset.sversion >= 110000)
appendPQExpBuffer(&buf, ",\n pubtruncate AS \"%s\"",
gettext_noop("Truncates")); if (pset.sversion >= 180000)
appendPQExpBuffer(&buf, ",\n (CASE pubgencols\n" " WHEN '%c' THEN 'none'\n" " WHEN '%c' THEN 'stored'\n" " END) AS \"%s\"",
PUBLISH_GENCOLS_NONE,
PUBLISH_GENCOLS_STORED,
gettext_noop("Generated columns")); if (pset.sversion >= 130000)
appendPQExpBuffer(&buf, ",\n pubviaroot AS \"%s\"",
gettext_noop("Via root"));
/* *Addfootertopublicationdescription.
*/ staticbool
addFooterToPublicationDesc(PQExpBuffer buf, constchar *footermsg, bool as_schema, printTableContent *const cont)
{
PGresult *res; int count = 0; int i = 0;
res = PSQLexec(buf->data); if (!res) returnfalse; else
count = PQntuples(res);
if (count > 0)
printTableAddFooter(cont, footermsg);
for (i = 0; i < count; i++)
{ if (as_schema)
printfPQExpBuffer(buf, " \"%s\"", PQgetvalue(res, i, 0)); else
{
printfPQExpBuffer(buf, " \"%s.%s\"", PQgetvalue(res, i, 0),
PQgetvalue(res, i, 1));
if (!PQgetisnull(res, i, 3))
appendPQExpBuffer(buf, " (%s)", PQgetvalue(res, i, 3));
if (!PQgetisnull(res, i, 2))
appendPQExpBuffer(buf, " WHERE %s", PQgetvalue(res, i, 2));
}
pg_log_error("The server (version %s) does not support publications.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
printfPQExpBuffer(&buf, "SELECT oid, pubname,\n" " pg_catalog.pg_get_userbyid(pubowner) AS owner,\n" " puballtables, pubinsert, pubupdate, pubdelete"); if (has_pubtruncate)
appendPQExpBufferStr(&buf, ", pubtruncate"); else
appendPQExpBufferStr(&buf, ", false AS pubtruncate");
if (has_pubgencols)
appendPQExpBuffer(&buf, ", (CASE pubgencols\n" " WHEN '%c' THEN 'none'\n" " WHEN '%c' THEN 'stored'\n" " END) AS \"%s\"\n",
PUBLISH_GENCOLS_NONE,
PUBLISH_GENCOLS_STORED,
gettext_noop("Generated columns")); else
appendPQExpBufferStr(&buf, ", 'none' AS pubgencols");
if (has_pubviaroot)
appendPQExpBufferStr(&buf, ", pubviaroot"); else
appendPQExpBufferStr(&buf, ", false AS pubviaroot");
res = PSQLexec(buf.data); if (!res)
{
termPQExpBuffer(&buf); returnfalse;
}
if (PQntuples(res) == 0)
{ if (!pset.quiet)
{ if (pattern)
pg_log_error("Did not find any publication named \"%s\".",
pattern); else
pg_log_error("Did not find any publications.");
}
printTableAddCell(&cont, PQgetvalue(res, i, 2), false, false);
printTableAddCell(&cont, PQgetvalue(res, i, 3), false, false);
printTableAddCell(&cont, PQgetvalue(res, i, 4), false, false);
printTableAddCell(&cont, PQgetvalue(res, i, 5), false, false);
printTableAddCell(&cont, PQgetvalue(res, i, 6), false, false); if (has_pubtruncate)
printTableAddCell(&cont, PQgetvalue(res, i, 7), false, false); if (has_pubgencols)
printTableAddCell(&cont, PQgetvalue(res, i, 8), false, false); if (has_pubviaroot)
printTableAddCell(&cont, PQgetvalue(res, i, 9), false, false);
if (!puballtables)
{ /* Get the tables for the specified publication */
printfPQExpBuffer(&buf, "SELECT n.nspname, c.relname"); if (pset.sversion >= 150000)
{
appendPQExpBufferStr(&buf, ", pg_get_expr(pr.prqual, c.oid)");
appendPQExpBufferStr(&buf, ", (CASE WHEN pr.prattrs IS NOT NULL THEN\n" " pg_catalog.array_to_string(" " ARRAY(SELECT attname\n" " FROM\n" " pg_catalog.generate_series(0, pg_catalog.array_upper(pr.prattrs::pg_catalog.int2[], 1)) s,\n" " pg_catalog.pg_attribute\n" " WHERE attrelid = c.oid AND attnum = prattrs[s]), ', ')\n" " ELSE NULL END)");
} else
appendPQExpBufferStr(&buf, ", NULL, NULL");
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_class c,\n" " pg_catalog.pg_namespace n,\n" " pg_catalog.pg_publication_rel pr\n" "WHERE c.relnamespace = n.oid\n" " AND c.oid = pr.prrelid\n" " AND pr.prpubid = '%s'\n" "ORDER BY 1,2", pubid); if (!addFooterToPublicationDesc(&buf, _("Tables:"), false, &cont)) goto error_return;
if (pset.sversion >= 150000)
{ /* Get the schemas for the specified publication */
printfPQExpBuffer(&buf, "SELECT n.nspname\n" "FROM pg_catalog.pg_namespace n\n" " JOIN pg_catalog.pg_publication_namespace pn ON n.oid = pn.pnnspid\n" "WHERE pn.pnpubid = '%s'\n" "ORDER BY 1", pubid); if (!addFooterToPublicationDesc(&buf, _("Tables from schemas:"), true, &cont)) goto error_return;
}
}
pg_log_error("The server (version %s) does not support subscriptions.",
formatPGVersionNumber(pset.sversion, false,
sverbuf, sizeof(sverbuf))); returntrue;
}
initPQExpBuffer(&buf);
printfPQExpBuffer(&buf, "SELECT subname AS \"%s\"\n" ", pg_catalog.pg_get_userbyid(subowner) AS \"%s\"\n" ", subenabled AS \"%s\"\n" ", subpublications AS \"%s\"\n",
gettext_noop("Name"),
gettext_noop("Owner"),
gettext_noop("Enabled"),
gettext_noop("Publication"));
if (verbose)
{ /* Binary mode and streaming are only supported in v14 and higher */ if (pset.sversion >= 140000)
{
appendPQExpBuffer(&buf, ", subbinary AS \"%s\"\n",
gettext_noop("Binary"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf, ", (CASE substream\n" " WHEN " CppAsString2(LOGICALREP_STREAM_OFF) " THEN 'off'\n" " WHEN " CppAsString2(LOGICALREP_STREAM_ON) " THEN 'on'\n" " WHEN " CppAsString2(LOGICALREP_STREAM_PARALLEL) " THEN 'parallel'\n" " END) AS \"%s\"\n",
gettext_noop("Streaming")); else
appendPQExpBuffer(&buf, ", substream AS \"%s\"\n",
gettext_noop("Streaming"));
}
/* Two_phase and disable_on_error are only supported in v15 and higher */ if (pset.sversion >= 150000)
appendPQExpBuffer(&buf, ", subtwophasestate AS \"%s\"\n" ", subdisableonerr AS \"%s\"\n",
gettext_noop("Two-phase commit"),
gettext_noop("Disable on error"));
if (pset.sversion >= 160000)
appendPQExpBuffer(&buf, ", suborigin AS \"%s\"\n" ", subpasswordrequired AS \"%s\"\n" ", subrunasowner AS \"%s\"\n",
gettext_noop("Origin"),
gettext_noop("Password required"),
gettext_noop("Run as owner?"));
if (pset.sversion >= 170000)
appendPQExpBuffer(&buf, ", subfailover AS \"%s\"\n",
gettext_noop("Failover"));
appendPQExpBuffer(&buf, ", subsynccommit AS \"%s\"\n" ", subconninfo AS \"%s\"\n",
gettext_noop("Synchronous commit"),
gettext_noop("Conninfo"));
/* Skip LSN is only supported in v15 and higher */ if (pset.sversion >= 150000)
appendPQExpBuffer(&buf, ", subskiplsn AS \"%s\"\n",
gettext_noop("Skip LSN"));
}
/* Only display subscriptions in current database. */
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_subscription\n" "WHERE subdbid = (SELECT oid\n" " FROM pg_catalog.pg_database\n" " WHERE datname = pg_catalog.current_database())");
printfPQExpBuffer(&buf, "SELECT\n" " am.amname AS \"%s\",\n" " pg_catalog.format_type(c.opcintype, NULL) AS \"%s\",\n" " CASE\n" " WHEN c.opckeytype <> 0 AND c.opckeytype <> c.opcintype\n" " THEN pg_catalog.format_type(c.opckeytype, NULL)\n" " ELSE NULL\n" " END AS \"%s\",\n" " CASE\n" " WHEN pg_catalog.pg_opclass_is_visible(c.oid)\n" " THEN pg_catalog.format('%%I', c.opcname)\n" " ELSE pg_catalog.format('%%I.%%I', n.nspname, c.opcname)\n" " END AS \"%s\",\n" " (CASE WHEN c.opcdefault\n" " THEN '%s'\n" " ELSE '%s'\n" " END) AS \"%s\"",
gettext_noop("AM"),
gettext_noop("Input type"),
gettext_noop("Storage type"),
gettext_noop("Operator class"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Default?")); if (verbose)
appendPQExpBuffer(&buf, ",\n CASE\n" " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" " THEN pg_catalog.format('%%I', of.opfname)\n" " ELSE pg_catalog.format('%%I.%%I', ofn.nspname, of.opfname)\n" " END AS \"%s\",\n" " pg_catalog.pg_get_userbyid(c.opcowner) AS \"%s\"\n",
gettext_noop("Operator family"),
gettext_noop("Owner"));
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_opclass c\n" " LEFT JOIN pg_catalog.pg_am am on am.oid = c.opcmethod\n" " LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.opcnamespace\n" " LEFT JOIN pg_catalog.pg_type t ON t.oid = c.opcintype\n" " LEFT JOIN pg_catalog.pg_namespace tn ON tn.oid = t.typnamespace\n"); if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = c.opcfamily\n" " LEFT JOIN pg_catalog.pg_namespace ofn ON ofn.oid = of.opfnamespace\n");
if (access_method_pattern) if (!validateSQLNamePattern(&buf, access_method_pattern, false, false, NULL, "am.amname", NULL, NULL,
&have_where, 1)) goto error_return; if (type_pattern)
{ /* Match type name pattern against either internal or external name */ if (!validateSQLNamePattern(&buf, type_pattern, have_where, false, "tn.nspname", "t.typname", "pg_catalog.format_type(t.oid, NULL)", "pg_catalog.pg_type_is_visible(t.oid)",
NULL, 3)) goto error_return;
}
appendPQExpBufferStr(&buf, "ORDER BY 1, 2, 4;");
res = PSQLexec(buf.data);
termPQExpBuffer(&buf); if (!res) returnfalse;
printfPQExpBuffer(&buf, "SELECT\n" " am.amname AS \"%s\",\n" " CASE\n" " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" " THEN pg_catalog.format('%%I', of.opfname)\n" " ELSE pg_catalog.format('%%I.%%I', nsf.nspname, of.opfname)\n" " END AS \"%s\",\n" " o.amopopr::pg_catalog.regoperator AS \"%s\"\n," " o.amopstrategy AS \"%s\",\n" " CASE o.amoppurpose\n" " WHEN " CppAsString2(AMOP_ORDER) " THEN '%s'\n" " WHEN " CppAsString2(AMOP_SEARCH) " THEN '%s'\n" " END AS \"%s\"\n",
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Operator"),
gettext_noop("Strategy"),
gettext_noop("ordering"),
gettext_noop("search"),
gettext_noop("Purpose"));
if (verbose)
appendPQExpBuffer(&buf, ", ofs.opfname AS \"%s\",\n" " CASE\n" " WHEN p.proleakproof THEN '%s'\n" " ELSE '%s'\n" " END AS \"%s\"\n",
gettext_noop("Sort opfamily"),
gettext_noop("yes"),
gettext_noop("no"),
gettext_noop("Leakproof?"));
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_amop o\n" " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = o.amopfamily\n" " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod AND am.oid = o.amopmethod\n" " LEFT JOIN pg_catalog.pg_namespace nsf ON of.opfnamespace = nsf.oid\n"); if (verbose)
appendPQExpBufferStr(&buf, " LEFT JOIN pg_catalog.pg_opfamily ofs ON ofs.oid = o.amopsortfamily\n" " LEFT JOIN pg_catalog.pg_operator op ON op.oid = o.amopopr\n" " LEFT JOIN pg_catalog.pg_proc p ON p.oid = op.oprcode\n");
if (access_method_pattern)
{ if (!validateSQLNamePattern(&buf, access_method_pattern, false, false, NULL, "am.amname",
NULL, NULL,
&have_where, 1)) goto error_return;
}
if (family_pattern)
{ if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, "nsf.nspname", "of.opfname", NULL, NULL,
NULL, 3)) goto error_return;
}
printfPQExpBuffer(&buf, "SELECT\n" " am.amname AS \"%s\",\n" " CASE\n" " WHEN pg_catalog.pg_opfamily_is_visible(of.oid)\n" " THEN pg_catalog.format('%%I', of.opfname)\n" " ELSE pg_catalog.format('%%I.%%I', ns.nspname, of.opfname)\n" " END AS \"%s\",\n" " pg_catalog.format_type(ap.amproclefttype, NULL) AS \"%s\",\n" " pg_catalog.format_type(ap.amprocrighttype, NULL) AS \"%s\",\n" " ap.amprocnum AS \"%s\"\n",
gettext_noop("AM"),
gettext_noop("Operator family"),
gettext_noop("Registered left type"),
gettext_noop("Registered right type"),
gettext_noop("Number"));
if (!verbose)
appendPQExpBuffer(&buf, ", p.proname AS \"%s\"\n",
gettext_noop("Function")); else
appendPQExpBuffer(&buf, ", ap.amproc::pg_catalog.regprocedure AS \"%s\"\n",
gettext_noop("Function"));
appendPQExpBufferStr(&buf, "FROM pg_catalog.pg_amproc ap\n" " LEFT JOIN pg_catalog.pg_opfamily of ON of.oid = ap.amprocfamily\n" " LEFT JOIN pg_catalog.pg_am am ON am.oid = of.opfmethod\n" " LEFT JOIN pg_catalog.pg_namespace ns ON of.opfnamespace = ns.oid\n" " LEFT JOIN pg_catalog.pg_proc p ON ap.amproc = p.oid\n");
if (access_method_pattern)
{ if (!validateSQLNamePattern(&buf, access_method_pattern, false, false, NULL, "am.amname",
NULL, NULL,
&have_where, 1)) goto error_return;
} if (family_pattern)
{ if (!validateSQLNamePattern(&buf, family_pattern, have_where, false, "ns.nspname", "of.opfname", NULL, NULL,
NULL, 3)) goto error_return;
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.217Bemerkung:
(vorverarbeitet am 2026-08-07)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.