Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
0a8f6b79
Commit
0a8f6b79
authored
Jul 03, 2008
by
Tom Lane
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
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.
parent
2c2aff6a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
227 additions
and
132 deletions
+227
-132
doc/src/sgml/ref/psql-ref.sgml
doc/src/sgml/ref/psql-ref.sgml
+21
-25
src/bin/psql/describe.c
src/bin/psql/describe.c
+206
-107
No files found.
doc/src/sgml/ref/psql-ref.sgml
View file @
0a8f6b79
<!--
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.20
8 2008/06/11 10:48:16 heikki
Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.20
9 2008/07/03 03:37:16 tgl
Exp $
PostgreSQL documentation
PostgreSQL documentation
-->
-->
...
@@ -407,7 +407,7 @@ PostgreSQL documentation
...
@@ -407,7 +407,7 @@ PostgreSQL documentation
<listitem>
<listitem>
<para>
<para>
Force <application>psql</application> to prompt for a
Force <application>psql</application> to prompt for a
password before connecting to a database.
password before connecting to a database.
</para>
</para>
<para>
<para>
...
@@ -459,7 +459,7 @@ PostgreSQL documentation
...
@@ -459,7 +459,7 @@ PostgreSQL documentation
<option>-f</> option, adding this option wraps
<option>-f</> option, adding this option wraps
<command>BEGIN</>/<command>COMMIT</> around the script to execute it
<command>BEGIN</>/<command>COMMIT</> around the script to execute it
as a single transaction. This ensures that either all the commands
as a single transaction. This ensures that either all the commands
complete successfully, or no changes are applied.
complete successfully, or no changes are applied.
</para>
</para>
<para>
<para>
...
@@ -542,8 +542,8 @@ PostgreSQL documentation
...
@@ -542,8 +542,8 @@ PostgreSQL documentation
<para>
<para>
An alternative way to specify connection parameters is in a
An alternative way to specify connection parameters is in a
<parameter>conninfo</parameter> string, which is used instead of a
<parameter>conninfo</parameter> string, which is used instead of a
database name. This mechanism give you very wide control over the
database name. This mechanism give you very wide control over the
connection. For example:
connection. For example:
<programlisting>
<programlisting>
$ <userinput>psql "service=myservice sslmode=require"</userinput>
$ <userinput>psql "service=myservice sslmode=require"</userinput>
...
@@ -873,7 +873,7 @@ testdb=>
...
@@ -873,7 +873,7 @@ testdb=>
Lists all available tablespaces. If <replaceable
Lists all available tablespaces. If <replaceable
class="parameter">pattern</replaceable>
class="parameter">pattern</replaceable>
is specified, only tablespaces whose names match the pattern are shown.
is specified, only tablespaces whose names match the pattern are shown.
If <literal>+</literal> is appended to the command name, each object
If <literal>+</literal> is appended to the command name, each object
is listed with its associated permissions.
is listed with its associated permissions.
</para>
</para>
</listitem>
</listitem>
...
@@ -1511,7 +1511,7 @@ lo_import 152801
...
@@ -1511,7 +1511,7 @@ lo_import 152801
<listitem>
<listitem>
<para>
<para>
Sets the output format to one of <literal>unaligned</literal>,
Sets the output format to one of <literal>unaligned</literal>,
<literal>aligned</literal>, <literal>wrapped</literal>,
<literal>aligned</literal>, <literal>wrapped</literal>,
<literal>html</literal>,
<literal>html</literal>,
<literal>latex</literal>, or <literal>troff-ms</literal>.
<literal>latex</literal>, or <literal>troff-ms</literal>.
Unique abbreviations are allowed. (That would mean one letter
Unique abbreviations are allowed. (That would mean one letter
...
@@ -2533,7 +2533,7 @@ testdb=> <userinput>\set content '''' `sed -e "s/'/''/g" -e 's/\\/\\\\/g' <
...
@@ -2533,7 +2533,7 @@ testdb=> <userinput>\set content '''' `sed -e "s/'/''/g" -e 's/\\/\\\\/g' <
The full host name (with domain name) of the database server,
The full host name (with domain name) of the database server,
or <literal>[local]</literal> if the connection is over a Unix
or <literal>[local]</literal> if the connection is over a Unix
domain socket, or
domain socket, or
<literal>[local:<replaceable>/dir/name</replaceable>]</literal>,
<literal>[local:<replaceable>/dir/name</replaceable>]</literal>,
if the Unix domain socket is not at the compiled in default
if the Unix domain socket is not at the compiled in default
location.
location.
</para>
</para>
...
@@ -2857,28 +2857,24 @@ $endif
...
@@ -2857,28 +2857,24 @@ $endif
<itemizedlist>
<itemizedlist>
<listitem>
<listitem>
<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>
...
...
src/bin/psql/describe.c
View file @
0a8f6b79
/*
/*
* 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.17
3 2008/05/13 00:23:17 alvherre
Exp $
* $PostgreSQL: pgsql/src/bin/psql/describe.c,v 1.17
4 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,
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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
\"
"
,
",
\n
pg_catalog.shobj_description(oid, 'pg_tablespace') AS
\"
%s
\"
"
,
gettext_noop
(
"Access privileges"
));
gettext_noop
(
"Access privileges"
),
if
(
verbose
&&
pset
.
sversion
>=
80200
)
appendPQExpBuffer
(
&
buf
,
",
\n
pg_catalog.shobj_description(oid, 'pg_tablespace') AS
\"
%s
\"
"
,
gettext_noop
(
"Description"
));
gettext_noop
(
"Description"
));
appendPQExpBuffer
(
&
buf
,
appendPQExpBuffer
(
&
buf
,
...
@@ -179,7 +191,13 @@ describeFunctions(const char *pattern, bool verbose)
...
@@ -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,10 +226,11 @@ describeFunctions(const char *pattern, bool verbose)
...
@@ -208,10 +226,11 @@ 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
(
"Name"
),
gettext_noop
(
"Result data type"
),
gettext_noop
(
"Argument data types"
));
gettext_noop
(
"Argument data types"
));
else
appendPQExpBuffer
(
&
buf
,
" pg_catalog.oidvectortypes(p.proargtypes) as
\"
%s
\"
"
,
gettext_noop
(
"Argument data types"
));
if
(
verbose
)
if
(
verbose
)
appendPQExpBuffer
(
&
buf
,
appendPQExpBuffer
(
&
buf
,
...
@@ -220,7 +239,7 @@ describeFunctions(const char *pattern, bool 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)
...
@@ -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
,
"
\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
"
);
"
\n
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
\n
"
);
else
if
(
verbose
)
appendPQExpBuffer
(
&
buf
,
appendPQExpBuffer
(
&
buf
,
"
\n
FROM 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,9 +314,13 @@ describeTypes(const char *pattern, bool verbose)
...
@@ -299,9 +314,13 @@ 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
"
" FROM pg_catalog.pg_enum e
\n
"
" FROM pg_catalog.pg_enum e
\n
"
" WHERE e.enumtypid = t.oid
\n
"
" WHERE e.enumtypid = t.oid
\n
"
...
@@ -309,10 +328,8 @@ describeTypes(const char *pattern, bool verbose)
...
@@ -309,10 +328,8 @@ 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
,
" pg_catalog.obj_description(t.oid, 'pg_type') as
\"
%s
\"\n
"
,
" pg_catalog.obj_description(t.oid, 'pg_type') as
\"
%s
\"\n
"
,
gettext_noop
(
"Description"
));
gettext_noop
(
"Description"
));
...
@@ -321,13 +338,20 @@ describeTypes(const char *pattern, bool verbose)
...
@@ -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 includ
e
* do not include
complex types (typrelid!=0) unless they are standalon
e
* comp
lex types (typrelid!=0) unless they are standalone comp
osite 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)
...
@@ -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"
));
appendPQExpBuffer
(
&
buf
,
if
(
verbose
&&
pset
.
sversion
>=
80200
)
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
,
"
\n
FROM pg_catalog.pg_database d"
"
\n
FROM 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,17 +507,23 @@ permissionsList(const char *pattern)
...
@@ -484,17 +507,23 @@ 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"
));
else
appendPQExpBuffer
(
&
buf
,
" pg_catalog.array_to_string(c.relacl, '
\\
n') as
\"
%s
\"\n
"
,
gettext_noop
(
"Access privileges"
));
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
* tables, since they normally aren't very interesting from a permissions
* tables, since they normally aren't very interesting from a permissions
...
@@ -694,7 +723,6 @@ objectDescription(const char *pattern)
...
@@ -694,7 +723,6 @@ objectDescription(const char *pattern)
}
}
/*
/*
* describeTableDetails (for \d)
* describeTableDetails (for \d)
*
*
...
@@ -815,10 +843,10 @@ describeOneTableDetails(const char *schemaname,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
,
"
\n
FROM 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,9 +1174,10 @@ describeOneTableDetails(const char *schemaname,
...
@@ -1134,9 +1174,10 @@ 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 */
add_tablespace_footer
(
&
cont
,
'i'
,
if
(
pset
.
sversion
>=
80000
)
atooid
(
PQgetvalue
(
result
,
i
,
6
)),
add_tablespace_footer
(
&
cont
,
'i'
,
false
);
atooid
(
PQgetvalue
(
result
,
i
,
6
)),
false
);
}
}
}
}
PQclear
(
result
);
PQclear
(
result
);
...
@@ -1149,7 +1190,7 @@ describeOneTableDetails(const char *schemaname,
...
@@ -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'
\n
ORDER 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,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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,
...
@@ -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
,
"
\n
ORDER 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,
...
@@ -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,
...
@@ -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)
...
@@ -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)
...
@@ -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
,
"
\n
FROM pg_catalog.pg_roles r
\n
"
);
processSQLNamePattern
(
pset
.
db
,
&
buf
,
pattern
,
false
,
false
,
appendPQExpBufferStr
(
&
buf
,
"
\n
FROM pg_catalog.pg_roles r
\n
"
);
NULL
,
"r.rolname"
,
NULL
,
NULL
);
processSQLNamePattern
(
pset
.
db
,
&
buf
,
pattern
,
false
,
false
,
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"
"
\n
FROM 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)
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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
,
"
\n
FROM pg_catalog.pg_class c"
"
\n
FROM 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)
...
@@ -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)
...
@@ -1997,8 +2069,7 @@ listSchemas(const char *pattern, bool verbose)
gettext_noop
(
"Description"
));
gettext_noop
(
"Description"
));
appendPQExpBuffer
(
&
buf
,
appendPQExpBuffer
(
&
buf
,
"
\n
FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_roles r
\n
"
"
\n
FROM 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)
...
@@ -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)
...
@@ -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)
...
@@ -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)
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment