Fix psql's \d and allied commands to work with all server versions back to 7.4.
Guillaume Lelarge, with some additional fixes by me.
This commit is contained in:
parent
2c2aff6acd
commit
0a8f6b797a
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.208 2008/06/11 10:48:16 heikki Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.209 2008/07/03 03:37:16 tgl Exp $
|
||||||
PostgreSQL documentation
|
PostgreSQL documentation
|
||||||
-->
|
-->
|
||||||
|
|
||||||
@ -2859,26 +2859,22 @@ $endif
|
|||||||
<para>
|
<para>
|
||||||
In an earlier life <application>psql</application> allowed the
|
In an earlier life <application>psql</application> allowed the
|
||||||
first argument of a single-letter backslash command to start
|
first argument of a single-letter backslash command to start
|
||||||
directly after the command, without intervening whitespace. For
|
directly after the command, without intervening whitespace.
|
||||||
compatibility this is still supported to some extent,
|
As of <productname>PostgreSQL</productname> 8.4 this is no
|
||||||
but we are not going to explain the details here as this use is
|
longer allowed.
|
||||||
discouraged. If you get strange messages, keep this in mind.
|
|
||||||
For example:
|
|
||||||
<programlisting>
|
|
||||||
testdb=> <userinput>\foo</userinput>
|
|
||||||
Field separator is "oo".
|
|
||||||
</programlisting>
|
|
||||||
which is perhaps not what one would expect.
|
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
<application>psql</application> only works smoothly with servers
|
<application>psql</application> is only guaranteed to work smoothly
|
||||||
of the same version. That does not mean other combinations will
|
with servers of the same version. That does not mean other combinations
|
||||||
fail outright, but subtle and not-so-subtle problems might come
|
will fail outright, but subtle and not-so-subtle problems might come
|
||||||
up. Backslash commands are particularly likely to fail if the
|
up. Backslash commands are particularly likely to fail if the
|
||||||
server is of a different version.
|
server is of a newer version than <application>psql</> itself. However,
|
||||||
|
backslash commands of the <literal>\d</> family should work with
|
||||||
|
servers of versions back to 7.4, though not necessarily with servers
|
||||||
|
newer than <application>psql</> itself.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
@ -1,9 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* psql - the PostgreSQL interactive terminal
|
* psql - the PostgreSQL interactive terminal
|
||||||
*
|
*
|
||||||
|
* Support for the various \d ("describe") commands. Note that the current
|
||||||
|
* expectation is that all functions in this file will succeed when working
|
||||||
|
* with servers of versions 7.4 and up. It's okay to omit irrelevant
|
||||||
|
* information for an old server, but not to fail outright.
|
||||||
|
*
|
||||||
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.173 2008/05/13 00:23:17 alvherre Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.174 2008/07/03 03:37:17 tgl Exp $
|
||||||
*/
|
*/
|
||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
@ -38,7 +43,7 @@ static bool describeOneTSConfig(const char *oid, const char *nspname,
|
|||||||
* Handlers for various slash commands displaying some sort of list
|
* Handlers for various slash commands displaying some sort of list
|
||||||
* of things in the database.
|
* of things in the database.
|
||||||
*
|
*
|
||||||
* If you add something here, try to format the query to look nice in -E output.
|
* Note: try to format the queries to look nice in -E output.
|
||||||
*----------------
|
*----------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -55,14 +60,16 @@ describeAggregates(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
/*
|
|
||||||
* There are two kinds of aggregates: ones that work on particular types
|
|
||||||
* and ones that work on all (denoted by input type = "any")
|
|
||||||
*/
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT n.nspname as \"%s\",\n"
|
"SELECT n.nspname as \"%s\",\n"
|
||||||
" p.proname AS \"%s\",\n"
|
" p.proname AS \"%s\",\n"
|
||||||
" pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n"
|
" pg_catalog.format_type(p.prorettype, NULL) AS \"%s\",\n",
|
||||||
|
gettext_noop("Schema"),
|
||||||
|
gettext_noop("Name"),
|
||||||
|
gettext_noop("Result data type"));
|
||||||
|
|
||||||
|
if (pset.sversion >= 80200)
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
" CASE WHEN p.pronargs = 0\n"
|
" CASE WHEN p.pronargs = 0\n"
|
||||||
" THEN CAST('*' AS pg_catalog.text)\n"
|
" THEN CAST('*' AS pg_catalog.text)\n"
|
||||||
" ELSE\n"
|
" ELSE\n"
|
||||||
@ -72,22 +79,25 @@ describeAggregates(const char *pattern, bool verbose)
|
|||||||
" FROM\n"
|
" FROM\n"
|
||||||
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
|
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
|
||||||
" ), ', ')\n"
|
" ), ', ')\n"
|
||||||
" END AS \"%s\",\n"
|
" END AS \"%s\",\n",
|
||||||
|
gettext_noop("Argument data types"));
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
|
" pg_catalog.format_type(p.proargtypes[0], NULL) AS \"%s\",\n",
|
||||||
|
gettext_noop("Argument data types"));
|
||||||
|
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
" pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
|
" pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"\n"
|
||||||
"FROM pg_catalog.pg_proc p\n"
|
"FROM pg_catalog.pg_proc p\n"
|
||||||
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
|
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n"
|
||||||
"WHERE p.proisagg\n",
|
"WHERE p.proisagg\n",
|
||||||
gettext_noop("Schema"),
|
|
||||||
gettext_noop("Name"),
|
|
||||||
gettext_noop("Result data type"),
|
|
||||||
gettext_noop("Argument data types"),
|
|
||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
|
|
||||||
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
||||||
"n.nspname", "p.proname", NULL,
|
"n.nspname", "p.proname", NULL,
|
||||||
"pg_catalog.pg_function_is_visible(p.oid)");
|
"pg_catalog.pg_function_is_visible(p.oid)");
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3;");
|
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 4;");
|
||||||
|
|
||||||
res = PSQLexec(buf.data, false);
|
res = PSQLexec(buf.data, false);
|
||||||
termPQExpBuffer(&buf);
|
termPQExpBuffer(&buf);
|
||||||
@ -116,8 +126,8 @@ describeTablespaces(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
if (pset.sversion < 80000)
|
if (pset.sversion < 80000)
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("The server version (%d) does not support tablespaces.\n"),
|
fprintf(stderr, _("The server (version %d.%d) does not support tablespaces.\n"),
|
||||||
pset.sversion);
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,9 +143,11 @@ describeTablespaces(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n spcacl AS \"%s\""
|
",\n spcacl AS \"%s\"",
|
||||||
|
gettext_noop("Access privileges"));
|
||||||
|
if (verbose && pset.sversion >= 80200)
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
|
",\n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \"%s\"",
|
||||||
gettext_noop("Access privileges"),
|
|
||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
@ -179,7 +191,13 @@ describeFunctions(const char *pattern, bool verbose)
|
|||||||
"SELECT n.nspname as \"%s\",\n"
|
"SELECT n.nspname as \"%s\",\n"
|
||||||
" p.proname as \"%s\",\n"
|
" p.proname as \"%s\",\n"
|
||||||
" CASE WHEN p.proretset THEN 'setof ' ELSE '' END ||\n"
|
" CASE WHEN p.proretset THEN 'setof ' ELSE '' END ||\n"
|
||||||
" pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n"
|
" pg_catalog.format_type(p.prorettype, NULL) as \"%s\",\n",
|
||||||
|
gettext_noop("Schema"),
|
||||||
|
gettext_noop("Name"),
|
||||||
|
gettext_noop("Result data type"));
|
||||||
|
|
||||||
|
if (pset.sversion >= 80100)
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
" CASE WHEN proallargtypes IS NOT NULL THEN\n"
|
" CASE WHEN proallargtypes IS NOT NULL THEN\n"
|
||||||
" pg_catalog.array_to_string(ARRAY(\n"
|
" pg_catalog.array_to_string(ARRAY(\n"
|
||||||
" SELECT\n"
|
" SELECT\n"
|
||||||
@ -208,9 +226,10 @@ describeFunctions(const char *pattern, bool verbose)
|
|||||||
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
|
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i)\n"
|
||||||
" ), ', ')\n"
|
" ), ', ')\n"
|
||||||
" END AS \"%s\"",
|
" END AS \"%s\"",
|
||||||
gettext_noop("Schema"),
|
gettext_noop("Argument data types"));
|
||||||
gettext_noop("Name"),
|
else
|
||||||
gettext_noop("Result data type"),
|
appendPQExpBuffer(&buf,
|
||||||
|
" pg_catalog.oidvectortypes(p.proargtypes) as \"%s\"",
|
||||||
gettext_noop("Argument data types"));
|
gettext_noop("Argument data types"));
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@ -220,7 +239,7 @@ describeFunctions(const char *pattern, bool verbose)
|
|||||||
" WHEN p.provolatile = 's' THEN 'stable'\n"
|
" WHEN p.provolatile = 's' THEN 'stable'\n"
|
||||||
" WHEN p.provolatile = 'v' THEN 'volatile'\n"
|
" WHEN p.provolatile = 'v' THEN 'volatile'\n"
|
||||||
"END as \"%s\""
|
"END as \"%s\""
|
||||||
",\n r.rolname as \"%s\",\n"
|
",\n pg_catalog.pg_get_userbyid(p.proowner) as \"%s\",\n"
|
||||||
" l.lanname as \"%s\",\n"
|
" l.lanname as \"%s\",\n"
|
||||||
" p.prosrc as \"%s\",\n"
|
" p.prosrc as \"%s\",\n"
|
||||||
" pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
|
" pg_catalog.obj_description(p.oid, 'pg_proc') as \"%s\"",
|
||||||
@ -230,31 +249,27 @@ describeFunctions(const char *pattern, bool verbose)
|
|||||||
gettext_noop("Source code"),
|
gettext_noop("Source code"),
|
||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
|
|
||||||
if (!verbose)
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_proc p"
|
"\nFROM pg_catalog.pg_proc p"
|
||||||
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n");
|
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace\n");
|
||||||
else
|
|
||||||
|
if (verbose)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_proc p"
|
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang\n");
|
||||||
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace"
|
|
||||||
"\n LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang"
|
|
||||||
"\n JOIN pg_catalog.pg_roles r ON r.oid = p.proowner\n");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we skip in/out funcs by excluding functions that take or return cstring
|
* we skip in/out funcs by excluding functions that take or return cstring
|
||||||
*/
|
*/
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"WHERE p.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype\n"
|
"WHERE p.prorettype <> 'pg_catalog.cstring'::pg_catalog.regtype\n"
|
||||||
" AND (p.proargtypes[0] IS NULL\n"
|
" AND p.proargtypes[0] IS DISTINCT FROM 'pg_catalog.cstring'::pg_catalog.regtype\n"
|
||||||
" OR p.proargtypes[0] <> 'pg_catalog.cstring'::pg_catalog.regtype)\n"
|
|
||||||
" AND NOT p.proisagg\n");
|
" AND NOT p.proisagg\n");
|
||||||
|
|
||||||
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
||||||
"n.nspname", "p.proname", NULL,
|
"n.nspname", "p.proname", NULL,
|
||||||
"pg_catalog.pg_function_is_visible(p.oid)");
|
"pg_catalog.pg_function_is_visible(p.oid)");
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 3, 4;");
|
appendPQExpBuffer(&buf, "ORDER BY 1, 2, 4;");
|
||||||
|
|
||||||
res = PSQLexec(buf.data, false);
|
res = PSQLexec(buf.data, false);
|
||||||
termPQExpBuffer(&buf);
|
termPQExpBuffer(&buf);
|
||||||
@ -299,7 +314,11 @@ describeTypes(const char *pattern, bool verbose)
|
|||||||
" WHEN t.typlen < 0\n"
|
" WHEN t.typlen < 0\n"
|
||||||
" THEN CAST('var' AS pg_catalog.text)\n"
|
" THEN CAST('var' AS pg_catalog.text)\n"
|
||||||
" ELSE CAST(t.typlen AS pg_catalog.text)\n"
|
" ELSE CAST(t.typlen AS pg_catalog.text)\n"
|
||||||
" END AS \"%s\",\n"
|
" END AS \"%s\",\n",
|
||||||
|
gettext_noop("Internal name"),
|
||||||
|
gettext_noop("Size"));
|
||||||
|
if (verbose && pset.sversion >= 80300)
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
" pg_catalog.array_to_string(\n"
|
" pg_catalog.array_to_string(\n"
|
||||||
" ARRAY(\n"
|
" ARRAY(\n"
|
||||||
" SELECT e.enumlabel\n"
|
" SELECT e.enumlabel\n"
|
||||||
@ -309,8 +328,6 @@ describeTypes(const char *pattern, bool verbose)
|
|||||||
" ),\n"
|
" ),\n"
|
||||||
" E'\\n'\n"
|
" E'\\n'\n"
|
||||||
" ) AS \"%s\",\n",
|
" ) AS \"%s\",\n",
|
||||||
gettext_noop("Internal name"),
|
|
||||||
gettext_noop("Size"),
|
|
||||||
gettext_noop("Elements"));
|
gettext_noop("Elements"));
|
||||||
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
@ -321,13 +338,20 @@ describeTypes(const char *pattern, bool verbose)
|
|||||||
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
|
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do not include array types (start with underscore); do not include
|
* do not include complex types (typrelid!=0) unless they are standalone
|
||||||
* complex types (typrelid!=0) unless they are standalone composite types
|
* composite types
|
||||||
*/
|
*/
|
||||||
appendPQExpBuffer(&buf, "WHERE (t.typrelid = 0 ");
|
appendPQExpBuffer(&buf, "WHERE (t.typrelid = 0 ");
|
||||||
appendPQExpBuffer(&buf, "OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c "
|
appendPQExpBuffer(&buf, "OR (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c "
|
||||||
"WHERE c.oid = t.typrelid)) ");
|
"WHERE c.oid = t.typrelid))\n");
|
||||||
appendPQExpBuffer(&buf, "AND t.typname !~ '^_'\n");
|
/*
|
||||||
|
* do not include array types (before 8.3 we have to use the assumption
|
||||||
|
* that their names start with underscore)
|
||||||
|
*/
|
||||||
|
if (pset.sversion >= 80300)
|
||||||
|
appendPQExpBuffer(&buf, " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid)\n");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, " AND t.typname !~ '^_'\n");
|
||||||
|
|
||||||
/* Match name pattern against either internal or external name */
|
/* Match name pattern against either internal or external name */
|
||||||
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
processSQLNamePattern(pset.db, &buf, pattern, true, false,
|
||||||
@ -419,32 +443,31 @@ listAllDbs(bool verbose)
|
|||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT d.datname as \"%s\",\n"
|
"SELECT d.datname as \"%s\",\n"
|
||||||
" r.rolname as \"%s\",\n"
|
" pg_catalog.pg_get_userbyid(d.datdba) as \"%s\",\n"
|
||||||
" pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n"
|
" pg_catalog.pg_encoding_to_char(d.encoding) as \"%s\",\n"
|
||||||
" d.datacl as \"%s\"",
|
" d.datacl as \"%s\"",
|
||||||
gettext_noop("Name"),
|
gettext_noop("Name"),
|
||||||
gettext_noop("Owner"),
|
gettext_noop("Owner"),
|
||||||
gettext_noop("Encoding"),
|
gettext_noop("Encoding"),
|
||||||
gettext_noop("Access Privileges"));
|
gettext_noop("Access Privileges"));
|
||||||
if (verbose)
|
if (verbose && pset.sversion >= 80200)
|
||||||
{
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
|
",\n CASE WHEN pg_catalog.has_database_privilege(d.datname, 'CONNECT')\n"
|
||||||
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
|
" THEN pg_catalog.pg_size_pretty(pg_catalog.pg_database_size(d.datname))\n"
|
||||||
" ELSE 'No Access'\n"
|
" ELSE 'No Access'\n"
|
||||||
" END as \"%s\"",
|
" END as \"%s\"",
|
||||||
gettext_noop("Size"));
|
gettext_noop("Size"));
|
||||||
|
if (verbose && pset.sversion >= 80000)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n t.spcname as \"%s\"",
|
",\n t.spcname as \"%s\"",
|
||||||
gettext_noop("Tablespace"));
|
gettext_noop("Tablespace"));
|
||||||
|
if (verbose && pset.sversion >= 80200)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
|
",\n pg_catalog.shobj_description(d.oid, 'pg_database') as \"%s\"",
|
||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
}
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_database d"
|
"\nFROM pg_catalog.pg_database d\n");
|
||||||
"\n JOIN pg_catalog.pg_roles r ON d.datdba = r.oid\n");
|
if (verbose && pset.sversion >= 80000)
|
||||||
if (verbose)
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
|
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid\n");
|
||||||
appendPQExpBuffer(&buf, "ORDER BY 1;");
|
appendPQExpBuffer(&buf, "ORDER BY 1;");
|
||||||
@ -484,16 +507,22 @@ permissionsList(const char *pattern)
|
|||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT n.nspname as \"%s\",\n"
|
"SELECT n.nspname as \"%s\",\n"
|
||||||
" c.relname as \"%s\",\n"
|
" c.relname as \"%s\",\n"
|
||||||
" CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'S' THEN '%s' END as \"%s\",\n"
|
" CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'S' THEN '%s' END as \"%s\",\n",
|
||||||
" pg_catalog.array_to_string(c.relacl, E'\\n') as \"%s\"\n"
|
|
||||||
"FROM pg_catalog.pg_class c\n"
|
|
||||||
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
|
|
||||||
"WHERE c.relkind IN ('r', 'v', 'S')\n",
|
|
||||||
gettext_noop("Schema"),
|
gettext_noop("Schema"),
|
||||||
gettext_noop("Name"),
|
gettext_noop("Name"),
|
||||||
gettext_noop("table"), gettext_noop("view"), gettext_noop("sequence"),
|
gettext_noop("table"), gettext_noop("view"), gettext_noop("sequence"),
|
||||||
gettext_noop("Type"),
|
gettext_noop("Type"));
|
||||||
|
|
||||||
|
if (pset.sversion >= 80100)
|
||||||
|
appendPQExpBuffer(&buf, " pg_catalog.array_to_string(c.relacl, E'\\n') as \"%s\"\n",
|
||||||
gettext_noop("Access privileges"));
|
gettext_noop("Access privileges"));
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, " pg_catalog.array_to_string(c.relacl, '\\n') as \"%s\"\n",
|
||||||
|
gettext_noop("Access privileges"));
|
||||||
|
|
||||||
|
appendPQExpBuffer(&buf, "FROM pg_catalog.pg_class c\n"
|
||||||
|
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace\n"
|
||||||
|
"WHERE c.relkind IN ('r', 'v', 'S')\n");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Unless a schema pattern is specified, we suppress system and temp
|
* Unless a schema pattern is specified, we suppress system and temp
|
||||||
@ -694,7 +723,6 @@ objectDescription(const char *pattern)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* describeTableDetails (for \d)
|
* describeTableDetails (for \d)
|
||||||
*
|
*
|
||||||
@ -815,10 +843,10 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
|
|
||||||
/* Get general table info */
|
/* Get general table info */
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules, \n"
|
"SELECT relhasindex, relkind, relchecks, reltriggers, relhasrules, "
|
||||||
"relhasoids %s \n"
|
"relhasoids%s\n"
|
||||||
"FROM pg_catalog.pg_class WHERE oid = '%s'",
|
"FROM pg_catalog.pg_class WHERE oid = '%s'",
|
||||||
pset.sversion >= 80000 ? ", reltablespace" : "",
|
(pset.sversion >= 80000 ? ", reltablespace" : ""),
|
||||||
oid);
|
oid);
|
||||||
res = PSQLexec(buf.data, false);
|
res = PSQLexec(buf.data, false);
|
||||||
if (!res)
|
if (!res)
|
||||||
@ -833,7 +861,6 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
goto error_return;
|
goto error_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: check for null pointers here? */
|
|
||||||
tableinfo.checks = atoi(PQgetvalue(res, 0, 2));
|
tableinfo.checks = atoi(PQgetvalue(res, 0, 2));
|
||||||
tableinfo.triggers = atoi(PQgetvalue(res, 0, 3));
|
tableinfo.triggers = atoi(PQgetvalue(res, 0, 3));
|
||||||
tableinfo.relkind = *(PQgetvalue(res, 0, 1));
|
tableinfo.relkind = *(PQgetvalue(res, 0, 1));
|
||||||
@ -930,7 +957,9 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
{
|
{
|
||||||
PGresult *result;
|
PGresult *result;
|
||||||
|
|
||||||
printfPQExpBuffer(&buf, "SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true)", oid);
|
printfPQExpBuffer(&buf,
|
||||||
|
"SELECT pg_catalog.pg_get_viewdef('%s'::pg_catalog.oid, true)",
|
||||||
|
oid);
|
||||||
result = PSQLexec(buf.data, false);
|
result = PSQLexec(buf.data, false);
|
||||||
if (!result)
|
if (!result)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -984,7 +1013,12 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
PGresult *result;
|
PGresult *result;
|
||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT i.indisunique, i.indisprimary, i.indisclustered, i.indisvalid, a.amname, c2.relname,\n"
|
"SELECT i.indisunique, i.indisprimary, i.indisclustered, ");
|
||||||
|
if (pset.sversion >= 80200)
|
||||||
|
appendPQExpBuffer(&buf, "i.indisvalid, ");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, "true as indisvalid, ");
|
||||||
|
appendPQExpBuffer(&buf, "a.amname, c2.relname,\n"
|
||||||
" pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
|
" pg_catalog.pg_get_expr(i.indpred, i.indrelid, true)\n"
|
||||||
"FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
|
"FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a\n"
|
||||||
"WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
|
"WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid\n"
|
||||||
@ -1033,7 +1067,6 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
printTableAddFooter(&cont, tmpbuf.data);
|
printTableAddFooter(&cont, tmpbuf.data);
|
||||||
add_tablespace_footer(&cont, tableinfo.relkind,
|
add_tablespace_footer(&cont, tableinfo.relkind,
|
||||||
tableinfo.tablespace, true);
|
tableinfo.tablespace, true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PQclear(result);
|
PQclear(result);
|
||||||
@ -1086,9 +1119,16 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
if (tableinfo.hasindex)
|
if (tableinfo.hasindex)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, i.indisvalid, "
|
"SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, ");
|
||||||
"pg_catalog.pg_get_indexdef(i.indexrelid, 0, true), c2.reltablespace\n"
|
if (pset.sversion >= 80200)
|
||||||
"FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
|
appendPQExpBuffer(&buf, "i.indisvalid, ");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf, "true as indisvalid, ");
|
||||||
|
appendPQExpBuffer(&buf, "pg_catalog.pg_get_indexdef(i.indexrelid, 0, true)");
|
||||||
|
if (pset.sversion >= 80000)
|
||||||
|
appendPQExpBuffer(&buf, ", c2.reltablespace");
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
|
"\nFROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i\n"
|
||||||
"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
"WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid\n"
|
||||||
"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
|
"ORDER BY i.indisprimary DESC, i.indisunique DESC, c2.relname",
|
||||||
oid);
|
oid);
|
||||||
@ -1134,6 +1174,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
printTableAddFooter(&cont, buf.data);
|
printTableAddFooter(&cont, buf.data);
|
||||||
|
|
||||||
/* Print tablespace of the index on the same line */
|
/* Print tablespace of the index on the same line */
|
||||||
|
if (pset.sversion >= 80000)
|
||||||
add_tablespace_footer(&cont, 'i',
|
add_tablespace_footer(&cont, 'i',
|
||||||
atooid(PQgetvalue(result, i, 6)),
|
atooid(PQgetvalue(result, i, 6)),
|
||||||
false);
|
false);
|
||||||
@ -1149,7 +1190,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
"SELECT r.conname, "
|
"SELECT r.conname, "
|
||||||
"pg_catalog.pg_get_constraintdef(r.oid, true)\n"
|
"pg_catalog.pg_get_constraintdef(r.oid, true)\n"
|
||||||
"FROM pg_catalog.pg_constraint r\n"
|
"FROM pg_catalog.pg_constraint r\n"
|
||||||
"WHERE r.conrelid = '%s' AND r.contype = 'c' ORDER BY 1",
|
"WHERE r.conrelid = '%s' AND r.contype = 'c'\nORDER BY 1",
|
||||||
oid);
|
oid);
|
||||||
result = PSQLexec(buf.data, false);
|
result = PSQLexec(buf.data, false);
|
||||||
if (!result)
|
if (!result)
|
||||||
@ -1178,7 +1219,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT conname,\n"
|
"SELECT conname,\n"
|
||||||
" pg_catalog.pg_get_constraintdef(oid, true) as condef\n"
|
" pg_catalog.pg_get_constraintdef(r.oid, true) as condef\n"
|
||||||
"FROM pg_catalog.pg_constraint r\n"
|
"FROM pg_catalog.pg_constraint r\n"
|
||||||
"WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1",
|
"WHERE r.conrelid = '%s' AND r.contype = 'f' ORDER BY 1",
|
||||||
oid);
|
oid);
|
||||||
@ -1209,7 +1250,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT conname, conrelid::pg_catalog.regclass,\n"
|
"SELECT conname, conrelid::pg_catalog.regclass,\n"
|
||||||
" pg_catalog.pg_get_constraintdef(oid, true) as condef\n"
|
" pg_catalog.pg_get_constraintdef(c.oid, true) as condef\n"
|
||||||
"FROM pg_catalog.pg_constraint c\n"
|
"FROM pg_catalog.pg_constraint c\n"
|
||||||
"WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1",
|
"WHERE c.confrelid = '%s' AND c.contype = 'f' ORDER BY 1",
|
||||||
oid);
|
oid);
|
||||||
@ -1240,11 +1281,11 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
/* print rules */
|
/* print rules */
|
||||||
if (tableinfo.hasrules)
|
if (tableinfo.hasrules)
|
||||||
{
|
{
|
||||||
if (pset.sversion < 80300)
|
if (pset.sversion >= 80300)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
|
"SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
|
||||||
"'O'::char AS ev_enabled\n"
|
"ev_enabled\n"
|
||||||
"FROM pg_catalog.pg_rewrite r\n"
|
"FROM pg_catalog.pg_rewrite r\n"
|
||||||
"WHERE r.ev_class = '%s' ORDER BY 1",
|
"WHERE r.ev_class = '%s' ORDER BY 1",
|
||||||
oid);
|
oid);
|
||||||
@ -1253,7 +1294,7 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
|
"SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
|
||||||
"ev_enabled\n"
|
"'O'::char AS ev_enabled\n"
|
||||||
"FROM pg_catalog.pg_rewrite r\n"
|
"FROM pg_catalog.pg_rewrite r\n"
|
||||||
"WHERE r.ev_class = '%s' ORDER BY 1",
|
"WHERE r.ev_class = '%s' ORDER BY 1",
|
||||||
oid);
|
oid);
|
||||||
@ -1336,13 +1377,23 @@ describeOneTableDetails(const char *schemaname,
|
|||||||
if (tableinfo.triggers)
|
if (tableinfo.triggers)
|
||||||
{
|
{
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT t.tgname, pg_catalog.pg_get_triggerdef(t.oid), "
|
"SELECT t.tgname, "
|
||||||
|
"pg_catalog.pg_get_triggerdef(t.oid), "
|
||||||
"t.tgenabled\n"
|
"t.tgenabled\n"
|
||||||
"FROM pg_catalog.pg_trigger t\n"
|
"FROM pg_catalog.pg_trigger t\n"
|
||||||
"WHERE t.tgrelid = '%s' "
|
"WHERE t.tgrelid = '%s' AND ",
|
||||||
"AND t.tgconstraint = 0\n"
|
|
||||||
"ORDER BY 1",
|
|
||||||
oid);
|
oid);
|
||||||
|
if (pset.sversion >= 80300)
|
||||||
|
appendPQExpBuffer(&buf, "t.tgconstraint = 0");
|
||||||
|
else
|
||||||
|
appendPQExpBuffer(&buf,
|
||||||
|
"(NOT tgisconstraint "
|
||||||
|
" OR NOT EXISTS"
|
||||||
|
" (SELECT 1 FROM pg_catalog.pg_depend d "
|
||||||
|
" JOIN pg_catalog.pg_constraint c ON (d.refclassid = c.tableoid AND d.refobjid = c.oid) "
|
||||||
|
" WHERE d.classid = t.tableoid AND d.objid = t.oid AND d.deptype = 'i' AND c.contype = 'f'))");
|
||||||
|
appendPQExpBuffer(&buf, "\nORDER BY 1");
|
||||||
|
|
||||||
result = PSQLexec(buf.data, false);
|
result = PSQLexec(buf.data, false);
|
||||||
if (!result)
|
if (!result)
|
||||||
goto error_return;
|
goto error_return;
|
||||||
@ -1511,7 +1562,8 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* We ignore the database default tablespace so that users not using
|
* We ignore the database default tablespace so that users not using
|
||||||
* tablespaces don't need to know about them.
|
* tablespaces don't need to know about them. This case also covers
|
||||||
|
* pre-8.0 servers, for which tablespace will always be 0.
|
||||||
*/
|
*/
|
||||||
if (tablespace != 0)
|
if (tablespace != 0)
|
||||||
{
|
{
|
||||||
@ -1519,8 +1571,9 @@ add_tablespace_footer(printTableContent *const cont, char relkind,
|
|||||||
PQExpBufferData buf;
|
PQExpBufferData buf;
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
printfPQExpBuffer(&buf, "SELECT spcname FROM pg_tablespace \n"
|
printfPQExpBuffer(&buf,
|
||||||
"WHERE oid = '%u';", tablespace);
|
"SELECT spcname FROM pg_catalog.pg_tablespace\n"
|
||||||
|
"WHERE oid = '%u'", tablespace);
|
||||||
result = PSQLexec(buf.data, false);
|
result = PSQLexec(buf.data, false);
|
||||||
if (!result)
|
if (!result)
|
||||||
return;
|
return;
|
||||||
@ -1572,7 +1625,9 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
appendPQExpBufferStr(&buf,
|
if (pset.sversion >= 80100)
|
||||||
|
{
|
||||||
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
|
"SELECT r.rolname, r.rolsuper, r.rolinherit,\n"
|
||||||
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
|
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin,\n"
|
||||||
" r.rolconnlimit,\n"
|
" r.rolconnlimit,\n"
|
||||||
@ -1581,16 +1636,31 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
|
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)\n"
|
||||||
" WHERE m.member = r.oid) as memberof");
|
" WHERE m.member = r.oid) as memberof");
|
||||||
|
|
||||||
if (verbose)
|
if (verbose && pset.sversion >= 80200)
|
||||||
{
|
{
|
||||||
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
|
appendPQExpBufferStr(&buf, "\n, pg_catalog.shobj_description(r.oid, 'pg_authid') AS description");
|
||||||
ncols++;
|
ncols++;
|
||||||
}
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, "\nFROM pg_catalog.pg_roles r\n");
|
appendPQExpBufferStr(&buf, "\nFROM pg_catalog.pg_roles r\n");
|
||||||
|
|
||||||
processSQLNamePattern(pset.db, &buf, pattern, false, false,
|
processSQLNamePattern(pset.db, &buf, pattern, false, false,
|
||||||
NULL, "r.rolname", NULL, NULL);
|
NULL, "r.rolname", NULL, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printfPQExpBuffer(&buf,
|
||||||
|
"SELECT u.usename AS rolname,\n"
|
||||||
|
" u.usesuper AS rolsuper,\n"
|
||||||
|
" true AS rolinherit, false AS rolcreaterole,\n"
|
||||||
|
" u.usecreatedb AS rolcreatedb, true AS rolcanlogin,\n"
|
||||||
|
" -1 AS rolconnlimit,\n"
|
||||||
|
" ARRAY(SELECT g.groname FROM pg_catalog.pg_group g WHERE u.usesysid = ANY(g.grolist)) as memberof"
|
||||||
|
"\nFROM pg_catalog.pg_user u\n");
|
||||||
|
|
||||||
|
processSQLNamePattern(pset.db, &buf, pattern, false, false,
|
||||||
|
NULL, "u.usename", NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
appendPQExpBuffer(&buf, "ORDER BY 1;");
|
appendPQExpBuffer(&buf, "ORDER BY 1;");
|
||||||
|
|
||||||
@ -1607,7 +1677,7 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
|
printTableAddHeader(&cont, gettext_noop("Attributes"), true, align);
|
||||||
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
|
printTableAddHeader(&cont, gettext_noop("Member of"), true, align);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose && pset.sversion >= 80200)
|
||||||
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
|
printTableAddHeader(&cont, gettext_noop("Description"), true, align);
|
||||||
|
|
||||||
for (i = 0; i < nrows; i++)
|
for (i = 0; i < nrows; i++)
|
||||||
@ -1650,7 +1720,7 @@ describeRoles(const char *pattern, bool verbose)
|
|||||||
|
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 7), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 7), false);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose && pset.sversion >= 80200)
|
||||||
printTableAddCell(&cont, PQgetvalue(res, i, 8), false);
|
printTableAddCell(&cont, PQgetvalue(res, i, 8), false);
|
||||||
}
|
}
|
||||||
termPQExpBuffer(&buf);
|
termPQExpBuffer(&buf);
|
||||||
@ -1716,10 +1786,14 @@ listTables(const char *tabtypes, const char *pattern, bool verbose)
|
|||||||
"SELECT n.nspname as \"%s\",\n"
|
"SELECT n.nspname as \"%s\",\n"
|
||||||
" c.relname as \"%s\",\n"
|
" c.relname as \"%s\",\n"
|
||||||
" CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' WHEN 's' THEN '%s' END as \"%s\",\n"
|
" CASE c.relkind WHEN 'r' THEN '%s' WHEN 'v' THEN '%s' WHEN 'i' THEN '%s' WHEN 'S' THEN '%s' WHEN 's' THEN '%s' END as \"%s\",\n"
|
||||||
" r.rolname as \"%s\"",
|
" pg_catalog.pg_get_userbyid(c.relowner) as \"%s\"",
|
||||||
gettext_noop("Schema"),
|
gettext_noop("Schema"),
|
||||||
gettext_noop("Name"),
|
gettext_noop("Name"),
|
||||||
gettext_noop("table"), gettext_noop("view"), gettext_noop("index"), gettext_noop("sequence"), gettext_noop("special"),
|
gettext_noop("table"),
|
||||||
|
gettext_noop("view"),
|
||||||
|
gettext_noop("index"),
|
||||||
|
gettext_noop("sequence"),
|
||||||
|
gettext_noop("special"),
|
||||||
gettext_noop("Type"),
|
gettext_noop("Type"),
|
||||||
gettext_noop("Owner"));
|
gettext_noop("Owner"));
|
||||||
|
|
||||||
@ -1728,19 +1802,17 @@ listTables(const char *tabtypes, const char *pattern, bool verbose)
|
|||||||
",\n c2.relname as \"%s\"",
|
",\n c2.relname as \"%s\"",
|
||||||
gettext_noop("Table"));
|
gettext_noop("Table"));
|
||||||
|
|
||||||
if (verbose)
|
if (verbose && pset.sversion >= 80100)
|
||||||
{
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \"%s\"",
|
",\n pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \"%s\"",
|
||||||
gettext_noop("Size"));
|
gettext_noop("Size"));
|
||||||
|
if (verbose)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
|
",\n pg_catalog.obj_description(c.oid, 'pg_class') as \"%s\"",
|
||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
}
|
|
||||||
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_class c"
|
"\nFROM pg_catalog.pg_class c"
|
||||||
"\n JOIN pg_catalog.pg_roles r ON r.oid = c.relowner"
|
|
||||||
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
|
"\n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace");
|
||||||
if (showIndexes)
|
if (showIndexes)
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
@ -1985,7 +2057,7 @@ listSchemas(const char *pattern, bool verbose)
|
|||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
"SELECT n.nspname AS \"%s\",\n"
|
"SELECT n.nspname AS \"%s\",\n"
|
||||||
" r.rolname AS \"%s\"",
|
" pg_catalog.pg_get_userbyid(n.nspowner) AS \"%s\"",
|
||||||
gettext_noop("Name"),
|
gettext_noop("Name"),
|
||||||
gettext_noop("Owner"));
|
gettext_noop("Owner"));
|
||||||
|
|
||||||
@ -1997,8 +2069,7 @@ listSchemas(const char *pattern, bool verbose)
|
|||||||
gettext_noop("Description"));
|
gettext_noop("Description"));
|
||||||
|
|
||||||
appendPQExpBuffer(&buf,
|
appendPQExpBuffer(&buf,
|
||||||
"\nFROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_roles r\n"
|
"\nFROM pg_catalog.pg_namespace n\n"
|
||||||
" ON n.nspowner=r.oid\n"
|
|
||||||
"WHERE (n.nspname !~ '^pg_temp_' OR\n"
|
"WHERE (n.nspname !~ '^pg_temp_' OR\n"
|
||||||
" n.nspname = (pg_catalog.current_schemas(true))[1])\n"); /* temp schema is first */
|
" n.nspname = (pg_catalog.current_schemas(true))[1])\n"); /* temp schema is first */
|
||||||
|
|
||||||
@ -2035,6 +2106,13 @@ listTSParsers(const char *pattern, bool verbose)
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
printQueryOpt myopt = pset.popt;
|
printQueryOpt myopt = pset.popt;
|
||||||
|
|
||||||
|
if (pset.sversion < 80300)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
|
||||||
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
return listTSParsersVerbose(pattern);
|
return listTSParsersVerbose(pattern);
|
||||||
|
|
||||||
@ -2261,6 +2339,13 @@ listTSDictionaries(const char *pattern, bool verbose)
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
printQueryOpt myopt = pset.popt;
|
printQueryOpt myopt = pset.popt;
|
||||||
|
|
||||||
|
if (pset.sversion < 80300)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
|
||||||
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
printfPQExpBuffer(&buf,
|
printfPQExpBuffer(&buf,
|
||||||
@ -2322,6 +2407,13 @@ listTSTemplates(const char *pattern, bool verbose)
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
printQueryOpt myopt = pset.popt;
|
printQueryOpt myopt = pset.popt;
|
||||||
|
|
||||||
|
if (pset.sversion < 80300)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
|
||||||
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
initPQExpBuffer(&buf);
|
initPQExpBuffer(&buf);
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
@ -2383,6 +2475,13 @@ listTSConfigs(const char *pattern, bool verbose)
|
|||||||
PGresult *res;
|
PGresult *res;
|
||||||
printQueryOpt myopt = pset.popt;
|
printQueryOpt myopt = pset.popt;
|
||||||
|
|
||||||
|
if (pset.sversion < 80300)
|
||||||
|
{
|
||||||
|
fprintf(stderr, _("The server (version %d.%d) does not support full text search.\n"),
|
||||||
|
pset.sversion / 10000, (pset.sversion / 100) % 100);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (verbose)
|
if (verbose)
|
||||||
return listTSConfigsVerbose(pattern);
|
return listTSConfigsVerbose(pattern);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user