2000-01-19 00:30:24 +01:00
/*
* psql - the PostgreSQL interactive terminal
*
2008-07-03 05:37:17 +02:00
* 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 .
*
2019-01-02 18:44:25 +01:00
* Copyright ( c ) 2000 - 2019 , PostgreSQL Global Development Group
2000-01-19 00:30:24 +01:00
*
2010-09-20 22:08:53 +02:00
* src / bin / psql / describe . c
2000-01-19 00:30:24 +01:00
*/
2001-02-10 03:31:31 +01:00
# include "postgres_fe.h"
1999-11-04 22:56:02 +01:00
2008-05-13 00:59:58 +02:00
# include <ctype.h>
1999-11-04 22:56:02 +01:00
2018-04-08 19:59:52 +02:00
# include "catalog/pg_attribute_d.h"
2018-08-31 22:45:33 +02:00
# include "catalog/pg_cast_d.h"
2018-04-08 19:59:52 +02:00
# include "catalog/pg_class_d.h"
# include "catalog/pg_default_acl_d.h"
2019-10-23 06:08:53 +02:00
# include "common.h"
2019-05-14 20:19:49 +02:00
# include "common/logging.h"
2019-10-23 06:08:53 +02:00
# include "describe.h"
2019-05-14 20:19:49 +02:00
# include "fe_utils/mbprint.h"
# include "fe_utils/print.h"
2016-03-24 20:55:44 +01:00
# include "fe_utils/string_utils.h"
2008-05-13 00:59:58 +02:00
# include "settings.h"
1999-11-04 22:56:02 +01:00
# include "variables.h"
2002-08-10 05:56:24 +02:00
static bool describeOneTableDetails ( const char * schemaname ,
2019-05-22 19:04:48 +02:00
const char * relationname ,
const char * oid ,
bool verbose ) ;
2008-05-13 00:59:58 +02:00
static void add_tablespace_footer ( printTableContent * const cont , char relkind ,
2019-05-22 19:04:48 +02:00
Oid tablespace , const bool newline ) ;
2008-05-13 02:23:17 +02:00
static void add_role_attribute ( PQExpBuffer buf , const char * const str ) ;
2007-08-21 03:11:32 +02:00
static bool listTSParsersVerbose ( const char * pattern ) ;
static bool describeOneTSParser ( const char * oid , const char * nspname ,
2019-05-22 19:04:48 +02:00
const char * prsname ) ;
2007-08-21 03:11:32 +02:00
static bool listTSConfigsVerbose ( const char * pattern ) ;
static bool describeOneTSConfig ( const char * oid , const char * nspname ,
2019-05-22 19:04:48 +02:00
const char * cfgname ,
const char * pnspname , const char * prsname ) ;
2008-12-31 19:07:47 +01:00
static void printACLColumn ( PQExpBuffer buf , const char * colname ) ;
2011-02-08 22:08:41 +01:00
static bool listOneExtensionContents ( const char * extname , const char * oid ) ;
2007-08-21 03:11:32 +02:00
2004-07-12 22:41:13 +02:00
1999-11-04 22:56:02 +01:00
/*----------------
* Handlers for various slash commands displaying some sort of list
* of things in the database .
*
2008-07-03 05:37:17 +02:00
* Note : try to format the queries to look nice in - E output .
1999-11-04 22:56:02 +01:00
* - - - - - - - - - - - - - - - -
*/
2017-07-27 17:57:29 +02:00
/*
* \ da
2002-08-10 05:56:24 +02:00
* Takes an optional regexp to select particular aggregates
1999-11-04 22:56:02 +01:00
*/
bool
2009-01-06 22:10:30 +01:00
describeAggregates ( const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT n.nspname as \" %s \" , \n "
" p.proname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(p.prorettype, NULL) AS \" %s \" , \n " ,
2008-07-03 05:37:17 +02:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Result data type " ) ) ;
Allow aggregate functions to be VARIADIC.
There's no inherent reason why an aggregate function can't be variadic
(even VARIADIC ANY) if its transition function can handle the case.
Indeed, this patch to add the feature touches none of the planner or
executor, and little of the parser; the main missing stuff was DDL and
pg_dump support.
It is true that variadic aggregates can create the same sort of ambiguity
about parameters versus ORDER BY keys that was complained of when we
(briefly) had both one- and two-argument forms of string_agg(). However,
the policy formed in response to that discussion only said that we'd not
create any built-in aggregates with varying numbers of arguments, not that
we shouldn't allow users to do it. So the logical extension of that is
we can allow users to make variadic aggregates as long as we're wary about
shipping any such in core.
In passing, this patch allows aggregate function arguments to be named, to
the extent of remembering the names in pg_proc and dumping them in pg_dump.
You can't yet call an aggregate using named-parameter notation. That seems
like a likely future extension, but it'll take some work, and it's not what
this patch is really about. Likewise, there's still some work needed to
make window functions handle VARIADIC fully, but I left that for another
day.
initdb forced because of new aggvariadic field in Aggref parse nodes.
2013-09-03 23:08:38 +02:00
if ( pset . sversion > = 80400 )
appendPQExpBuffer ( & buf ,
" CASE WHEN p.pronargs = 0 \n "
" THEN CAST('*' AS pg_catalog.text) \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" ELSE pg_catalog.pg_get_function_arguments(p.oid) \n "
Allow aggregate functions to be VARIADIC.
There's no inherent reason why an aggregate function can't be variadic
(even VARIADIC ANY) if its transition function can handle the case.
Indeed, this patch to add the feature touches none of the planner or
executor, and little of the parser; the main missing stuff was DDL and
pg_dump support.
It is true that variadic aggregates can create the same sort of ambiguity
about parameters versus ORDER BY keys that was complained of when we
(briefly) had both one- and two-argument forms of string_agg(). However,
the policy formed in response to that discussion only said that we'd not
create any built-in aggregates with varying numbers of arguments, not that
we shouldn't allow users to do it. So the logical extension of that is
we can allow users to make variadic aggregates as long as we're wary about
shipping any such in core.
In passing, this patch allows aggregate function arguments to be named, to
the extent of remembering the names in pg_proc and dumping them in pg_dump.
You can't yet call an aggregate using named-parameter notation. That seems
like a likely future extension, but it'll take some work, and it's not what
this patch is really about. Likewise, there's still some work needed to
make window functions handle VARIADIC fully, but I left that for another
day.
initdb forced because of new aggvariadic field in Aggref parse nodes.
2013-09-03 23:08:38 +02:00
" END AS \" %s \" , \n " ,
gettext_noop ( " Argument data types " ) ) ;
else if ( pset . sversion > = 80200 )
2009-06-11 16:49:15 +02:00
appendPQExpBuffer ( & buf ,
" CASE WHEN p.pronargs = 0 \n "
" THEN CAST('*' AS pg_catalog.text) \n "
" ELSE \n "
" pg_catalog.array_to_string(ARRAY( \n "
" SELECT \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(p.proargtypes[s.i], NULL) \n "
2009-06-11 16:49:15 +02:00
" FROM \n "
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i) \n "
" ), ', ') \n "
" END AS \" %s \" , \n " ,
gettext_noop ( " Argument data types " ) ) ;
2008-07-03 05:37:17 +02:00
else
2009-06-11 16:49:15 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(p.proargtypes[0], NULL) AS \" %s \" , \n " ,
2009-06-11 16:49:15 +02:00
gettext_noop ( " Argument data types " ) ) ;
2008-07-03 05:37:17 +02:00
2018-03-02 14:57:38 +01:00
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 = 'a' \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 " ) ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
2014-05-06 18:12:18 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " p.proname " , NULL ,
" pg_catalog.pg_function_is_visible(p.oid) " ) ;
1999-11-05 00:14:30 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2, 4; " ) ;
1999-11-05 00:14:30 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of aggregate functions " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
1999-11-05 00:14:30 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
2017-07-27 17:57:29 +02:00
/*
* \ dA
2016-06-07 23:59:34 +02:00
* Takes an optional regexp to select particular access methods
*/
bool
describeAccessMethods ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2016-06-08 00:03:31 +02:00
static const bool translate_columns [ ] = { false , true , false , false } ;
2016-06-07 23:59:34 +02:00
if ( pset . sversion < 90600 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support access methods. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2016-06-07 23:59:34 +02:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT amname AS \" %s \" , \n "
" CASE amtype "
" WHEN 'i' THEN '%s' "
2019-03-29 16:59:40 +01:00
" WHEN 't' THEN '%s' "
2016-06-07 23:59:34 +02:00
" END AS \" %s \" " ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Index " ) ,
2019-03-29 16:59:40 +01:00
gettext_noop ( " Table " ) ,
2016-06-07 23:59:34 +02:00
gettext_noop ( " Type " ) ) ;
if ( verbose )
{
appendPQExpBuffer ( & buf ,
" , \n amhandler AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(oid, 'pg_am') AS \" %s \" " ,
2016-06-07 23:59:34 +02:00
gettext_noop ( " Handler " ) ,
gettext_noop ( " Description " ) ) ;
}
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_am \n " ) ;
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " amname " , NULL ,
NULL ) ;
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
res = PSQLexec ( buf . data ) ;
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of access methods " ) ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
myopt . n_translate_columns = lengthof ( translate_columns ) ;
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
PQclear ( res ) ;
return true ;
}
2017-07-27 17:57:29 +02:00
/*
* \ db
2004-06-18 08:14:31 +02:00
* Takes an optional regexp to select particular tablespaces
*/
bool
2004-07-15 05:56:06 +02:00
describeTablespaces ( const char * pattern , bool verbose )
2004-06-18 08:14:31 +02:00
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2004-11-05 20:17:13 +01:00
if ( pset . sversion < 80000 )
2004-08-29 07:07:03 +02:00
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_info ( " The server (version %s) does not support tablespaces. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2004-08-29 07:07:03 +02:00
return true ;
2004-08-20 22:18:23 +02:00
}
2004-06-18 08:14:31 +02:00
initPQExpBuffer ( & buf ) ;
2011-12-07 10:35:00 +01:00
if ( pset . sversion > = 90200 )
printfPQExpBuffer ( & buf ,
" SELECT spcname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(spcowner) AS \" %s \" , \n "
" pg_catalog.pg_tablespace_location(oid) AS \" %s \" " ,
2011-12-07 10:35:00 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ,
gettext_noop ( " Location " ) ) ;
else
printfPQExpBuffer ( & buf ,
" SELECT spcname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(spcowner) AS \" %s \" , \n "
2011-12-07 10:35:00 +01:00
" spclocation AS \" %s \" " ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ,
gettext_noop ( " Location " ) ) ;
2004-06-18 08:14:31 +02:00
2004-07-15 05:56:06 +02:00
if ( verbose )
2008-12-31 19:07:47 +01:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " spcacl " ) ;
}
2014-01-26 18:11:15 +01:00
if ( verbose & & pset . sversion > = 90000 )
appendPQExpBuffer ( & buf ,
" , \n spcoptions AS \" %s \" " ,
gettext_noop ( " Options " ) ) ;
2014-07-15 00:04:52 +02:00
if ( verbose & & pset . sversion > = 90200 )
appendPQExpBuffer ( & buf ,
" , \n pg_catalog.pg_size_pretty(pg_catalog.pg_tablespace_size(oid)) AS \" %s \" " ,
gettext_noop ( " Size " ) ) ;
2014-01-26 21:13:57 +01:00
if ( verbose & & pset . sversion > = 80200 )
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.shobj_description(oid, 'pg_tablespace') AS \" %s \" " ,
2014-01-26 21:13:57 +01:00
gettext_noop ( " Description " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_tablespace \n " ) ;
2004-07-15 05:56:06 +02:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " spcname " , NULL ,
NULL ) ;
2004-06-18 08:14:31 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2004-06-18 08:14:31 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2004-06-18 08:14:31 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of tablespaces " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2004-06-18 08:14:31 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2004-06-18 08:14:31 +02:00
PQclear ( res ) ;
return true ;
}
1999-11-04 22:56:02 +01:00
2017-07-27 17:57:29 +02:00
/*
* \ df
2009-04-21 17:49:06 +02:00
* Takes an optional regexp to select particular functions .
*
* As with \ d , you can specify the kinds of functions you want :
*
* a for aggregates
* n for normal
2019-09-11 08:17:35 +02:00
* p for procedure
2009-04-21 17:49:06 +02:00
* t for trigger
* w for window
*
* and you can mix and match these in any order .
1999-11-04 22:56:02 +01:00
*/
bool
2009-04-21 17:49:06 +02:00
describeFunctions ( const char * functypes , const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2009-05-05 04:29:06 +02:00
bool showAggregate = strchr ( functypes , ' a ' ) ! = NULL ;
bool showNormal = strchr ( functypes , ' n ' ) ! = NULL ;
2018-07-14 12:17:49 +02:00
bool showProcedure = strchr ( functypes , ' p ' ) ! = NULL ;
2009-05-05 04:29:06 +02:00
bool showTrigger = strchr ( functypes , ' t ' ) ! = NULL ;
bool showWindow = strchr ( functypes , ' w ' ) ! = NULL ;
bool have_where ;
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
2016-07-11 18:35:03 +02:00
static const bool translate_columns [ ] = { false , false , false , false , true , true , true , false , true , false , false , false , false } ;
/* No "Parallel" column before 9.6 */
static const bool translate_columns_pre_96 [ ] = { false , false , false , false , true , true , false , true , false , false , false , false } ;
1999-11-05 00:14:30 +01:00
2018-07-14 12:17:49 +02:00
if ( strlen ( functypes ) ! = strspn ( functypes , " anptwS+ " ) )
2009-04-21 19:28:01 +02:00
{
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " \\ df only takes [anptwS+] as options " ) ;
2018-07-14 12:17:49 +02:00
return true ;
}
if ( showProcedure & & pset . sversion < 110000 )
{
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " \\ df does not take a \" %c \" option with server version %s " ,
2019-05-22 18:55:34 +02:00
' p ' ,
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2009-04-21 19:28:01 +02:00
return true ;
}
2009-04-21 17:49:06 +02:00
if ( showWindow & & pset . sversion < 80400 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " \\ df does not take a \" %c \" option with server version %s " ,
2019-05-22 18:55:34 +02:00
' w ' ,
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2009-04-21 17:49:06 +02:00
return true ;
}
2018-07-14 12:17:49 +02:00
if ( ! showAggregate & & ! showNormal & & ! showProcedure & & ! showTrigger & & ! showWindow )
2009-04-21 17:49:06 +02:00
{
showAggregate = showNormal = showTrigger = true ;
2018-07-14 12:17:49 +02:00
if ( pset . sversion > = 110000 )
showProcedure = true ;
2009-04-21 17:49:06 +02:00
if ( pset . sversion > = 80400 )
showWindow = true ;
}
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2004-09-10 06:10:53 +02:00
" SELECT n.nspname as \" %s \" , \n "
2008-07-18 05:32:53 +02:00
" p.proname as \" %s \" , \n " ,
2008-07-03 05:37:17 +02:00
gettext_noop ( " Schema " ) ,
2008-07-18 05:32:53 +02:00
gettext_noop ( " Name " ) ) ;
2008-07-03 05:37:17 +02:00
2018-03-02 14:57:38 +01:00
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 'a' THEN '%s' \n "
" WHEN 'w' THEN '%s' \n "
" WHEN 'p' 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 if ( pset . sversion > = 80400 )
2008-07-18 05:32:53 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_function_result(p.oid) as \" %s \" , \n "
" pg_catalog.pg_get_function_arguments(p.oid) as \" %s \" , \n "
2009-04-21 17:49:06 +02:00
" CASE \n "
" WHEN p.proisagg THEN '%s' \n "
" WHEN p.proiswindow THEN '%s' \n "
2009-05-05 04:29:06 +02:00
" WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s' \n "
2009-04-21 17:49:06 +02:00
" ELSE '%s' \n "
2013-01-25 16:19:11 +01:00
" END as \" %s \" " ,
2008-07-18 05:32:53 +02:00
gettext_noop ( " Result data type " ) ,
2009-06-11 16:49:15 +02:00
gettext_noop ( " Argument data types " ) ,
/* translator: "agg" is short for "aggregate" */
gettext_noop ( " agg " ) ,
gettext_noop ( " window " ) ,
gettext_noop ( " trigger " ) ,
2017-11-30 14:46:13 +01:00
gettext_noop ( " func " ) ,
2009-06-11 16:49:15 +02:00
gettext_noop ( " Type " ) ) ;
else if ( pset . sversion > = 80100 )
2008-07-03 05:37:17 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END || \n "
" pg_catalog.format_type(p.prorettype, NULL) as \" %s \" , \n "
2009-06-11 16:49:15 +02:00
" CASE WHEN proallargtypes IS NOT NULL THEN \n "
" pg_catalog.array_to_string(ARRAY( \n "
" SELECT \n "
" CASE \n "
" WHEN p.proargmodes[s.i] = 'i' THEN '' \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHEN p.proargmodes[s.i] = 'o' THEN 'OUT ' \n "
" WHEN p.proargmodes[s.i] = 'b' THEN 'INOUT ' \n "
" WHEN p.proargmodes[s.i] = 'v' THEN 'VARIADIC ' \n "
2009-06-11 16:49:15 +02:00
" END || \n "
" CASE \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHEN COALESCE(p.proargnames[s.i], '') = '' THEN '' \n "
2017-04-14 05:47:46 +02:00
" ELSE p.proargnames[s.i] || ' ' \n "
2009-06-11 16:49:15 +02:00
" END || \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(p.proallargtypes[s.i], NULL) \n "
2009-06-11 16:49:15 +02:00
" FROM \n "
" pg_catalog.generate_series(1, pg_catalog.array_upper(p.proallargtypes, 1)) AS s(i) \n "
" ), ', ') \n "
" ELSE \n "
" pg_catalog.array_to_string(ARRAY( \n "
" SELECT \n "
" CASE \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHEN COALESCE(p.proargnames[s.i+1], '') = '' THEN '' \n "
2009-06-11 16:49:15 +02:00
" ELSE p.proargnames[s.i+1] || ' ' \n "
" END || \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(p.proargtypes[s.i], NULL) \n "
2009-06-11 16:49:15 +02:00
" FROM \n "
" pg_catalog.generate_series(0, pg_catalog.array_upper(p.proargtypes, 1)) AS s(i) \n "
" ), ', ') \n "
" END AS \" %s \" , \n "
" CASE \n "
" WHEN p.proisagg THEN '%s' \n "
" WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s' \n "
" ELSE '%s' \n "
" END AS \" %s \" " ,
2008-07-18 05:32:53 +02:00
gettext_noop ( " Result data type " ) ,
2009-04-21 17:49:06 +02:00
gettext_noop ( " Argument data types " ) ,
2009-06-11 16:49:15 +02:00
/* translator: "agg" is short for "aggregate" */
2009-04-21 17:49:06 +02:00
gettext_noop ( " agg " ) ,
gettext_noop ( " trigger " ) ,
2017-11-30 14:46:13 +01:00
gettext_noop ( " func " ) ,
2009-04-21 17:49:06 +02:00
gettext_noop ( " Type " ) ) ;
2008-07-03 05:37:17 +02:00
else
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" CASE WHEN p.proretset THEN 'SETOF ' ELSE '' END || \n "
" pg_catalog.format_type(p.prorettype, NULL) as \" %s \" , \n "
" pg_catalog.oidvectortypes(p.proargtypes) as \" %s \" , \n "
2009-06-11 16:49:15 +02:00
" CASE \n "
" WHEN p.proisagg THEN '%s' \n "
" WHEN p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype THEN '%s' \n "
" ELSE '%s' \n "
" END AS \" %s \" " ,
2008-07-18 05:32:53 +02:00
gettext_noop ( " Result data type " ) ,
2009-04-21 17:49:06 +02:00
gettext_noop ( " Argument data types " ) ,
2009-06-11 16:49:15 +02:00
/* translator: "agg" is short for "aggregate" */
2009-04-21 17:49:06 +02:00
gettext_noop ( " agg " ) ,
gettext_noop ( " trigger " ) ,
2017-11-30 14:46:13 +01:00
gettext_noop ( " func " ) ,
2009-04-21 17:49:06 +02:00
gettext_noop ( " Type " ) ) ;
2001-06-30 19:26:12 +02:00
2000-04-12 19:17:23 +02:00
if ( verbose )
2016-07-11 18:35:03 +02:00
{
2002-04-24 07:24:00 +02:00
appendPQExpBuffer ( & buf ,
2007-06-28 08:40:16 +02:00
" , \n CASE \n "
2009-05-05 04:29:06 +02:00
" WHEN p.provolatile = 'i' THEN '%s' \n "
" WHEN p.provolatile = 's' THEN '%s' \n "
" WHEN p.provolatile = 'v' THEN '%s' \n "
2016-07-11 18:35:03 +02:00
" END as \" %s \" " ,
2009-05-05 04:29:06 +02:00
gettext_noop ( " immutable " ) ,
gettext_noop ( " stable " ) ,
gettext_noop ( " volatile " ) ,
2016-07-11 18:35:03 +02:00
gettext_noop ( " Volatility " ) ) ;
if ( pset . sversion > = 90600 )
appendPQExpBuffer ( & buf ,
" , \n CASE \n "
" WHEN p.proparallel = 'r' THEN '%s' \n "
" WHEN p.proparallel = 's' THEN '%s' \n "
" WHEN p.proparallel = 'u' THEN '%s' \n "
" END as \" %s \" " ,
gettext_noop ( " restricted " ) ,
gettext_noop ( " safe " ) ,
gettext_noop ( " unsafe " ) ,
gettext_noop ( " Parallel " ) ) ;
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.pg_get_userbyid(p.proowner) as \" %s \" "
" , \n CASE WHEN prosecdef THEN '%s' ELSE '%s' END AS \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Owner " ) ,
2016-07-11 18:35:03 +02:00
gettext_noop ( " definer " ) ,
gettext_noop ( " invoker " ) ,
gettext_noop ( " Security " ) ) ;
appendPQExpBufferStr ( & buf , " , \n " ) ;
printACLColumn ( & buf , " p.proacl " ) ;
appendPQExpBuffer ( & buf ,
" , \n l.lanname as \" %s \" "
" , \n p.prosrc as \" %s \" "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.obj_description(p.oid, 'pg_proc') as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Language " ) ,
gettext_noop ( " Source code " ) ,
gettext_noop ( " Description " ) ) ;
2016-07-11 18:35:03 +02:00
}
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_proc p "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" \n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace \n " ) ;
2008-07-03 05:37:17 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_language l ON l.oid = p.prolang \n " ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
2009-05-05 04:29:06 +02:00
have_where = false ;
2009-04-21 17:49:06 +02:00
2009-05-05 04:29:06 +02:00
/* filter by function type, if requested */
2018-07-14 12:17:49 +02:00
if ( showNormal & & showAggregate & & showProcedure & & showTrigger & & showWindow )
2009-06-11 16:49:15 +02:00
/* Do nothing */ ;
2009-04-21 17:49:06 +02:00
else if ( showNormal )
{
if ( ! showAggregate )
2009-05-05 04:29:06 +02:00
{
if ( have_where )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND " ) ;
2009-05-05 04:29:06 +02:00
else
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE " ) ;
2009-05-05 04:29:06 +02:00
have_where = true ;
}
2018-03-02 14:57:38 +01:00
if ( pset . sversion > = 110000 )
appendPQExpBufferStr ( & buf , " p.prokind <> 'a' \n " ) ;
else
appendPQExpBufferStr ( & buf , " NOT p.proisagg \n " ) ;
2009-05-05 04:29:06 +02:00
}
2018-07-14 12:17:49 +02:00
if ( ! showProcedure & & pset . sversion > = 110000 )
{
if ( have_where )
appendPQExpBufferStr ( & buf , " AND " ) ;
else
{
appendPQExpBufferStr ( & buf , " WHERE " ) ;
have_where = true ;
}
appendPQExpBufferStr ( & buf , " p.prokind <> 'p' \n " ) ;
}
2009-04-21 17:49:06 +02:00
if ( ! showTrigger )
{
2009-05-05 04:29:06 +02:00
if ( have_where )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND " ) ;
2009-05-05 04:29:06 +02:00
else
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE " ) ;
2009-05-05 04:29:06 +02:00
have_where = true ;
}
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " p.prorettype <> 'pg_catalog.trigger'::pg_catalog.regtype \n " ) ;
2009-05-05 04:29:06 +02:00
}
if ( ! showWindow & & pset . sversion > = 80400 )
{
if ( have_where )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND " ) ;
2009-04-21 17:49:06 +02:00
else
2009-05-05 04:29:06 +02:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE " ) ;
2009-05-05 04:29:06 +02:00
have_where = true ;
}
2018-03-02 14:57:38 +01:00
if ( pset . sversion > = 110000 )
appendPQExpBufferStr ( & buf , " p.prokind <> 'w' \n " ) ;
else
appendPQExpBufferStr ( & buf , " NOT p.proiswindow \n " ) ;
2009-04-21 17:49:06 +02:00
}
}
else
{
2009-06-11 16:49:15 +02:00
bool needs_or = false ;
2009-04-21 17:49:06 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE ( \n " ) ;
2009-05-05 04:29:06 +02:00
have_where = true ;
/* Note: at least one of these must be true ... */
2009-04-21 17:49:06 +02:00
if ( showAggregate )
{
2018-03-02 14:57:38 +01:00
if ( pset . sversion > = 110000 )
appendPQExpBufferStr ( & buf , " p.prokind = 'a' \n " ) ;
else
appendPQExpBufferStr ( & buf , " p.proisagg \n " ) ;
2009-04-21 17:49:06 +02:00
needs_or = true ;
}
if ( showTrigger )
{
if ( needs_or )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " OR " ) ;
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" p.prorettype = 'pg_catalog.trigger'::pg_catalog.regtype \n " ) ;
2009-04-21 17:49:06 +02:00
needs_or = true ;
}
2018-07-14 12:17:49 +02:00
if ( showProcedure )
{
if ( needs_or )
appendPQExpBufferStr ( & buf , " OR " ) ;
appendPQExpBufferStr ( & buf , " p.prokind = 'p' \n " ) ;
needs_or = true ;
}
2009-04-21 17:49:06 +02:00
if ( showWindow )
{
if ( needs_or )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " OR " ) ;
2018-03-02 14:57:38 +01:00
if ( pset . sversion > = 110000 )
appendPQExpBufferStr ( & buf , " p.prokind = 'w' \n " ) ;
else
appendPQExpBufferStr ( & buf , " p.proiswindow \n " ) ;
2009-05-05 04:29:06 +02:00
needs_or = true ;
2009-04-21 17:49:06 +02:00
}
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ) \n " ) ;
2009-04-21 17:49:06 +02:00
}
2002-08-10 05:56:24 +02:00
2009-10-28 19:09:44 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , have_where , false ,
2009-05-05 04:29:06 +02:00
" n.nspname " , " p.proname " , NULL ,
" pg_catalog.pg_function_is_visible(p.oid) " ) ;
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
2014-05-06 18:12:18 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2, 4; " ) ;
1999-11-05 00:14:30 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of functions " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2016-07-11 18:35:03 +02:00
if ( pset . sversion > = 90600 )
{
myopt . translate_columns = translate_columns ;
myopt . n_translate_columns = lengthof ( translate_columns ) ;
}
else
{
myopt . translate_columns = translate_columns_pre_96 ;
myopt . n_translate_columns = lengthof ( translate_columns_pre_96 ) ;
}
1999-11-05 00:14:30 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
/*
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
* \ dT
* describe types
1999-11-04 22:56:02 +01:00
*/
bool
2009-01-06 22:10:30 +01:00
describeTypes ( const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT n.nspname as \" %s \" , \n "
2005-10-15 04:49:52 +02:00
" pg_catalog.format_type(t.oid, NULL) AS \" %s \" , \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ) ;
2000-04-12 19:17:23 +02:00
if ( verbose )
2002-04-24 07:24:00 +02:00
appendPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" 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 "
2008-07-03 05:37:17 +02:00
" END AS \" %s \" , \n " ,
gettext_noop ( " Internal name " ) ,
gettext_noop ( " Size " ) ) ;
if ( verbose & & pset . sversion > = 80300 )
2010-10-25 05:04:37 +02:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" pg_catalog.array_to_string( \n "
" ARRAY( \n "
2017-04-12 20:43:01 +02:00
" SELECT e.enumlabel \n "
2013-11-18 17:29:01 +01:00
" FROM pg_catalog.pg_enum e \n "
" WHERE e.enumtypid = t.oid \n " ) ;
2010-10-25 05:04:37 +02:00
if ( pset . sversion > = 90100 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" ORDER BY e.enumsortorder \n " ) ;
2010-10-25 05:04:37 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" ORDER BY e.oid \n " ) ;
2010-10-25 05:04:37 +02:00
appendPQExpBuffer ( & buf ,
2008-05-05 02:11:31 +02:00
" ), \n "
" E' \\ n' \n "
" ) AS \" %s \" , \n " ,
gettext_noop ( " Elements " ) ) ;
2010-10-25 05:04:37 +02:00
}
2015-04-09 21:39:35 +02:00
if ( verbose )
{
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(t.typowner) AS \" %s \" , \n " ,
2015-04-09 21:39:35 +02:00
gettext_noop ( " Owner " ) ) ;
}
2011-12-19 23:05:19 +01:00
if ( verbose & & pset . sversion > = 90200 )
{
printACLColumn ( & buf , " t.typacl " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2011-12-19 23:05:19 +01:00
}
2008-07-03 05:37:17 +02:00
2002-04-24 07:24:00 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(t.oid, 'pg_type') as \" %s \" \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2000-04-12 19:17:23 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " FROM pg_catalog.pg_type t \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n " ) ;
2002-08-10 05:56:24 +02:00
2000-04-12 19:17:23 +02:00
/*
2008-07-03 05:37:17 +02:00
* do not include complex types ( typrelid ! = 0 ) unless they are standalone
* composite types
2000-04-12 19:17:23 +02:00
*/
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE (t.typrelid = 0 " ) ;
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , " OR (SELECT c.relkind = " CppAsString2 ( RELKIND_COMPOSITE_TYPE )
" FROM pg_catalog.pg_class c "
2014-05-06 18:12:18 +02:00
" WHERE c.oid = t.typrelid)) \n " ) ;
2009-06-11 16:49:15 +02:00
2008-07-03 05:37:17 +02:00
/*
* do not include array types ( before 8.3 we have to use the assumption
* that their names start with underscore )
*/
if ( pset . sversion > = 80300 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type el WHERE el.oid = t.typelem AND el.typarray = t.oid) \n " ) ;
2008-07-03 05:37:17 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND t.typname !~ '^_' \n " ) ;
1999-11-05 00:14:30 +01:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
2014-05-06 18:12:18 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2002-08-10 05:56:24 +02:00
/* Match name pattern against either internal or external name */
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " t.typname " ,
" pg_catalog.format_type(t.oid, NULL) " ,
" pg_catalog.pg_type_is_visible(t.oid) " ) ;
1999-11-05 00:14:30 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2002-04-24 07:24:00 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of data types " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
1999-11-05 00:14:30 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
2017-07-27 17:57:29 +02:00
/*
* \ do
2014-01-16 21:29:18 +01:00
* Describe operators
1999-11-04 22:56:02 +01:00
*/
bool
2014-01-16 21:29:18 +01:00
describeOperators ( const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
2011-03-03 07:33:19 +01:00
/*
* Note : before Postgres 9.1 , we did not assign comments to any built - in
* operators , preferring to let the comment on the underlying function
* suffice . The coalesce ( ) on the obj_description ( ) calls below supports
* this convention by providing a fallback lookup of a comment on the
* operator ' s function . As of 9.1 there is a policy that every built - in
* operator should have a comment ; so the coalesce ( ) is no longer
* necessary so far as built - in operators are concerned . We keep it
* anyway , for now , because ( 1 ) third - party modules may still be following
* the old convention , and ( 2 ) we ' d need to do it anyway when talking to a
* pre - 9.1 server .
*/
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" 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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(o.oprresult, NULL) AS \" %s \" , \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Left arg type " ) ,
gettext_noop ( " Right arg type " ) ,
2014-01-16 21:29:18 +01:00
gettext_noop ( " Result type " ) ) ;
if ( verbose )
appendPQExpBuffer ( & buf ,
" o.oprcode AS \" %s \" , \n " ,
gettext_noop ( " Function " ) ) ;
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" coalesce(pg_catalog.obj_description(o.oid, 'pg_operator'), \n "
" pg_catalog.obj_description(o.oprcode, 'pg_proc')) AS \" %s \" \n "
2014-01-16 21:29:18 +01:00
" FROM pg_catalog.pg_operator o \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = o.oprnamespace \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2002-08-10 05:56:24 +02:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2009-04-02 17:15:32 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , ! showSystem & & ! pattern , true ,
2006-10-10 01:30:33 +02:00
" n.nspname " , " o.oprname " , NULL ,
" pg_catalog.pg_operator_is_visible(o.oid) " ) ;
1999-11-05 00:14:30 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2, 3, 4; " ) ;
1999-11-05 00:14:30 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of operators " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
1999-11-05 00:14:30 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
/*
* listAllDbs
*
* for \ l , \ list , and - l switch
*/
bool
2013-03-04 04:17:08 +01:00
listAllDbs ( const char * pattern , bool verbose )
1999-11-04 22:56:02 +01:00
{
1999-11-05 00:14:30 +01:00
PGresult * res ;
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
1999-11-04 22:56:02 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT d.datname as \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(d.datdba) as \" %s \" , \n "
" pg_catalog.pg_encoding_to_char(d.encoding) as \" %s \" , \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ,
2008-09-23 11:20:39 +02:00
gettext_noop ( " Encoding " ) ) ;
if ( pset . sversion > = 80400 )
appendPQExpBuffer ( & buf ,
" d.datcollate as \" %s \" , \n "
" d.datctype as \" %s \" , \n " ,
2011-02-12 14:54:13 +01:00
gettext_noop ( " Collate " ) ,
2008-09-23 11:20:39 +02:00
gettext_noop ( " Ctype " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " " ) ;
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " d.datacl " ) ;
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80200 )
2008-03-30 20:10:20 +02:00
appendPQExpBuffer ( & buf ,
" , \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 "
" ELSE 'No Access' \n "
" END as \" %s \" " ,
gettext_noop ( " Size " ) ) ;
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80000 )
2006-04-27 01:15:45 +02:00
appendPQExpBuffer ( & buf ,
" , \n t.spcname as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Tablespace " ) ) ;
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80200 )
2009-06-11 16:49:15 +02:00
appendPQExpBuffer ( & buf ,
2006-02-12 04:22:21 +01:00
" , \n pg_catalog.shobj_description(d.oid, 'pg_database') as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_database d \n " ) ;
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80000 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" JOIN pg_catalog.pg_tablespace t on d.dattablespace = t.oid \n " ) ;
2013-03-04 04:17:08 +01:00
if ( pattern )
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " d.datname " , NULL , NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of databases " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
1999-11-04 22:56:02 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
2001-06-30 19:26:12 +02:00
/*
2009-01-22 21:16:10 +01:00
* List Tables ' Grant / Revoke Permissions
1999-11-04 22:56:02 +01:00
* \ z ( now also \ dp - - perhaps more mnemonic )
*/
bool
2002-08-10 05:56:24 +02:00
permissionsList ( const char * pattern )
1999-11-04 22:56:02 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
static const bool translate_columns [ ] = { false , false , true , false , false , false } ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
2002-08-10 05:56:24 +02:00
/*
2005-10-15 04:49:52 +02:00
* we ignore indexes and toast tables since they have no meaningful rights
2002-08-10 05:56:24 +02:00
*/
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT n.nspname as \" %s \" , \n "
" c.relname as \" %s \" , \n "
2013-03-04 01:23:31 +01:00
" CASE c.relkind "
2017-03-10 02:42:42 +01:00
" WHEN " CppAsString2 ( RELKIND_RELATION ) " THEN '%s' "
" WHEN " CppAsString2 ( RELKIND_VIEW ) " THEN '%s' "
" WHEN " CppAsString2 ( RELKIND_MATVIEW ) " THEN '%s' "
" WHEN " CppAsString2 ( RELKIND_SEQUENCE ) " THEN '%s' "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHEN " CppAsString2 ( RELKIND_FOREIGN_TABLE ) " THEN '%s' "
" WHEN " CppAsString2 ( RELKIND_PARTITIONED_TABLE ) " THEN '%s' "
2013-03-04 01:23:31 +01:00
" END as \" %s \" , \n "
2008-12-31 19:07:47 +01:00
" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
2013-03-04 01:23:31 +01:00
gettext_noop ( " table " ) ,
gettext_noop ( " view " ) ,
gettext_noop ( " materialized view " ) ,
gettext_noop ( " sequence " ) ,
2011-04-10 17:42:00 +02:00
gettext_noop ( " foreign table " ) ,
2018-11-19 20:54:26 +01:00
gettext_noop ( " partitioned table " ) ,
2008-07-03 05:37:17 +02:00
gettext_noop ( " Type " ) ) ;
2009-01-22 21:16:10 +01:00
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " c.relacl " ) ;
2009-01-22 21:16:10 +01:00
if ( pset . sversion > = 80400 )
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 \" " ,
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
gettext_noop ( " Column privileges " ) ) ;
2016-12-05 21:50:55 +01:00
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 || E'):' \n "
2017-04-14 05:47:46 +02:00
" ELSE E':' \n "
2016-12-05 21:50:55 +01:00
" 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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" E' \\ n to: ' || pg_catalog.array_to_string( \n "
2016-12-05 21:50:55 +01:00
" 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 )
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
appendPQExpBuffer ( & buf ,
" , \n pg_catalog.array_to_string(ARRAY( \n "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" SELECT polname \n "
2016-12-05 21:50:55 +01:00
" || CASE WHEN NOT polpermissive THEN \n "
" E' (RESTRICTIVE)' \n "
" ELSE '' END \n "
2015-01-24 22:16:22 +01:00
" || CASE WHEN polcmd != '*' THEN \n "
" E' (' || polcmd || E'):' \n "
2017-04-14 05:47:46 +02:00
" ELSE E':' \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" END \n "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" || CASE WHEN polqual IS NOT NULL THEN \n "
" E' \\ n (u): ' || pg_catalog.pg_get_expr(polqual, polrelid) \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" ELSE E'' \n "
" END \n "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" || CASE WHEN polwithcheck IS NOT NULL THEN \n "
" E' \\ n (c): ' || pg_catalog.pg_get_expr(polwithcheck, polrelid) \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" ELSE E'' \n "
" END "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" || CASE WHEN polroles <> '{0}' THEN \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" E' \\ n to: ' || pg_catalog.array_to_string( \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" ARRAY( \n "
" SELECT rolname \n "
" FROM pg_catalog.pg_roles \n "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" WHERE oid = ANY (polroles) \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" ORDER BY 1 \n "
" ), E', ') \n "
" ELSE E'' \n "
" END \n "
Rename pg_rowsecurity -> pg_policy and other fixes
As pointed out by Robert, we should really have named pg_rowsecurity
pg_policy, as the objects stored in that catalog are policies. This
patch fixes that and updates the column names to start with 'pol' to
match the new catalog name.
The security consideration for COPY with row level security, also
pointed out by Robert, has also been addressed by remembering and
re-checking the OID of the relation initially referenced during COPY
processing, to make sure it hasn't changed under us by the time we
finish planning out the query which has been built.
Robert and Alvaro also commented on missing OCLASS and OBJECT entries
for POLICY (formerly ROWSECURITY or POLICY, depending) in various
places. This patch fixes that too, which also happens to add the
ability to COMMENT on policies.
In passing, attempt to improve the consistency of messages, comments,
and documentation as well. This removes various incarnations of
'row-security', 'row-level security', 'Row-security', etc, in favor
of 'policy', 'row level security' or 'row_security' as appropriate.
Happy Thanksgiving!
2014-11-27 07:06:36 +01:00
" FROM pg_catalog.pg_policy pol \n "
" WHERE polrelid = c.oid), E' \\ n') \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" AS \" %s \" " ,
gettext_noop ( " Policies " ) ) ;
2009-01-22 21:16:10 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n "
2017-03-10 02:42:42 +01:00
" 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 " ) ;
2008-07-03 05:37:17 +02:00
2002-08-10 05:56:24 +02:00
/*
* Unless a schema pattern is specified , we suppress system and temp
2005-10-15 04:49:52 +02:00
* tables , since they normally aren ' t very interesting from a permissions
* point of view . You can see ' em by explicit request though , eg with \ z
* pg_catalog . *
2002-08-10 05:56:24 +02:00
*/
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.relname " , NULL ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" n.nspname !~ '^pg_' AND pg_catalog.pg_table_is_visible(c.oid) " ) ;
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
1999-11-04 22:56:02 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
2002-04-24 07:24:00 +02:00
{
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
return false ;
2002-04-24 07:24:00 +02:00
}
1999-11-05 00:14:30 +01:00
2000-04-12 19:17:23 +02:00
myopt . nullPrint = NULL ;
2008-07-03 17:59:55 +02:00
printfPQExpBuffer ( & buf , _ ( " Access privileges " ) ) ;
2002-04-24 07:24:00 +02:00
myopt . title = buf . data ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
1999-11-04 22:56:02 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
2009-10-05 21:24:49 +02:00
/*
* \ ddp
*
2012-12-09 06:08:23 +01:00
* List Default ACLs . The pattern can match either schema or role name .
2009-10-05 21:24:49 +02:00
*/
bool
listDefaultACLs ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
static const bool translate_columns [ ] = { false , false , true , false } ;
2010-02-17 05:19:41 +01:00
if ( pset . sversion < 90000 )
2009-10-05 21:24:49 +02:00
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support altering default privileges. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2009-10-05 21:24:49 +02:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT pg_catalog.pg_get_userbyid(d.defaclrole) AS \" %s \" , \n "
2009-10-05 21:24:49 +02:00
" n.nspname AS \" %s \" , \n "
2017-03-28 17:58:55 +02:00
" CASE d.defaclobjtype WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' WHEN '%c' THEN '%s' END AS \" %s \" , \n "
2009-10-05 21:24:49 +02:00
" " ,
gettext_noop ( " Owner " ) ,
gettext_noop ( " Schema " ) ,
2012-12-09 06:08:23 +01:00
DEFACLOBJ_RELATION ,
2009-10-05 21:24:49 +02:00
gettext_noop ( " table " ) ,
2012-12-09 06:08:23 +01:00
DEFACLOBJ_SEQUENCE ,
2009-10-05 21:24:49 +02:00
gettext_noop ( " sequence " ) ,
2012-12-09 06:08:23 +01:00
DEFACLOBJ_FUNCTION ,
2009-10-05 21:24:49 +02:00
gettext_noop ( " function " ) ,
2012-12-09 06:08:23 +01:00
DEFACLOBJ_TYPE ,
gettext_noop ( " type " ) ,
2017-03-28 17:58:55 +02:00
DEFACLOBJ_NAMESPACE ,
gettext_noop ( " schema " ) ,
2009-10-05 21:24:49 +02:00
gettext_noop ( " Type " ) ) ;
printACLColumn ( & buf , " d.defaclacl " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_default_acl d \n "
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.defaclnamespace \n " ) ;
2009-10-05 21:24:49 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL ,
" n.nspname " ,
" pg_catalog.pg_get_userbyid(d.defaclrole) " ,
NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2, 3; " ) ;
2009-10-05 21:24:49 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2009-10-05 21:24:49 +02:00
if ( ! res )
{
termPQExpBuffer ( & buf ) ;
return false ;
}
myopt . nullPrint = NULL ;
printfPQExpBuffer ( & buf , _ ( " Default access privileges " ) ) ;
myopt . title = buf . data ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2009-10-05 21:24:49 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2009-10-05 21:24:49 +02:00
termPQExpBuffer ( & buf ) ;
PQclear ( res ) ;
return true ;
}
1999-11-04 22:56:02 +01:00
/*
* Get object comments
*
* \ dd [ foo ]
*
2011-08-11 17:16:29 +02:00
* Note : This command only lists comments for object types which do not have
* their comments displayed by their own backslash commands . The following
* types of objects will be displayed : constraint , operator class ,
* operator family , rule , and trigger .
*
1999-11-04 22:56:02 +01:00
*/
bool
2009-01-06 22:10:30 +01:00
objectDescription ( const char * pattern , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
2008-07-15 00:00:04 +02:00
static const bool translate_columns [ ] = { false , false , true , false } ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
2002-08-10 05:56:24 +02:00
appendPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT DISTINCT tt.nspname AS \" %s \" , tt.name AS \" %s \" , tt.object AS \" %s \" , d.description AS \" %s \" \n "
" FROM ( \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Object " ) ,
gettext_noop ( " Description " ) ) ;
2001-06-30 19:26:12 +02:00
2014-12-23 13:06:44 +01:00
/* Table constraint descriptions */
2002-08-10 05:56:24 +02:00
appendPQExpBuffer ( & buf ,
2011-08-11 17:16:29 +02:00
" SELECT pgc.oid as oid, pgc.tableoid AS tableoid, \n "
2002-09-04 22:31:48 +02:00
" n.nspname as nspname, \n "
2011-08-11 17:16:29 +02:00
" CAST(pgc.conname AS pg_catalog.text) as name, "
2002-09-04 22:31:48 +02:00
" CAST('%s' AS pg_catalog.text) as object \n "
2011-08-11 17:16:29 +02:00
" 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 " ,
2014-12-23 13:06:44 +01:00
gettext_noop ( " table constraint " ) ) ;
2009-01-06 22:10:30 +01:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-06-11 16:49:15 +02:00
2011-08-11 17:16:29 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , ! showSystem & & ! pattern ,
false , " n.nspname " , " pgc.conname " , NULL ,
2006-10-10 01:30:33 +02:00
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
2001-06-30 19:26:12 +02:00
2014-12-23 13:06:44 +01:00
/* 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 " ) ;
processSQLNamePattern ( pset . db , & buf , pattern , ! showSystem & & ! pattern ,
false , " n.nspname " , " pgc.conname " , NULL ,
" pg_catalog.pg_type_is_visible(t.oid) " ) ;
2011-08-11 17:16:29 +02:00
/*
2011-11-12 05:33:44 +01:00
* pg_opclass . opcmethod only available in 8.3 +
2011-08-11 17:16:29 +02:00
*/
if ( pset . sversion > = 80300 )
{
/* 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 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2011-08-11 17:16:29 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " o.opcname " , NULL ,
" pg_catalog.pg_opclass_is_visible(o.oid) " ) ;
2011-11-12 05:33:44 +01:00
}
2011-08-11 17:16:29 +02:00
2011-11-12 05:33:44 +01:00
/*
* although operator family comments have been around since 8.3 ,
* pg_opfamily_is_visible is only available in 9.2 +
*/
if ( pset . sversion > = 90200 )
{
2011-08-11 17:16:29 +02:00
/* Operator family descriptions */
appendPQExpBuffer ( & buf ,
" UNION ALL \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT opf.oid as oid, opf.tableoid as tableoid, \n "
2011-08-11 17:16:29 +02:00
" n.nspname as nspname, \n "
" CAST(opf.opfname AS pg_catalog.text) AS name, \n "
" CAST('%s' AS pg_catalog.text) as object \n "
" FROM pg_catalog.pg_opfamily opf \n "
" JOIN pg_catalog.pg_am am "
" ON opf.opfmethod = am.oid \n "
" JOIN pg_catalog.pg_namespace n "
" ON opf.opfnamespace = n.oid \n " ,
gettext_noop ( " operator family " ) ) ;
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2011-08-11 17:16:29 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " opf.opfname " , NULL ,
" pg_catalog.pg_opfamily_is_visible(opf.oid) " ) ;
}
2011-03-03 07:33:19 +01:00
/* Rule descriptions (ignore rules for views) */
2002-08-10 05:56:24 +02:00
appendPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" 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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" 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 "
2002-09-04 22:31:48 +02:00
" WHERE r.rulename != '_RETURN' \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " rule " ) ) ;
2009-01-06 22:10:30 +01:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " r.rulename " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
2001-06-30 19:26:12 +02:00
2011-03-03 07:33:19 +01:00
/* Trigger descriptions */
2002-08-10 05:56:24 +02:00
appendPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" 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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" 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 " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " trigger " ) ) ;
2009-04-02 19:38:26 +02:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2009-04-02 17:15:32 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , ! showSystem & & ! pattern , false ,
2006-10-10 01:30:33 +02:00
" n.nspname " , " t.tgname " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" ) AS tt \n "
" JOIN pg_catalog.pg_description d ON (tt.oid = d.objoid AND tt.tableoid = d.classoid AND d.objsubid = 0) \n " ) ;
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2, 3; " ) ;
1999-11-05 00:14:30 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " Object descriptions " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
1999-11-05 00:14:30 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
/*
* describeTableDetails ( for \ d )
*
2002-08-10 05:56:24 +02:00
* This routine finds the tables to be displayed , and calls
* describeOneTableDetails for each one .
2004-04-22 19:38:16 +02:00
*
* verbose : if true , this is \ d +
1999-11-04 22:56:02 +01:00
*/
2002-08-10 05:56:24 +02:00
bool
2009-01-20 03:13:42 +01:00
describeTableDetails ( const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-08-10 05:56:24 +02:00
PQExpBufferData buf ;
PGresult * res ;
int i ;
1999-11-05 00:14:30 +01:00
2002-08-10 05:56:24 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT c.oid, \n "
" n.nspname, \n "
" c.relname \n "
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \n " ) ;
2002-08-10 05:56:24 +02:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-20 03:13:42 +01:00
2009-04-02 17:15:32 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , ! showSystem & & ! pattern , false ,
2006-10-10 01:30:33 +02:00
" n.nspname " , " c.relname " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 2, 3; " ) ;
2002-08-10 05:56:24 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-08-10 05:56:24 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
if ( PQntuples ( res ) = = 0 )
1999-11-05 00:14:30 +01:00
{
2006-08-29 17:19:51 +02:00
if ( ! pset . quiet )
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
{
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any relation named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any relations. " ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
}
2002-08-10 05:56:24 +02:00
PQclear ( res ) ;
return false ;
1999-11-05 00:14:30 +01:00
}
1999-11-04 22:56:02 +01:00
2002-08-10 05:56:24 +02:00
for ( i = 0 ; i < PQntuples ( res ) ; i + + )
{
const char * oid ;
const char * nspname ;
const char * relname ;
oid = PQgetvalue ( res , i , 0 ) ;
nspname = PQgetvalue ( res , i , 1 ) ;
relname = PQgetvalue ( res , i , 2 ) ;
1999-11-04 22:56:02 +01:00
2002-08-10 05:56:24 +02:00
if ( ! describeOneTableDetails ( nspname , relname , oid , verbose ) )
{
PQclear ( res ) ;
return false ;
}
2006-06-14 18:49:03 +02:00
if ( cancel_pressed )
{
PQclear ( res ) ;
return false ;
}
2002-08-10 05:56:24 +02:00
}
PQclear ( res ) ;
return true ;
}
/*
* describeOneTableDetails ( for \ d )
*
* Unfortunately , the information presented here is so complicated that it
* cannot be done in a single query . So we have to assemble the printed table
* by hand and pass it to the underlying printTable ( ) function .
*/
static bool
describeOneTableDetails ( const char * schemaname ,
const char * relationname ,
const char * oid ,
bool verbose )
1999-11-04 22:56:02 +01:00
{
2018-07-19 20:53:41 +02:00
bool retval = false ;
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
PGresult * res = NULL ;
2000-01-14 23:18:03 +01:00
printTableOpt myopt = pset . popt . topt ;
2008-05-13 00:59:58 +02:00
printTableContent cont ;
2009-06-11 16:49:15 +02:00
bool printTableInitialized = false ;
1999-11-05 00:14:30 +01:00
int i ;
2002-09-04 22:31:48 +02:00
char * view_def = NULL ;
2016-11-03 17:00:00 +01:00
char * headers [ 11 ] ;
2002-04-24 07:24:00 +02:00
PQExpBufferData title ;
2002-12-21 02:07:07 +01:00
PQExpBufferData tmpbuf ;
2009-07-07 18:28:38 +02:00
int cols ;
2018-07-19 20:53:41 +02:00
int attname_col = - 1 , /* column indexes in "res" */
atttype_col = - 1 ,
attrdef_col = - 1 ,
attnotnull_col = - 1 ,
attcoll_col = - 1 ,
attidentity_col = - 1 ,
2019-03-30 08:13:09 +01:00
attgenerated_col = - 1 ,
2018-07-19 20:53:41 +02:00
isindexkey_col = - 1 ,
indexdef_col = - 1 ,
fdwopts_col = - 1 ,
attstorage_col = - 1 ,
attstattarget_col = - 1 ,
attdescr_col = - 1 ;
int numrows ;
2000-04-12 19:17:23 +02:00
struct
{
int16 checks ;
2004-04-22 19:38:16 +02:00
char relkind ;
bool hasindex ;
2000-04-12 19:17:23 +02:00
bool hasrules ;
2008-11-09 22:24:33 +01:00
bool hastriggers ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
bool rowsecurity ;
2015-10-05 03:05:08 +02:00
bool forcerowsecurity ;
2004-08-29 07:07:03 +02:00
bool hasoids ;
2019-03-26 15:14:34 +01:00
bool ispartition ;
2004-07-12 22:41:13 +02:00
Oid tablespace ;
2008-12-19 15:39:58 +01:00
char * reloptions ;
2010-01-29 00:21:13 +01:00
char * reloftype ;
2010-12-29 12:48:53 +01:00
char relpersistence ;
2013-11-08 18:30:43 +01:00
char relreplident ;
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
char * relam ;
2000-04-12 19:17:23 +02:00
} tableinfo ;
2016-11-03 17:00:00 +01:00
bool show_column_details = false ;
1999-11-05 00:14:30 +01:00
2012-05-01 22:03:45 +02:00
myopt . default_footer = false ;
2005-10-27 15:34:47 +02:00
/* This output looks confusing in expanded mode. */
myopt . expanded = false ;
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
initPQExpBuffer ( & title ) ;
2002-12-21 02:07:07 +01:00
initPQExpBuffer ( & tmpbuf ) ;
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
/* Get general table info */
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
if ( pset . sversion > = 120000 )
{
printfPQExpBuffer ( & buf ,
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
" c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
2019-03-26 15:14:34 +01:00
" false AS relhasoids, c.relispartition, %s, c.reltablespace, "
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
" c.relpersistence, c.relreplident, am.amname \n "
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
" FROM pg_catalog.pg_class c \n "
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
" LEFT JOIN pg_catalog.pg_am am ON (c.relam = am.oid) \n "
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
" WHERE c.oid = '%s'; " ,
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
2019-03-26 15:14:34 +01:00
else if ( pset . sversion > = 100000 )
{
printfPQExpBuffer ( & buf ,
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
" c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
" c.relhasoids, c.relispartition, %s, c.reltablespace, "
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
" c.relpersistence, c.relreplident \n "
" FROM pg_catalog.pg_class c \n "
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
" WHERE c.oid = '%s'; " ,
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
Remove WITH OIDS support, change oid catalog column visibility.
Previously tables declared WITH OIDS, including a significant fraction
of the catalog tables, stored the oid column not as a normal column,
but as part of the tuple header.
This special column was not shown by default, which was somewhat odd,
as it's often (consider e.g. pg_class.oid) one of the more important
parts of a row. Neither pg_dump nor COPY included the contents of the
oid column by default.
The fact that the oid column was not an ordinary column necessitated a
significant amount of special case code to support oid columns. That
already was painful for the existing, but upcoming work aiming to make
table storage pluggable, would have required expanding and duplicating
that "specialness" significantly.
WITH OIDS has been deprecated since 2005 (commit ff02d0a05280e0).
Remove it.
Removing includes:
- CREATE TABLE and ALTER TABLE syntax for declaring the table to be
WITH OIDS has been removed (WITH (oids[ = true]) will error out)
- pg_dump does not support dumping tables declared WITH OIDS and will
issue a warning when dumping one (and ignore the oid column).
- restoring an pg_dump archive with pg_restore will warn when
restoring a table with oid contents (and ignore the oid column)
- COPY will refuse to load binary dump that includes oids.
- pg_upgrade will error out when encountering tables declared WITH
OIDS, they have to be altered to remove the oid column first.
- Functionality to access the oid of the last inserted row (like
plpgsql's RESULT_OID, spi's SPI_lastoid, ...) has been removed.
The syntax for declaring a table WITHOUT OIDS (or WITH (oids = false)
for CREATE TABLE) is still supported. While that requires a bit of
support code, it seems unnecessary to break applications / dumps that
do not use oids, and are explicit about not using them.
The biggest user of WITH OID columns was postgres' catalog. This
commit changes all 'magic' oid columns to be columns that are normally
declared and stored. To reduce unnecessary query breakage all the
newly added columns are still named 'oid', even if a table's column
naming scheme would indicate 'reloid' or such. This obviously
requires adapting a lot code, mostly replacing oid access via
HeapTupleGetOid() with access to the underlying Form_pg_*->oid column.
The bootstrap process now assigns oids for all oid columns in
genbki.pl that do not have an explicit value (starting at the largest
oid previously used), only oids assigned later by oids will be above
FirstBootstrapObjectId. As the oid column now is a normal column the
special bootstrap syntax for oids has been removed.
Oids are not automatically assigned during insertion anymore, all
backend code explicitly assigns oids with GetNewOidWithIndex(). For
the rare case that insertions into the catalog via SQL are called for
the new pg_nextoid() function can be used (which only works on catalog
tables).
The fact that oid columns on system tables are now normal columns
means that they will be included in the set of columns expanded
by * (i.e. SELECT * FROM pg_class will now include the table's oid,
previously it did not). It'd not technically be hard to hide oid
column by default, but that'd mean confusing behavior would either
have to be carried forward forever, or it'd cause breakage down the
line.
While it's not unlikely that further adjustments are needed, the
scope/invasiveness of the patch makes it worthwhile to get merge this
now. It's painful to maintain externally, too complicated to commit
after the code code freeze, and a dependency of a number of other
patches.
Catversion bump, for obvious reasons.
Author: Andres Freund, with contributions by John Naylor
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
2018-11-21 00:36:57 +01:00
else if ( pset . sversion > = 90500 )
2013-11-08 18:30:43 +01:00
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
" c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
2019-03-26 15:14:34 +01:00
" c.relhasoids, false as relispartition, %s, c.reltablespace, "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
" c.relpersistence, c.relreplident \n "
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
" WHERE c.oid = '%s'; " ,
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
else if ( pset . sversion > = 90400 )
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
2015-10-05 03:05:08 +02:00
" c.relhastriggers, false, false, c.relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, %s, c.reltablespace, "
2013-11-08 18:30:43 +01:00
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
" c.relpersistence, c.relreplident \n "
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
2013-11-08 18:30:43 +01:00
" WHERE c.oid = '%s'; " ,
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
else if ( pset . sversion > = 90100 )
2010-12-29 12:48:53 +01:00
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
2015-10-05 03:05:08 +02:00
" c.relhastriggers, false, false, c.relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, %s, c.reltablespace, "
2010-12-29 12:48:53 +01:00
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
" c.relpersistence \n "
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
2011-07-06 16:11:20 +02:00
" WHERE c.oid = '%s'; " ,
2010-12-29 12:48:53 +01:00
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
else if ( pset . sversion > = 90000 )
2009-12-07 06:22:23 +01:00
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
2015-10-05 03:05:08 +02:00
" c.relhastriggers, false, false, c.relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, %s, c.reltablespace, "
2010-03-11 22:29:32 +01:00
" CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END \n "
2009-12-07 06:22:23 +01:00
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
2011-07-06 16:11:20 +02:00
" WHERE c.oid = '%s'; " ,
2009-12-07 06:22:23 +01:00
( verbose ?
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
oid ) ;
}
else if ( pset . sversion > = 80400 )
2009-02-11 20:12:04 +01:00
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
2015-10-05 03:05:08 +02:00
" c.relhastriggers, false, false, c.relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, %s, c.reltablespace \n "
2009-02-11 20:12:04 +01:00
" FROM pg_catalog.pg_class c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid) \n "
2011-07-06 16:11:20 +02:00
" WHERE c.oid = '%s'; " ,
2009-02-11 20:12:04 +01:00
( verbose ?
2009-06-11 16:49:15 +02:00
" pg_catalog.array_to_string(c.reloptions || "
" array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ') \n "
: " '' " ) ,
2009-02-11 20:12:04 +01:00
oid ) ;
}
else if ( pset . sversion > = 80200 )
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT relchecks, relkind, relhasindex, relhasrules, "
2015-10-05 03:05:08 +02:00
" reltriggers <> 0, false, false, relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, %s, reltablespace \n "
2011-07-06 16:11:20 +02:00
" FROM pg_catalog.pg_class WHERE oid = '%s'; " ,
2009-02-11 20:12:04 +01:00
( verbose ?
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.array_to_string(reloptions, E', ') " : " '' " ) ,
2009-02-11 20:12:04 +01:00
oid ) ;
}
else if ( pset . sversion > = 80000 )
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT relchecks, relkind, relhasindex, relhasrules, "
2015-10-05 03:05:08 +02:00
" reltriggers <> 0, false, false, relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, '', reltablespace \n "
2011-07-06 16:11:20 +02:00
" FROM pg_catalog.pg_class WHERE oid = '%s'; " ,
2009-02-11 20:12:04 +01:00
oid ) ;
}
else
{
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT relchecks, relkind, relhasindex, relhasrules, "
2015-10-05 03:05:08 +02:00
" reltriggers <> 0, false, false, relhasoids, "
2019-03-26 15:14:34 +01:00
" false as relispartition, '', '' \n "
2011-07-06 16:11:20 +02:00
" FROM pg_catalog.pg_class WHERE oid = '%s'; " ,
2009-02-11 20:12:04 +01:00
oid ) ;
}
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2000-04-12 19:17:23 +02:00
if ( ! res )
2002-04-24 07:24:00 +02:00
goto error_return ;
1999-11-05 00:14:30 +01:00
/* Did we get anything? */
if ( PQntuples ( res ) = = 0 )
{
2006-08-29 17:19:51 +02:00
if ( ! pset . quiet )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any relation with OID %s. " , oid ) ;
2002-04-24 07:24:00 +02:00
goto error_return ;
1999-11-05 00:14:30 +01:00
}
2008-11-09 22:24:33 +01:00
tableinfo . checks = atoi ( PQgetvalue ( res , 0 , 0 ) ) ;
2004-04-22 19:38:16 +02:00
tableinfo . relkind = * ( PQgetvalue ( res , 0 , 1 ) ) ;
2008-11-09 22:24:33 +01:00
tableinfo . hasindex = strcmp ( PQgetvalue ( res , 0 , 2 ) , " t " ) = = 0 ;
tableinfo . hasrules = strcmp ( PQgetvalue ( res , 0 , 3 ) , " t " ) = = 0 ;
tableinfo . hastriggers = strcmp ( PQgetvalue ( res , 0 , 4 ) , " t " ) = = 0 ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
tableinfo . rowsecurity = strcmp ( PQgetvalue ( res , 0 , 5 ) , " t " ) = = 0 ;
2015-10-05 03:05:08 +02:00
tableinfo . forcerowsecurity = strcmp ( PQgetvalue ( res , 0 , 6 ) , " t " ) = = 0 ;
tableinfo . hasoids = strcmp ( PQgetvalue ( res , 0 , 7 ) , " t " ) = = 0 ;
2019-03-26 15:14:34 +01:00
tableinfo . ispartition = strcmp ( PQgetvalue ( res , 0 , 8 ) , " t " ) = = 0 ;
2009-12-07 06:22:23 +01:00
tableinfo . reloptions = ( pset . sversion > = 80200 ) ?
2019-03-26 15:14:34 +01:00
pg_strdup ( PQgetvalue ( res , 0 , 9 ) ) : NULL ;
2004-11-05 20:17:13 +01:00
tableinfo . tablespace = ( pset . sversion > = 80000 ) ?
2019-03-26 15:14:34 +01:00
atooid ( PQgetvalue ( res , 0 , 10 ) ) : 0 ;
2012-09-03 17:24:31 +02:00
tableinfo . reloftype = ( pset . sversion > = 90000 & &
2019-03-26 15:14:34 +01:00
strcmp ( PQgetvalue ( res , 0 , 11 ) , " " ) ! = 0 ) ?
pg_strdup ( PQgetvalue ( res , 0 , 11 ) ) : NULL ;
2012-09-03 17:24:31 +02:00
tableinfo . relpersistence = ( pset . sversion > = 90100 ) ?
2019-03-26 15:14:34 +01:00
* ( PQgetvalue ( res , 0 , 12 ) ) : 0 ;
2013-11-08 18:30:43 +01:00
tableinfo . relreplident = ( pset . sversion > = 90400 ) ?
2019-03-26 15:14:34 +01:00
* ( PQgetvalue ( res , 0 , 13 ) ) : ' d ' ;
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
if ( pset . sversion > = 120000 )
2019-03-26 15:14:34 +01:00
tableinfo . relam = PQgetisnull ( res , 0 , 14 ) ?
( char * ) NULL : pg_strdup ( PQgetvalue ( res , 0 , 14 ) ) ;
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
else
tableinfo . relam = NULL ;
2000-04-12 19:17:23 +02:00
PQclear ( res ) ;
2008-11-03 20:08:56 +01:00
res = NULL ;
2009-06-11 16:49:15 +02:00
2008-07-15 05:16:03 +02:00
/*
2017-09-25 17:59:46 +02:00
* If it ' s a sequence , deal with it here separately .
2008-07-15 05:16:03 +02:00
*/
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_SEQUENCE )
2008-07-15 05:16:03 +02:00
{
2017-09-25 17:59:46 +02:00
PGresult * result = NULL ;
printQueryOpt myopt = pset . popt ;
char * footers [ 2 ] = { NULL , NULL } ;
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 ,
2017-10-31 18:40:23 +01:00
" SELECT 'bigint' AS \" %s \" , \n "
2017-09-25 17:59:46 +02:00
" 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 ) ) ;
}
2009-06-11 16:49:15 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2009-07-20 05:46:45 +02:00
if ( ! res )
2008-07-15 05:16:03 +02:00
goto error_return ;
2009-06-11 16:49:15 +02:00
2017-09-25 17:59:46 +02:00
/* Footer information about a sequence */
/* 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 "
" \n FROM pg_catalog.pg_class c "
" \n INNER JOIN pg_catalog.pg_depend d ON c.oid=d.refobjid "
" \n INNER JOIN pg_catalog.pg_namespace n ON n.oid=c.relnamespace "
" \n INNER JOIN pg_catalog.pg_attribute a ON ( "
" \n a.attrelid=c.oid AND "
" \n a.attnum=d.refobjsubid) "
" \n WHERE 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 ) ;
result = PSQLexec ( buf . data ) ;
/*
* If we get no rows back , don ' t show anything ( obviously ) . We should
* never get more than one row back , but if we do , just ignore it and
* don ' t print anything .
*/
if ( ! result )
goto error_return ;
else if ( PQntuples ( result ) = = 1 )
{
switch ( PQgetvalue ( result , 0 , 1 ) [ 0 ] )
{
case ' a ' :
footers [ 0 ] = psprintf ( _ ( " Owned by: %s " ) ,
PQgetvalue ( result , 0 , 0 ) ) ;
break ;
case ' i ' :
footers [ 0 ] = psprintf ( _ ( " Sequence for identity column: %s " ) ,
PQgetvalue ( result , 0 , 0 ) ) ;
break ;
}
}
PQclear ( result ) ;
printfPQExpBuffer ( & title , _ ( " Sequence \" %s.%s \" " ) ,
schemaname , relationname ) ;
2009-06-11 16:49:15 +02:00
2017-09-25 17:59:46 +02:00
myopt . footers = footers ;
myopt . topt . default_footer = false ;
myopt . title = title . data ;
myopt . translate_header = true ;
2009-06-11 16:49:15 +02:00
2017-09-25 17:59:46 +02:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
if ( footers [ 0 ] )
free ( footers [ 0 ] ) ;
retval = true ;
goto error_return ; /* not an error, just return early */
2008-07-15 05:16:03 +02:00
}
1999-11-05 00:14:30 +01:00
2018-07-19 20:53:41 +02:00
/* Identify whether we should print collation, nullable, default vals */
if ( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_VIEW | |
tableinfo . relkind = = RELKIND_MATVIEW | |
tableinfo . relkind = = RELKIND_FOREIGN_TABLE | |
tableinfo . relkind = = RELKIND_COMPOSITE_TYPE | |
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
show_column_details = true ;
2011-08-05 19:24:03 +02:00
/*
2018-07-19 20:53:41 +02:00
* Get per - column info
2011-08-05 19:24:03 +02:00
*
2018-07-19 20:53:41 +02:00
* Since the set of query columns we need varies depending on relkind and
* server version , we compute all the column numbers on - the - fly . Column
* number variables for columns not fetched are left as - 1 ; this avoids
* duplicative test logic below .
2011-08-05 19:24:03 +02:00
*/
2018-07-19 20:53:41 +02:00
cols = 0 ;
printfPQExpBuffer ( & buf , " SELECT a.attname " ) ;
attname_col = cols + + ;
appendPQExpBufferStr ( & buf , " , \n pg_catalog.format_type(a.atttypid, a.atttypmod) " ) ;
atttype_col = cols + + ;
if ( show_column_details )
{
2019-03-30 08:13:09 +01:00
/* use "pretty" mode for expression to avoid excessive parentheses */
2018-07-19 20:53:41 +02:00
appendPQExpBufferStr ( & buf ,
2019-03-30 08:13:09 +01:00
" , \n (SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid, true) for 128) "
2018-07-19 20:53:41 +02:00
" \n FROM pg_catalog.pg_attrdef d "
" \n WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) "
" , \n a.attnotnull " ) ;
attrdef_col = cols + + ;
attnotnull_col = cols + + ;
if ( pset . sversion > = 90100 )
appendPQExpBufferStr ( & buf , " , \n (SELECT c.collname FROM pg_catalog.pg_collation c, pg_catalog.pg_type t \n "
" WHERE c.oid = a.attcollation AND t.oid = a.atttypid AND a.attcollation <> t.typcollation) AS attcollation " ) ;
else
appendPQExpBufferStr ( & buf , " , \n NULL AS attcollation " ) ;
attcoll_col = cols + + ;
if ( pset . sversion > = 100000 )
appendPQExpBufferStr ( & buf , " , \n a.attidentity " ) ;
else
appendPQExpBufferStr ( & buf , " , \n ''::pg_catalog.char AS attidentity " ) ;
attidentity_col = cols + + ;
2019-03-30 08:13:09 +01:00
if ( pset . sversion > = 120000 )
appendPQExpBufferStr ( & buf , " , \n a.attgenerated " ) ;
else
appendPQExpBufferStr ( & buf , " , \n ''::pg_catalog.char AS attgenerated " ) ;
attgenerated_col = cols + + ;
2018-07-19 20:53:41 +02:00
}
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
if ( tableinfo . relkind = = RELKIND_INDEX | |
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX )
2018-07-19 20:53:41 +02:00
{
if ( pset . sversion > = 110000 )
{
appendPQExpBuffer ( & buf , " , \n CASE WHEN a.attnum <= (SELECT i.indnkeyatts FROM pg_catalog.pg_index i WHERE i.indexrelid = '%s') THEN '%s' ELSE '%s' END AS is_key " ,
oid ,
gettext_noop ( " yes " ) ,
gettext_noop ( " no " ) ) ;
isindexkey_col = cols + + ;
}
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n pg_catalog.pg_get_indexdef(a.attrelid, a.attnum, TRUE) AS indexdef " ) ;
2018-07-19 20:53:41 +02:00
indexdef_col = cols + + ;
}
/* FDW options for foreign table column, only for 9.2 or later */
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_FOREIGN_TABLE & & pset . sversion > = 90200 )
2018-07-19 20:53:41 +02:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n CASE WHEN attfdwoptions IS NULL THEN '' ELSE "
2017-07-27 01:35:35 +02:00
" '(' || pg_catalog.array_to_string(ARRAY(SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM "
" pg_catalog.pg_options_to_table(attfdwoptions)), ', ') || ')' END AS attfdwoptions " ) ;
2018-07-19 20:53:41 +02:00
fdwopts_col = cols + + ;
}
2002-08-10 05:56:24 +02:00
if ( verbose )
2011-07-26 15:52:31 +02:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n a.attstorage " ) ;
2018-07-19 20:53:41 +02:00
attstorage_col = cols + + ;
/* stats target, if relevant to relkind */
if ( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_INDEX | |
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX | |
tableinfo . relkind = = RELKIND_MATVIEW | |
tableinfo . relkind = = RELKIND_FOREIGN_TABLE | |
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
{
appendPQExpBufferStr ( & buf , " , \n CASE WHEN a.attstattarget=-1 THEN NULL ELSE a.attstattarget END AS attstattarget " ) ;
attstattarget_col = cols + + ;
}
2012-06-10 21:20:04 +02:00
2011-07-26 15:52:31 +02:00
/*
* In 9.0 + , we have column comments for : relations , views , composite
2018-01-11 14:31:11 +01:00
* types , and foreign tables ( cf . CommentObject ( ) in comment . c ) .
2011-07-26 15:52:31 +02:00
*/
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_VIEW | |
tableinfo . relkind = = RELKIND_MATVIEW | |
tableinfo . relkind = = RELKIND_FOREIGN_TABLE | |
tableinfo . relkind = = RELKIND_COMPOSITE_TYPE | |
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
2018-07-19 20:53:41 +02:00
{
appendPQExpBufferStr ( & buf , " , \n pg_catalog.col_description(a.attrelid, a.attnum) " ) ;
attdescr_col = cols + + ;
}
2011-07-26 15:52:31 +02:00
}
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_attribute a " ) ;
2002-08-10 05:56:24 +02:00
appendPQExpBuffer ( & buf , " \n WHERE a.attrelid = '%s' AND a.attnum > 0 AND NOT a.attisdropped " , oid ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n ORDER BY a.attnum; " ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
if ( ! res )
2002-04-24 07:24:00 +02:00
goto error_return ;
2002-12-21 02:07:07 +01:00
numrows = PQntuples ( res ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
2008-05-13 02:14:11 +02:00
/* Make title */
switch ( tableinfo . relkind )
{
2017-03-10 02:42:42 +01:00
case RELKIND_RELATION :
2010-12-29 12:48:53 +01:00
if ( tableinfo . relpersistence = = ' u ' )
2011-02-23 01:54:32 +01:00
printfPQExpBuffer ( & title , _ ( " Unlogged table \" %s.%s \" " ) ,
2010-12-29 12:48:53 +01:00
schemaname , relationname ) ;
else
printfPQExpBuffer ( & title , _ ( " Table \" %s.%s \" " ) ,
schemaname , relationname ) ;
2008-05-13 02:14:11 +02:00
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_VIEW :
2008-05-13 02:14:11 +02:00
printfPQExpBuffer ( & title , _ ( " View \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_MATVIEW :
2013-03-04 01:23:31 +01:00
if ( tableinfo . relpersistence = = ' u ' )
printfPQExpBuffer ( & title , _ ( " Unlogged materialized view \" %s.%s \" " ) ,
schemaname , relationname ) ;
else
printfPQExpBuffer ( & title , _ ( " Materialized view \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_INDEX :
2010-12-29 12:48:53 +01:00
if ( tableinfo . relpersistence = = ' u ' )
2011-02-23 01:54:32 +01:00
printfPQExpBuffer ( & title , _ ( " Unlogged index \" %s.%s \" " ) ,
2010-12-29 12:48:53 +01:00
schemaname , relationname ) ;
else
printfPQExpBuffer ( & title , _ ( " Index \" %s.%s \" " ) ,
schemaname , relationname ) ;
2008-05-13 02:14:11 +02:00
break ;
2018-11-19 20:54:26 +01:00
case RELKIND_PARTITIONED_INDEX :
if ( tableinfo . relpersistence = = ' u ' )
printfPQExpBuffer ( & title , _ ( " Unlogged partitioned index \" %s.%s \" " ) ,
schemaname , relationname ) ;
else
printfPQExpBuffer ( & title , _ ( " Partitioned index \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2008-05-13 02:14:11 +02:00
case ' s ' :
/* not used as of 8.2, but keep it for backwards compatibility */
printfPQExpBuffer ( & title , _ ( " Special relation \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_TOASTVALUE :
2008-05-13 02:14:11 +02:00
printfPQExpBuffer ( & title , _ ( " TOAST table \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_COMPOSITE_TYPE :
2008-05-13 02:14:11 +02:00
printfPQExpBuffer ( & title , _ ( " Composite type \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_FOREIGN_TABLE :
2011-01-02 05:48:11 +01:00
printfPQExpBuffer ( & title , _ ( " Foreign table \" %s.%s \" " ) ,
schemaname , relationname ) ;
break ;
2017-03-10 02:42:42 +01:00
case RELKIND_PARTITIONED_TABLE :
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
if ( tableinfo . relpersistence = = ' u ' )
2018-11-19 20:54:26 +01:00
printfPQExpBuffer ( & title , _ ( " Unlogged partitioned table \" %s.%s \" " ) ,
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
schemaname , relationname ) ;
else
2018-11-19 20:54:26 +01:00
printfPQExpBuffer ( & title , _ ( " Partitioned table \" %s.%s \" " ) ,
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
schemaname , relationname ) ;
break ;
2008-05-13 02:14:11 +02:00
default :
/* untranslated unknown relkind */
printfPQExpBuffer ( & title , " ?%c? \" %s.%s \" " ,
tableinfo . relkind , schemaname , relationname ) ;
break ;
}
2018-07-19 20:53:41 +02:00
/* Fill headers[] with the names of the columns we will output */
cols = 0 ;
headers [ cols + + ] = gettext_noop ( " Column " ) ;
headers [ cols + + ] = gettext_noop ( " Type " ) ;
if ( show_column_details )
2008-05-13 00:59:58 +02:00
{
2016-11-03 17:00:00 +01:00
headers [ cols + + ] = gettext_noop ( " Collation " ) ;
headers [ cols + + ] = gettext_noop ( " Nullable " ) ;
headers [ cols + + ] = gettext_noop ( " Default " ) ;
2008-05-13 00:59:58 +02:00
}
2018-07-19 20:53:41 +02:00
if ( isindexkey_col > = 0 )
headers [ cols + + ] = gettext_noop ( " Key? " ) ;
if ( indexdef_col > = 0 )
2009-07-06 19:01:42 +02:00
headers [ cols + + ] = gettext_noop ( " Definition " ) ;
2018-07-19 20:53:41 +02:00
if ( fdwopts_col > = 0 )
2017-06-13 20:38:35 +02:00
headers [ cols + + ] = gettext_noop ( " FDW options " ) ;
2018-07-19 20:53:41 +02:00
if ( attstorage_col > = 0 )
2008-07-15 00:51:48 +02:00
headers [ cols + + ] = gettext_noop ( " Storage " ) ;
2018-07-19 20:53:41 +02:00
if ( attstattarget_col > = 0 )
headers [ cols + + ] = gettext_noop ( " Stats target " ) ;
if ( attdescr_col > = 0 )
headers [ cols + + ] = gettext_noop ( " Description " ) ;
Assert ( cols < = lengthof ( headers ) ) ;
2009-06-11 16:49:15 +02:00
2008-05-13 00:59:58 +02:00
printTableInit ( & cont , & myopt , title . data , cols , numrows ) ;
2008-11-03 20:08:56 +01:00
printTableInitialized = true ;
2008-05-13 00:59:58 +02:00
for ( i = 0 ; i < cols ; i + + )
printTableAddHeader ( & cont , headers [ i ] , true , ' l ' ) ;
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
/* Generate table cells to be printed */
2002-12-21 02:07:07 +01:00
for ( i = 0 ; i < numrows ; i + + )
1999-11-05 00:14:30 +01:00
{
2008-05-13 00:59:58 +02:00
/* Column */
2018-07-19 20:53:41 +02:00
printTableAddCell ( & cont , PQgetvalue ( res , i , attname_col ) , false , false ) ;
2003-07-27 05:32:26 +02:00
1999-11-05 00:14:30 +01:00
/* Type */
2018-07-19 20:53:41 +02:00
printTableAddCell ( & cont , PQgetvalue ( res , i , atttype_col ) , false , false ) ;
2008-11-03 20:08:56 +01:00
2016-11-03 17:00:00 +01:00
/* Collation, Nullable, Default */
if ( show_column_details )
2000-04-12 19:17:23 +02:00
{
2017-05-17 22:31:56 +02:00
char * identity ;
2019-03-30 08:13:09 +01:00
char * generated ;
2017-05-17 22:31:56 +02:00
char * default_str = " " ;
2017-04-06 14:33:16 +02:00
2018-07-19 20:53:41 +02:00
printTableAddCell ( & cont , PQgetvalue ( res , i , attcoll_col ) , false , false ) ;
2011-02-08 22:04:18 +01:00
2018-07-19 20:53:41 +02:00
printTableAddCell ( & cont ,
strcmp ( PQgetvalue ( res , i , attnotnull_col ) , " t " ) = = 0 ? " not null " : " " ,
false , false ) ;
2011-02-08 22:04:18 +01:00
2018-07-19 20:53:41 +02:00
identity = PQgetvalue ( res , i , attidentity_col ) ;
2019-03-30 08:13:09 +01:00
generated = PQgetvalue ( res , i , attgenerated_col ) ;
2017-04-06 14:33:16 +02:00
2019-03-30 08:13:09 +01:00
if ( identity [ 0 ] = = ATTRIBUTE_IDENTITY_ALWAYS )
2017-04-06 14:33:16 +02:00
default_str = " generated always as identity " ;
else if ( identity [ 0 ] = = ATTRIBUTE_IDENTITY_BY_DEFAULT )
default_str = " generated by default as identity " ;
2019-03-30 08:13:09 +01:00
else if ( generated [ 0 ] = = ATTRIBUTE_GENERATED_STORED )
default_str = psprintf ( " generated always as (%s) stored " , PQgetvalue ( res , i , attrdef_col ) ) ;
else
/* (note: above we cut off the 'default' string at 128) */
default_str = PQgetvalue ( res , i , attrdef_col ) ;
2017-04-06 14:33:16 +02:00
2019-03-30 08:13:09 +01:00
printTableAddCell ( & cont , default_str , false , generated [ 0 ] ? true : false ) ;
2000-04-12 19:17:23 +02:00
}
2018-07-19 20:53:41 +02:00
/* 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 ) ;
2009-07-06 19:01:42 +02:00
2018-07-19 20:53:41 +02:00
/* FDW options for foreign table columns */
if ( fdwopts_col > = 0 )
printTableAddCell ( & cont , PQgetvalue ( res , i , fdwopts_col ) , false , false ) ;
2011-08-05 19:24:03 +02:00
2008-07-15 00:51:48 +02:00
/* Storage and Description */
2018-07-19 20:53:41 +02:00
if ( attstorage_col > = 0 )
2008-07-15 00:51:48 +02:00
{
2018-07-19 20:53:41 +02:00
char * storage = PQgetvalue ( res , i , attstorage_col ) ;
2008-11-03 20:08:56 +01:00
2008-07-15 01:13:04 +02:00
/* these strings are literal in our syntax, so not translated. */
2009-06-11 16:49:15 +02:00
printTableAddCell ( & cont , ( storage [ 0 ] = = ' p ' ? " plain " :
( storage [ 0 ] = = ' m ' ? " main " :
( storage [ 0 ] = = ' x ' ? " extended " :
( storage [ 0 ] = = ' e ' ? " external " :
2008-07-15 00:51:48 +02:00
" ??? " ) ) ) ) ,
2010-03-01 21:55:45 +01:00
false , false ) ;
2018-07-19 20:53:41 +02:00
}
2011-11-05 13:02:48 +01:00
2018-07-19 20:53:41 +02:00
/* Statistics target, if the relkind supports this feature */
if ( attstattarget_col > = 0 )
printTableAddCell ( & cont , PQgetvalue ( res , i , attstattarget_col ) ,
false , false ) ;
2011-11-05 13:02:48 +01:00
2018-07-19 20:53:41 +02:00
/* Column comments, if the relkind supports this feature */
if ( attdescr_col > = 0 )
printTableAddCell ( & cont , PQgetvalue ( res , i , attdescr_col ) ,
false , false ) ;
1999-11-05 00:14:30 +01:00
}
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
/* Make footers */
2019-07-25 00:14:26 +02:00
if ( tableinfo . ispartition )
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
{
2019-07-25 00:14:26 +02:00
/* Footer information for a partition child table */
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
PGresult * result ;
2017-07-27 01:35:35 +02:00
printfPQExpBuffer ( & buf ,
" SELECT inhparent::pg_catalog.regclass, \n "
2019-07-25 00:14:26 +02:00
" pg_catalog.pg_get_expr(c.relpartbound, c.oid) " ) ;
2017-05-13 18:04:53 +02:00
/* If verbose, also request the partition constraint definition */
if ( verbose )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf ,
2019-07-25 00:14:26 +02:00
" , \n pg_catalog.pg_get_partition_constraintdef(c.oid) " ) ;
2017-07-27 01:35:35 +02:00
appendPQExpBuffer ( & buf ,
" \n FROM pg_catalog.pg_class c "
" JOIN pg_catalog.pg_inherits i "
" ON c.oid = inhrelid "
2019-07-25 00:14:26 +02:00
" \n WHERE c.oid = '%s'; " , oid ) ;
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
result = PSQLexec ( buf . data ) ;
if ( ! result )
goto error_return ;
if ( PQntuples ( result ) > 0 )
{
2019-07-25 00:14:26 +02:00
char * parent_name = PQgetvalue ( result , 0 , 0 ) ;
char * partdef = PQgetvalue ( result , 0 , 1 ) ;
2017-05-13 18:04:53 +02:00
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
printfPQExpBuffer ( & tmpbuf , _ ( " Partition of: %s %s " ) , parent_name ,
2017-05-17 22:31:56 +02:00
partdef ) ;
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
printTableAddFooter ( & cont , tmpbuf . data ) ;
2017-05-13 18:04:53 +02:00
2017-09-29 21:59:11 +02:00
if ( verbose )
{
2019-07-25 00:14:26 +02:00
char * partconstraintdef = NULL ;
if ( ! PQgetisnull ( result , 0 , 2 ) )
partconstraintdef = PQgetvalue ( result , 0 , 2 ) ;
2017-09-29 21:59:11 +02:00
/* If there isn't any constraint, show that explicitly */
if ( partconstraintdef = = NULL | | partconstraintdef [ 0 ] = = ' \0 ' )
printfPQExpBuffer ( & tmpbuf , _ ( " No partition constraint " ) ) ;
else
printfPQExpBuffer ( & tmpbuf , _ ( " Partition constraint: %s " ) ,
partconstraintdef ) ;
printTableAddFooter ( & cont , tmpbuf . data ) ;
}
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
}
2019-07-25 00:14:26 +02:00
PQclear ( result ) ;
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
}
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
{
2019-07-25 00:14:26 +02:00
/* Footer information for a partitioned table (partitioning parent) */
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
PGresult * result ;
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT pg_catalog.pg_get_partkeydef('%s'::pg_catalog.oid); " ,
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
oid ) ;
result = PSQLexec ( buf . data ) ;
2019-07-25 00:14:26 +02:00
if ( ! result )
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
goto error_return ;
2019-07-25 00:14:26 +02:00
if ( PQntuples ( result ) = = 1 )
{
char * partkeydef = PQgetvalue ( result , 0 , 0 ) ;
printfPQExpBuffer ( & tmpbuf , _ ( " Partition key: %s " ) , partkeydef ) ;
printTableAddFooter ( & cont , tmpbuf . data ) ;
}
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
PQclear ( result ) ;
}
2019-07-23 21:25:56 +02:00
if ( tableinfo . relkind = = RELKIND_TOASTVALUE )
{
/* For a TOAST table, print name of owning table */
PGresult * result ;
printfPQExpBuffer ( & buf ,
" SELECT n.nspname, c.relname \n "
" FROM pg_catalog.pg_class c "
" JOIN pg_catalog.pg_namespace n "
" ON n.oid = c.relnamespace \n "
" WHERE reltoastrelid = '%s'; " , oid ) ;
result = PSQLexec ( buf . data ) ;
if ( ! result )
goto error_return ;
if ( PQntuples ( result ) = = 1 )
{
char * schemaname = PQgetvalue ( result , 0 , 0 ) ;
char * relname = PQgetvalue ( result , 0 , 1 ) ;
printfPQExpBuffer ( & tmpbuf , _ ( " Owning table: \" %s.%s \" " ) ,
schemaname , relname ) ;
printTableAddFooter ( & cont , tmpbuf . data ) ;
}
PQclear ( result ) ;
}
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
if ( tableinfo . relkind = = RELKIND_INDEX | |
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX )
2000-04-12 19:17:23 +02:00
{
2001-08-06 00:13:46 +02:00
/* Footer information about an index */
2000-04-12 19:17:23 +02:00
PGresult * result ;
2002-09-04 22:31:48 +02:00
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT i.indisunique, i.indisprimary, i.indisclustered, " ) ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion > = 80200 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " i.indisvalid, \n " ) ;
2008-07-03 05:37:17 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " true AS indisvalid, \n " ) ;
2010-02-17 05:19:41 +01:00
if ( pset . sversion > = 90000 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" (NOT i.indimmediate) AND "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
2013-11-18 17:29:01 +01:00
" WHERE conrelid = i.indrelid AND "
" conindid = i.indexrelid AND "
" contype IN ('p','u','x') AND "
" condeferrable) AS condeferrable, \n "
" (NOT i.indimmediate) AND "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" EXISTS (SELECT 1 FROM pg_catalog.pg_constraint "
2013-11-18 17:29:01 +01:00
" WHERE conrelid = i.indrelid AND "
" conindid = i.indexrelid AND "
" contype IN ('p','u','x') AND "
" condeferred) AS condeferred, \n " ) ;
2009-07-29 22:56:21 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" false AS condeferrable, false AS condeferred, \n " ) ;
2013-11-08 18:30:43 +01:00
if ( pset . sversion > = 90400 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " i.indisreplident, \n " ) ;
2013-11-08 18:30:43 +01:00
else
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " false AS indisreplident, \n " ) ;
2013-11-08 18:30:43 +01:00
2009-07-29 22:56:21 +02:00
appendPQExpBuffer ( & buf , " a.amname, c2.relname, "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_expr(i.indpred, i.indrelid, true) \n "
2002-08-10 05:56:24 +02:00
" FROM pg_catalog.pg_index i, pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_am a \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHERE i.indexrelid = c.oid AND c.oid = '%s' AND c.relam = a.oid \n "
2011-07-06 16:11:20 +02:00
" AND i.indrelid = c2.oid; " ,
2002-08-10 05:56:24 +02:00
oid ) ;
2002-04-24 07:24:00 +02:00
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
if ( ! result )
goto error_return ;
else if ( PQntuples ( result ) ! = 1 )
{
PQclear ( result ) ;
goto error_return ;
}
2000-04-12 19:17:23 +02:00
else
{
2001-10-25 07:50:21 +02:00
char * indisunique = PQgetvalue ( result , 0 , 0 ) ;
char * indisprimary = PQgetvalue ( result , 0 , 1 ) ;
2004-04-06 06:05:17 +02:00
char * indisclustered = PQgetvalue ( result , 0 , 2 ) ;
2006-08-25 06:06:58 +02:00
char * indisvalid = PQgetvalue ( result , 0 , 3 ) ;
2009-07-29 22:56:21 +02:00
char * deferrable = PQgetvalue ( result , 0 , 4 ) ;
char * deferred = PQgetvalue ( result , 0 , 5 ) ;
2013-11-14 16:27:24 +01:00
char * indisreplident = PQgetvalue ( result , 0 , 6 ) ;
2013-11-08 18:30:43 +01:00
char * indamname = PQgetvalue ( result , 0 , 7 ) ;
char * indtable = PQgetvalue ( result , 0 , 8 ) ;
char * indpred = PQgetvalue ( result , 0 , 9 ) ;
2001-08-06 00:13:46 +02:00
2002-04-24 08:17:04 +02:00
if ( strcmp ( indisprimary , " t " ) = = 0 )
2004-10-12 23:54:45 +02:00
printfPQExpBuffer ( & tmpbuf , _ ( " primary key, " ) ) ;
2002-04-24 08:17:04 +02:00
else if ( strcmp ( indisunique , " t " ) = = 0 )
2004-10-12 23:54:45 +02:00
printfPQExpBuffer ( & tmpbuf , _ ( " unique, " ) ) ;
2002-04-24 08:17:04 +02:00
else
resetPQExpBuffer ( & tmpbuf ) ;
appendPQExpBuffer ( & tmpbuf , " %s, " , indamname ) ;
2002-08-10 05:56:24 +02:00
/* we assume here that index and table are in same schema */
appendPQExpBuffer ( & tmpbuf , _ ( " for table \" %s.%s \" " ) ,
schemaname , indtable ) ;
2002-04-24 08:17:04 +02:00
if ( strlen ( indpred ) )
2004-01-11 20:10:49 +01:00
appendPQExpBuffer ( & tmpbuf , _ ( " , predicate (%s) " ) , indpred ) ;
2002-04-24 08:17:04 +02:00
2004-04-06 06:05:17 +02:00
if ( strcmp ( indisclustered , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & tmpbuf , _ ( " , clustered " ) ) ;
2004-04-06 06:05:17 +02:00
2006-08-25 06:06:58 +02:00
if ( strcmp ( indisvalid , " t " ) ! = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & tmpbuf , _ ( " , invalid " ) ) ;
2006-08-25 06:06:58 +02:00
2009-07-29 22:56:21 +02:00
if ( strcmp ( deferrable , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & tmpbuf , _ ( " , deferrable " ) ) ;
2009-07-29 22:56:21 +02:00
if ( strcmp ( deferred , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & tmpbuf , _ ( " , initially deferred " ) ) ;
2009-07-29 22:56:21 +02:00
2013-11-14 16:27:24 +01:00
if ( strcmp ( indisreplident , " t " ) = = 0 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & tmpbuf , _ ( " , replica identity " ) ) ;
2013-11-08 18:30:43 +01:00
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , tmpbuf . data ) ;
2019-07-23 23:04:21 +02:00
/*
* If it ' s a partitioned index , we ' ll print the tablespace below
*/
if ( tableinfo . relkind = = RELKIND_INDEX )
add_tablespace_footer ( & cont , tableinfo . relkind ,
tableinfo . tablespace , true ) ;
2000-04-12 19:17:23 +02:00
}
2001-08-21 18:36:06 +02:00
PQclear ( result ) ;
2000-04-12 19:17:23 +02:00
}
2019-07-23 21:25:56 +02:00
/* If you add relkinds here, see also "Finish printing..." stanza below */
2017-03-10 02:42:42 +01:00
else if ( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_MATVIEW | |
tableinfo . relkind = = RELKIND_FOREIGN_TABLE | |
2019-07-23 21:25:56 +02:00
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE | |
2019-07-23 23:04:21 +02:00
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX | |
2019-07-23 21:25:56 +02:00
tableinfo . relkind = = RELKIND_TOASTVALUE )
1999-11-05 00:14:30 +01:00
{
2001-08-06 00:13:46 +02:00
/* Footer information about a table */
2008-05-13 00:59:58 +02:00
PGresult * result = NULL ;
int tuples = 0 ;
/* print indexes */
2002-04-24 07:24:00 +02:00
if ( tableinfo . hasindex )
2000-04-12 19:17:23 +02:00
{
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
2008-07-03 05:37:17 +02:00
" SELECT c2.relname, i.indisprimary, i.indisunique, i.indisclustered, " ) ;
2009-06-11 16:49:15 +02:00
if ( pset . sversion > = 80200 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " i.indisvalid, " ) ;
2009-06-11 16:49:15 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " true as indisvalid, " ) ;
appendPQExpBufferStr ( & buf , " pg_catalog.pg_get_indexdef(i.indexrelid, 0, true), \n " ) ;
2010-02-17 05:19:41 +01:00
if ( pset . sversion > = 90000 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_constraintdef(con.oid, true), "
2014-05-06 18:12:18 +02:00
" contype, condeferrable, condeferred " ) ;
2009-07-29 22:56:21 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" null AS constraintdef, null AS contype, "
" false AS condeferrable, false AS condeferred " ) ;
2013-11-08 18:30:43 +01:00
if ( pset . sversion > = 90400 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , i.indisreplident " ) ;
2013-11-08 18:30:43 +01:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , false AS indisreplident " ) ;
2009-06-11 16:49:15 +02:00
if ( pset . sversion > = 80000 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , c2.reltablespace " ) ;
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_class c, pg_catalog.pg_class c2, pg_catalog.pg_index i \n " ) ;
2010-03-11 22:29:32 +01:00
if ( pset . sversion > = 90000 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" LEFT JOIN pg_catalog.pg_constraint con ON (conrelid = i.indrelid AND conindid = i.indexrelid AND contype IN ('p','u','x')) \n " ) ;
2010-03-11 22:29:32 +01:00
appendPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" WHERE c.oid = '%s' AND c.oid = i.indrelid AND i.indexrelid = c2.oid \n "
2019-07-02 18:32:49 +02:00
" ORDER BY i.indisprimary DESC, c2.relname; " ,
2002-09-04 22:31:48 +02:00
oid ) ;
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
2002-04-24 07:24:00 +02:00
goto error_return ;
2000-04-12 19:17:23 +02:00
else
2008-05-13 00:59:58 +02:00
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 ) ) ;
2010-03-11 22:29:32 +01:00
/* If exclusion constraint, print the constraintdef */
if ( strcmp ( PQgetvalue ( result , i , 7 ) , " x " ) = = 0 )
{
appendPQExpBuffer ( & buf , " %s " ,
PQgetvalue ( result , i , 6 ) ) ;
}
else
{
const char * indexdef ;
const char * usingpos ;
/* Label as primary key or unique (but not both) */
if ( strcmp ( PQgetvalue ( result , i , 1 ) , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " PRIMARY KEY, " ) ;
2010-03-11 22:29:32 +01:00
else if ( strcmp ( PQgetvalue ( result , i , 2 ) , " t " ) = = 0 )
2010-08-01 03:08:29 +02:00
{
if ( strcmp ( PQgetvalue ( result , i , 7 ) , " u " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " UNIQUE CONSTRAINT, " ) ;
2010-08-01 03:08:29 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " UNIQUE, " ) ;
2010-08-01 03:08:29 +02:00
}
2010-03-11 22:29:32 +01:00
/* 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 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " DEFERRABLE " ) ;
2010-03-11 22:29:32 +01:00
if ( strcmp ( PQgetvalue ( result , i , 9 ) , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " INITIALLY DEFERRED " ) ;
2010-03-11 22:29:32 +01:00
}
/* Add these for all cases */
2008-05-13 00:59:58 +02:00
if ( strcmp ( PQgetvalue ( result , i , 3 ) , " t " ) = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " CLUSTER " ) ;
2008-05-13 00:59:58 +02:00
if ( strcmp ( PQgetvalue ( result , i , 4 ) , " t " ) ! = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " INVALID " ) ;
2008-05-13 00:59:58 +02:00
2013-11-08 18:30:43 +01:00
if ( strcmp ( PQgetvalue ( result , i , 10 ) , " t " ) = = 0 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " REPLICA IDENTITY " ) ;
2013-11-08 18:30:43 +01:00
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , buf . data ) ;
/* Print tablespace of the index on the same line */
2008-07-03 05:37:17 +02:00
if ( pset . sversion > = 80000 )
2017-03-10 02:42:42 +01:00
add_tablespace_footer ( & cont , RELKIND_INDEX ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
atooid ( PQgetvalue ( result , i , 11 ) ) ,
2008-07-03 05:37:17 +02:00
false ) ;
2008-05-13 00:59:58 +02:00
}
}
PQclear ( result ) ;
2000-04-12 19:17:23 +02:00
}
2008-05-13 00:59:58 +02:00
/* print table (and column) check constraints */
2002-04-24 07:24:00 +02:00
if ( tableinfo . checks )
2000-04-12 19:17:23 +02:00
{
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
2012-04-21 04:46:20 +02:00
" SELECT r.conname, "
2005-10-20 07:15:09 +02:00
" pg_catalog.pg_get_constraintdef(r.oid, true) \n "
2002-09-04 22:31:48 +02:00
" FROM pg_catalog.pg_constraint r \n "
2012-04-21 04:46:20 +02:00
" WHERE r.conrelid = '%s' AND r.contype = 'c' \n "
" ORDER BY 1; " ,
oid ) ;
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
2002-04-24 07:24:00 +02:00
goto error_return ;
2000-04-12 19:17:23 +02:00
else
2008-05-13 00:59:58 +02:00
tuples = PQntuples ( result ) ;
2000-04-12 19:17:23 +02:00
2008-05-13 00:59:58 +02:00
if ( tuples > 0 )
2007-03-20 00:38:32 +01:00
{
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , _ ( " Check constraints: " ) ) ;
for ( i = 0 ; i < tuples ; i + + )
{
2017-02-06 10:33:58 +01:00
/* untranslated constraint name and def */
2012-04-21 04:46:20 +02:00
printfPQExpBuffer ( & buf , " \" %s \" %s " ,
2008-05-13 00:59:58 +02:00
PQgetvalue ( result , i , 0 ) ,
2012-04-21 04:46:20 +02:00
PQgetvalue ( result , i , 1 ) ) ;
2000-04-12 19:17:23 +02:00
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
2003-06-27 18:55:23 +02:00
}
2008-05-13 00:59:58 +02:00
PQclear ( result ) ;
2000-04-12 19:17:23 +02:00
}
2018-05-14 17:43:14 +02:00
/*
* Print foreign - key constraints ( there are none if no triggers ,
* except if the table is partitioned , in which case the triggers
* appear in the partitions )
*/
if ( tableinfo . hastriggers | |
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
2002-08-17 01:01:21 +02:00
{
2019-03-26 15:14:34 +01:00
if ( pset . sversion > = 120000 & &
( tableinfo . ispartition | | tableinfo . relkind = = RELKIND_PARTITIONED_TABLE ) )
{
/*
* Put the constraints defined in this table first , followed
* by the constraints defined in ancestor partitioned tables .
*/
printfPQExpBuffer ( & buf ,
" SELECT conrelid = '%s'::pg_catalog.regclass AS sametable, \n "
" conname, \n "
" pg_catalog.pg_get_constraintdef(oid, true) AS condef, \n "
" conrelid::pg_catalog.regclass AS ontable \n "
" FROM pg_catalog.pg_constraint, \n "
" pg_catalog.pg_partition_ancestors('%s') \n "
" WHERE conrelid = relid AND contype = 'f' AND conparentid = 0 \n "
" ORDER BY sametable DESC, conname; " ,
oid , oid ) ;
}
else
{
printfPQExpBuffer ( & buf ,
" SELECT true as sametable, conname, \n "
" pg_catalog.pg_get_constraintdef(r.oid, true) as condef, \n "
" conrelid::pg_catalog.regclass AS ontable \n "
" FROM pg_catalog.pg_constraint r \n "
2019-04-03 19:38:20 +02:00
" WHERE r.conrelid = '%s' AND r.contype = 'f' \n " ,
2019-03-26 15:14:34 +01:00
oid ) ;
2019-04-03 19:38:20 +02:00
if ( pset . sversion > = 120000 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " AND conparentid = 0 \n " ) ;
appendPQExpBufferStr ( & buf , " ORDER BY conname " ) ;
2019-03-26 15:14:34 +01:00
}
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
2002-08-17 01:01:21 +02:00
goto error_return ;
else
2008-05-13 00:59:58 +02:00
tuples = PQntuples ( result ) ;
if ( tuples > 0 )
{
2019-03-26 15:14:34 +01:00
int i_sametable = PQfnumber ( result , " sametable " ) ,
i_conname = PQfnumber ( result , " conname " ) ,
i_condef = PQfnumber ( result , " condef " ) ,
i_ontable = PQfnumber ( result , " ontable " ) ;
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , _ ( " Foreign-key constraints: " ) ) ;
for ( i = 0 ; i < tuples ; i + + )
{
2019-03-26 15:14:34 +01:00
/*
* Print untranslated constraint name and definition . Use
* a " TABLE tab " prefix when the constraint is defined in
* a parent partitioned table .
*/
if ( strcmp ( PQgetvalue ( result , i , i_sametable ) , " f " ) = = 0 )
printfPQExpBuffer ( & buf , " TABLE \" %s \" CONSTRAINT \" %s \" %s " ,
PQgetvalue ( result , i , i_ontable ) ,
PQgetvalue ( result , i , i_conname ) ,
PQgetvalue ( result , i , i_condef ) ) ;
else
printfPQExpBuffer ( & buf , " \" %s \" %s " ,
PQgetvalue ( result , i , i_conname ) ,
PQgetvalue ( result , i , i_condef ) ) ;
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
}
PQclear ( result ) ;
2002-08-17 01:01:21 +02:00
}
2019-03-26 15:14:34 +01:00
/* print incoming foreign-key references */
if ( tableinfo . hastriggers | |
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE )
2008-03-30 19:50:11 +02:00
{
2019-03-26 15:14:34 +01:00
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 = 'f' 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 = 'f' \n "
" ORDER BY conname; " ,
oid ) ;
}
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
2008-03-30 19:50:11 +02:00
goto error_return ;
else
2008-05-13 00:59:58 +02:00
tuples = PQntuples ( result ) ;
2008-03-30 19:50:11 +02:00
2008-05-13 00:59:58 +02:00
if ( tuples > 0 )
2003-03-27 17:57:39 +01:00
{
2019-03-26 15:14:34 +01:00
int i_conname = PQfnumber ( result , " conname " ) ,
i_ontable = PQfnumber ( result , " ontable " ) ,
i_condef = PQfnumber ( result , " condef " ) ;
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , _ ( " Referenced by: " ) ) ;
for ( i = 0 ; i < tuples ; i + + )
2005-06-15 01:59:31 +02:00
{
2009-06-13 15:43:34 +02:00
printfPQExpBuffer ( & buf , " TABLE \" %s \" CONSTRAINT \" %s \" %s " ,
2019-03-26 15:14:34 +01:00
PQgetvalue ( result , i , i_ontable ) ,
PQgetvalue ( result , i , i_conname ) ,
PQgetvalue ( result , i , i_condef ) ) ;
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , buf . data ) ;
2005-06-15 01:59:31 +02:00
}
2003-03-27 17:57:39 +01:00
}
2008-05-13 00:59:58 +02:00
PQclear ( result ) ;
2000-04-12 19:17:23 +02:00
}
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
/* print any row-level policies */
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
if ( pset . sversion > = 90500 )
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
{
2017-07-27 01:35:35 +02:00
printfPQExpBuffer ( & buf , " SELECT pol.polname, " ) ;
2016-12-05 21:50:55 +01:00
if ( pset . sversion > = 100000 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf ,
" pol.polpermissive, \n " ) ;
2016-12-05 21:50:55 +01:00
else
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf ,
" 't' as polpermissive, \n " ) ;
2017-07-27 01:35:35 +02:00
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 ) ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
if ( ! result )
goto error_return ;
else
tuples = PQntuples ( result ) ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
/*
2015-05-24 03:35:49 +02:00
* Handle cases where RLS is enabled and there are policies , or
* there aren ' t policies , or RLS isn ' t enabled but there are
* policies
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
*/
2015-10-05 03:05:08 +02:00
if ( tableinfo . rowsecurity & & ! tableinfo . forcerowsecurity & & tuples > 0 )
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
printTableAddFooter ( & cont , _ ( " Policies: " ) ) ;
2015-10-05 03:05:08 +02:00
if ( tableinfo . rowsecurity & & tableinfo . forcerowsecurity & & tuples > 0 )
2015-12-20 17:50:04 +01:00
printTableAddFooter ( & cont , _ ( " Policies (forced row security enabled): " ) ) ;
2015-10-05 03:05:08 +02:00
if ( tableinfo . rowsecurity & & ! tableinfo . forcerowsecurity & & tuples = = 0 )
2015-12-20 17:50:04 +01:00
printTableAddFooter ( & cont , _ ( " Policies (row security enabled): (none) " ) ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
2015-10-05 03:05:08 +02:00
if ( tableinfo . rowsecurity & & tableinfo . forcerowsecurity & & tuples = = 0 )
2015-12-20 17:50:04 +01:00
printTableAddFooter ( & cont , _ ( " Policies (forced row security enabled): (none) " ) ) ;
2015-10-05 03:05:08 +02:00
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
if ( ! tableinfo . rowsecurity & & tuples > 0 )
2015-12-20 17:50:04 +01:00
printTableAddFooter ( & cont , _ ( " Policies (row security disabled): " ) ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
/* Might be an empty set - that's ok */
for ( i = 0 ; i < tuples ; i + + )
{
printfPQExpBuffer ( & buf , " POLICY \" %s \" " ,
2015-05-24 03:35:49 +02:00
PQgetvalue ( result , i , 0 ) ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
2016-12-05 21:50:55 +01:00
if ( * ( PQgetvalue ( result , i , 1 ) ) = = ' f ' )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " AS RESTRICTIVE " ) ;
2016-12-05 21:50:55 +01:00
if ( ! PQgetisnull ( result , i , 5 ) )
2014-10-03 22:31:53 +02:00
appendPQExpBuffer ( & buf , " FOR %s " ,
2016-12-05 21:50:55 +01:00
PQgetvalue ( result , i , 5 ) ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
2016-12-05 21:50:55 +01:00
if ( ! PQgetisnull ( result , i , 2 ) )
2014-10-03 22:31:53 +02:00
{
appendPQExpBuffer ( & buf , " \n TO %s " ,
2016-12-05 21:50:55 +01:00
PQgetvalue ( result , i , 2 ) ) ;
2014-10-03 22:31:53 +02:00
}
2016-12-05 21:50:55 +01:00
if ( ! PQgetisnull ( result , i , 3 ) )
2015-08-03 18:07:47 +02:00
appendPQExpBuffer ( & buf , " \n USING (%s) " ,
2016-12-05 21:50:55 +01:00
PQgetvalue ( result , i , 3 ) ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
2016-12-05 21:50:55 +01:00
if ( ! PQgetisnull ( result , i , 4 ) )
2015-08-03 18:07:47 +02:00
appendPQExpBuffer ( & buf , " \n WITH CHECK (%s) " ,
2016-12-05 21:50:55 +01:00
PQgetvalue ( result , i , 4 ) ) ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
printTableAddFooter ( & cont , buf . data ) ;
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
}
PQclear ( result ) ;
}
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
/* print any extended statistics */
if ( pset . sversion > = 100000 )
{
printfPQExpBuffer ( & buf ,
2017-04-06 19:21:40 +02:00
" SELECT oid, "
Change CREATE STATISTICS syntax
Previously, we had the WITH clause in the middle of the command, where
you'd specify both generic options as well as statistic types. Few
people liked this, so this commit changes it to remove the WITH keyword
from that clause and makes it accept statistic types only. (We
currently don't have any generic options, but if we invent in the
future, we will gain a new WITH clause, probably at the end of the
command).
Also, the column list is now specified without parens, which makes the
whole command look more similar to a SELECT command. This change will
let us expand the command to supporting expressions (not just columns
names) as well as multiple tables and their join conditions.
Tom added lots of code comments and fixed some parts of the CREATE
STATISTICS reference page, too; more changes in this area are
forthcoming. He also fixed a potential problem in the alter_generic
regression test, reducing verbosity on a cascaded drop to avoid
dependency on message ordering, as we do in other tests.
Tom also closed a security bug: we documented that table ownership was
required in order to create a statistics object on it, but didn't
actually implement it.
Implement tab-completion for statistics objects. This can stand some
more improvement.
Authors: Alvaro Herrera, with lots of cleanup by Tom Lane
Discussion: https://postgr.es/m/20170420212426.ltvgyhnefvhixm6i@alvherre.pgsql
2017-05-12 19:59:23 +02:00
" stxrelid::pg_catalog.regclass, "
2017-04-17 23:34:29 +02:00
" stxnamespace::pg_catalog.regnamespace AS nsp, "
Change CREATE STATISTICS syntax
Previously, we had the WITH clause in the middle of the command, where
you'd specify both generic options as well as statistic types. Few
people liked this, so this commit changes it to remove the WITH keyword
from that clause and makes it accept statistic types only. (We
currently don't have any generic options, but if we invent in the
future, we will gain a new WITH clause, probably at the end of the
command).
Also, the column list is now specified without parens, which makes the
whole command look more similar to a SELECT command. This change will
let us expand the command to supporting expressions (not just columns
names) as well as multiple tables and their join conditions.
Tom added lots of code comments and fixed some parts of the CREATE
STATISTICS reference page, too; more changes in this area are
forthcoming. He also fixed a potential problem in the alter_generic
regression test, reducing verbosity on a cascaded drop to avoid
dependency on message ordering, as we do in other tests.
Tom also closed a security bug: we documented that table ownership was
required in order to create a statistics object on it, but didn't
actually implement it.
Implement tab-completion for statistics objects. This can stand some
more improvement.
Authors: Alvaro Herrera, with lots of cleanup by Tom Lane
Discussion: https://postgr.es/m/20170420212426.ltvgyhnefvhixm6i@alvherre.pgsql
2017-05-12 19:59:23 +02:00
" stxname, \n "
2017-04-06 19:21:40 +02:00
" (SELECT pg_catalog.string_agg(pg_catalog.quote_ident(attname),', ') \n "
2017-04-17 23:34:29 +02:00
" FROM pg_catalog.unnest(stxkeys) s(attnum) \n "
" JOIN pg_catalog.pg_attribute a ON (stxrelid = a.attrelid AND \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" a.attnum = s.attnum AND NOT attisdropped)) AS columns, \n "
2017-10-22 22:45:16 +02:00
" 'd' = any(stxkind) AS ndist_enabled, \n "
Add support for multivariate MCV lists
Introduce a third extended statistic type, supported by the CREATE
STATISTICS command - MCV lists, a generalization of the statistic
already built and used for individual columns.
Compared to the already supported types (n-distinct coefficients and
functional dependencies), MCV lists are more complex, include column
values and allow estimation of much wider range of common clauses
(equality and inequality conditions, IS NULL, IS NOT NULL etc.).
Similarly to the other types, a new pseudo-type (pg_mcv_list) is used.
Author: Tomas Vondra
Reviewed-by: Dean Rasheed, David Rowley, Mark Dilger, Alvaro Herrera
Discussion: https://postgr.es/m/dfdac334-9cf2-2597-fb27-f0fb3753f435@2ndquadrant.com
2019-03-27 18:32:18 +01:00
" 'f' = any(stxkind) AS deps_enabled, \n "
" 'm' = any(stxkind) AS mcv_enabled \n "
2017-04-06 19:21:40 +02:00
" FROM pg_catalog.pg_statistic_ext stat "
2017-04-17 23:34:29 +02:00
" WHERE stxrelid = '%s' \n "
2017-04-06 19:21:40 +02:00
" ORDER BY 1; " ,
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
oid ) ;
result = PSQLexec ( buf . data ) ;
if ( ! result )
goto error_return ;
else
tuples = PQntuples ( result ) ;
if ( tuples > 0 )
{
2017-05-14 16:54:47 +02:00
printTableAddFooter ( & cont , _ ( " Statistics objects: " ) ) ;
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
for ( i = 0 ; i < tuples ; i + + )
{
2017-04-06 00:00:42 +02:00
bool gotone = false ;
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
printfPQExpBuffer ( & buf , " " ) ;
2017-05-14 16:54:47 +02:00
/* statistics object name (qualified with namespace) */
Change CREATE STATISTICS syntax
Previously, we had the WITH clause in the middle of the command, where
you'd specify both generic options as well as statistic types. Few
people liked this, so this commit changes it to remove the WITH keyword
from that clause and makes it accept statistic types only. (We
currently don't have any generic options, but if we invent in the
future, we will gain a new WITH clause, probably at the end of the
command).
Also, the column list is now specified without parens, which makes the
whole command look more similar to a SELECT command. This change will
let us expand the command to supporting expressions (not just columns
names) as well as multiple tables and their join conditions.
Tom added lots of code comments and fixed some parts of the CREATE
STATISTICS reference page, too; more changes in this area are
forthcoming. He also fixed a potential problem in the alter_generic
regression test, reducing verbosity on a cascaded drop to avoid
dependency on message ordering, as we do in other tests.
Tom also closed a security bug: we documented that table ownership was
required in order to create a statistics object on it, but didn't
actually implement it.
Implement tab-completion for statistics objects. This can stand some
more improvement.
Authors: Alvaro Herrera, with lots of cleanup by Tom Lane
Discussion: https://postgr.es/m/20170420212426.ltvgyhnefvhixm6i@alvherre.pgsql
2017-05-12 19:59:23 +02:00
appendPQExpBuffer ( & buf , " \" %s \" . \" %s \" ( " ,
PQgetvalue ( result , i , 2 ) ,
PQgetvalue ( result , i , 3 ) ) ;
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
/* options */
if ( strcmp ( PQgetvalue ( result , i , 5 ) , " t " ) = = 0 )
{
appendPQExpBufferStr ( & buf , " ndistinct " ) ;
2017-04-06 00:00:42 +02:00
gotone = true ;
}
if ( strcmp ( PQgetvalue ( result , i , 6 ) , " t " ) = = 0 )
{
appendPQExpBuffer ( & buf , " %sdependencies " , gotone ? " , " : " " ) ;
Add support for multivariate MCV lists
Introduce a third extended statistic type, supported by the CREATE
STATISTICS command - MCV lists, a generalization of the statistic
already built and used for individual columns.
Compared to the already supported types (n-distinct coefficients and
functional dependencies), MCV lists are more complex, include column
values and allow estimation of much wider range of common clauses
(equality and inequality conditions, IS NULL, IS NOT NULL etc.).
Similarly to the other types, a new pseudo-type (pg_mcv_list) is used.
Author: Tomas Vondra
Reviewed-by: Dean Rasheed, David Rowley, Mark Dilger, Alvaro Herrera
Discussion: https://postgr.es/m/dfdac334-9cf2-2597-fb27-f0fb3753f435@2ndquadrant.com
2019-03-27 18:32:18 +01:00
gotone = true ;
}
if ( strcmp ( PQgetvalue ( result , i , 7 ) , " t " ) = = 0 )
{
appendPQExpBuffer ( & buf , " %smcv " , gotone ? " , " : " " ) ;
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
}
Change CREATE STATISTICS syntax
Previously, we had the WITH clause in the middle of the command, where
you'd specify both generic options as well as statistic types. Few
people liked this, so this commit changes it to remove the WITH keyword
from that clause and makes it accept statistic types only. (We
currently don't have any generic options, but if we invent in the
future, we will gain a new WITH clause, probably at the end of the
command).
Also, the column list is now specified without parens, which makes the
whole command look more similar to a SELECT command. This change will
let us expand the command to supporting expressions (not just columns
names) as well as multiple tables and their join conditions.
Tom added lots of code comments and fixed some parts of the CREATE
STATISTICS reference page, too; more changes in this area are
forthcoming. He also fixed a potential problem in the alter_generic
regression test, reducing verbosity on a cascaded drop to avoid
dependency on message ordering, as we do in other tests.
Tom also closed a security bug: we documented that table ownership was
required in order to create a statistics object on it, but didn't
actually implement it.
Implement tab-completion for statistics objects. This can stand some
more improvement.
Authors: Alvaro Herrera, with lots of cleanup by Tom Lane
Discussion: https://postgr.es/m/20170420212426.ltvgyhnefvhixm6i@alvherre.pgsql
2017-05-12 19:59:23 +02:00
appendPQExpBuffer ( & buf , " ) ON %s FROM %s " ,
PQgetvalue ( result , i , 4 ) ,
PQgetvalue ( result , i , 1 ) ) ;
Implement multivariate n-distinct coefficients
Add support for explicitly declared statistic objects (CREATE
STATISTICS), allowing collection of statistics on more complex
combinations that individual table columns. Companion commands DROP
STATISTICS and ALTER STATISTICS ... OWNER TO / SET SCHEMA / RENAME are
added too. All this DDL has been designed so that more statistic types
can be added later on, such as multivariate most-common-values and
multivariate histograms between columns of a single table, leaving room
for permitting columns on multiple tables, too, as well as expressions.
This commit only adds support for collection of n-distinct coefficient
on user-specified sets of columns in a single table. This is useful to
estimate number of distinct groups in GROUP BY and DISTINCT clauses;
estimation errors there can cause over-allocation of memory in hashed
aggregates, for instance, so it's a worthwhile problem to solve. A new
special pseudo-type pg_ndistinct is used.
(num-distinct estimation was deemed sufficiently useful by itself that
this is worthwhile even if no further statistic types are added
immediately; so much so that another version of essentially the same
functionality was submitted by Kyotaro Horiguchi:
https://postgr.es/m/20150828.173334.114731693.horiguchi.kyotaro@lab.ntt.co.jp
though this commit does not use that code.)
Author: Tomas Vondra. Some code rework by Álvaro.
Reviewed-by: Dean Rasheed, David Rowley, Kyotaro Horiguchi, Jeff Janes,
Ideriha Takeshi
Discussion: https://postgr.es/m/543AFA15.4080608@fuzzy.cz
https://postgr.es/m/20170320190220.ixlaueanxegqd5gr@alvherre.pgsql
2017-03-24 18:06:10 +01:00
printTableAddFooter ( & cont , buf . data ) ;
}
}
PQclear ( result ) ;
}
2008-05-13 00:59:58 +02:00
/* print rules */
2017-03-10 02:42:42 +01:00
if ( tableinfo . hasrules & & tableinfo . relkind ! = RELKIND_MATVIEW )
2003-08-04 02:43:34 +02:00
{
2008-07-03 05:37:17 +02:00
if ( pset . sversion > = 80300 )
2003-03-27 17:57:39 +01:00
{
2008-05-13 00:59:58 +02:00
printfPQExpBuffer ( & buf ,
" SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
2008-07-03 05:37:17 +02:00
" ev_enabled \n "
2008-05-13 00:59:58 +02:00
" FROM pg_catalog.pg_rewrite r \n "
2011-07-06 16:11:20 +02:00
" WHERE r.ev_class = '%s' ORDER BY 1; " ,
2008-05-13 00:59:58 +02:00
oid ) ;
2003-03-27 17:57:39 +01:00
}
2008-05-13 00:59:58 +02:00
else
2008-03-30 19:50:11 +02:00
{
2008-05-13 00:59:58 +02:00
printfPQExpBuffer ( & buf ,
" SELECT r.rulename, trim(trailing ';' from pg_catalog.pg_get_ruledef(r.oid, true)), "
2017-10-31 18:40:23 +01:00
" 'O' AS ev_enabled \n "
2008-05-13 00:59:58 +02:00
" FROM pg_catalog.pg_rewrite r \n "
2011-07-06 16:11:20 +02:00
" WHERE r.ev_class = '%s' ORDER BY 1; " ,
2008-05-13 00:59:58 +02:00
oid ) ;
2008-03-30 19:50:11 +02:00
}
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
goto error_return ;
else
tuples = PQntuples ( result ) ;
2000-04-12 19:17:23 +02:00
2008-05-13 00:59:58 +02:00
if ( tuples > 0 )
2007-03-20 00:38:32 +01:00
{
2008-05-13 00:59:58 +02:00
bool have_heading ;
int category ;
2003-03-27 17:57:39 +01:00
2008-05-13 00:59:58 +02:00
for ( category = 0 ; category < 4 ; category + + )
2007-03-20 00:38:32 +01:00
{
2008-05-13 00:59:58 +02:00
have_heading = false ;
2007-03-20 00:38:32 +01:00
2008-05-13 00:59:58 +02:00
for ( i = 0 ; i < tuples ; i + + )
2007-03-20 00:38:32 +01:00
{
2008-05-13 00:59:58 +02:00
const char * ruledef ;
bool list_rule = false ;
2007-03-20 00:38:32 +01:00
switch ( category )
{
case 0 :
2008-05-13 00:59:58 +02:00
if ( * PQgetvalue ( result , i , 2 ) = = ' O ' )
list_rule = true ;
2007-03-20 00:38:32 +01:00
break ;
case 1 :
2008-05-13 00:59:58 +02:00
if ( * PQgetvalue ( result , i , 2 ) = = ' D ' )
list_rule = true ;
2007-03-20 00:38:32 +01:00
break ;
case 2 :
2008-05-13 00:59:58 +02:00
if ( * PQgetvalue ( result , i , 2 ) = = ' A ' )
list_rule = true ;
2007-03-20 00:38:32 +01:00
break ;
case 3 :
2008-05-13 00:59:58 +02:00
if ( * PQgetvalue ( result , i , 2 ) = = ' R ' )
list_rule = true ;
2007-03-20 00:38:32 +01:00
break ;
}
2008-05-13 00:59:58 +02:00
if ( ! list_rule )
continue ;
2007-03-20 00:38:32 +01:00
2008-05-13 00:59:58 +02:00
if ( ! have_heading )
{
switch ( category )
{
case 0 :
printfPQExpBuffer ( & buf , _ ( " Rules: " ) ) ;
break ;
case 1 :
printfPQExpBuffer ( & buf , _ ( " Disabled rules: " ) ) ;
break ;
case 2 :
printfPQExpBuffer ( & buf , _ ( " Rules firing always: " ) ) ;
break ;
case 3 :
printfPQExpBuffer ( & buf , _ ( " Rules firing on replica only: " ) ) ;
break ;
}
printTableAddFooter ( & cont , buf . data ) ;
have_heading = true ;
}
/* Everything after "CREATE RULE" is echoed verbatim */
ruledef = PQgetvalue ( result , i , 1 ) ;
ruledef + = 12 ;
printfPQExpBuffer ( & buf , " %s " , ruledef ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
2007-03-20 00:38:32 +01:00
}
2003-03-27 17:57:39 +01:00
}
2008-05-13 00:59:58 +02:00
PQclear ( result ) ;
2000-04-12 19:17:23 +02:00
}
2017-01-19 18:00:00 +01:00
/* print any publications */
if ( pset . sversion > = 100000 )
{
printfPQExpBuffer ( & buf ,
2017-06-20 18:25:07 +02:00
" SELECT pubname \n "
" FROM pg_catalog.pg_publication p \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" JOIN pg_catalog.pg_publication_rel pr ON p.oid = pr.prpubid \n "
2017-06-20 18:25:07 +02:00
" WHERE pr.prrelid = '%s' \n "
" UNION ALL \n "
" SELECT pubname \n "
" FROM pg_catalog.pg_publication p \n "
2017-07-27 01:35:35 +02:00
" WHERE p.puballtables AND pg_catalog.pg_relation_is_publishable('%s') \n "
2017-01-19 18:00:00 +01:00
" ORDER BY 1; " ,
2017-06-20 18:25:07 +02:00
oid , oid ) ;
2017-01-19 18:00:00 +01:00
result = PSQLexec ( buf . data ) ;
if ( ! result )
goto error_return ;
else
tuples = PQntuples ( result ) ;
if ( tuples > 0 )
printTableAddFooter ( & cont , _ ( " Publications: " ) ) ;
/* Might be an empty set - that's ok */
for ( i = 0 ; i < tuples ; i + + )
{
printfPQExpBuffer ( & buf , " \" %s \" " ,
PQgetvalue ( result , i , 0 ) ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
PQclear ( result ) ;
}
2010-10-10 19:43:33 +02:00
}
2018-07-19 20:53:41 +02:00
/* 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 ) ;
}
2013-03-04 01:23:31 +01:00
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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHERE r.ev_class = '%s' AND r.rulename != '_RETURN' ORDER BY 1; " ,
2013-03-04 01:23:31 +01:00
oid ) ;
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2013-03-04 01:23:31 +01:00
if ( ! result )
goto error_return ;
if ( PQntuples ( result ) > 0 )
{
printTableAddFooter ( & cont , _ ( " Rules: " ) ) ;
for ( i = 0 ; i < PQntuples ( result ) ; i + + )
{
const char * ruledef ;
/* Everything after "CREATE RULE" is echoed verbatim */
ruledef = PQgetvalue ( result , i , 1 ) ;
ruledef + = 12 ;
printfPQExpBuffer ( & buf , " %s " , ruledef ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
}
PQclear ( result ) ;
}
}
2010-10-10 19:43:33 +02:00
/*
* Print triggers next , if any ( but only user - defined triggers ) . This
* could apply to either a table or a view .
*/
if ( tableinfo . hastriggers )
{
2011-04-10 17:42:00 +02:00
PGresult * result ;
int tuples ;
2000-04-12 19:17:23 +02:00
2011-04-10 17:42:00 +02:00
printfPQExpBuffer ( & buf ,
" SELECT t.tgname, "
" pg_catalog.pg_get_triggerdef(t.oid%s), "
2014-02-24 18:44:55 +01:00
" t.tgenabled, %s \n "
2011-04-10 17:42:00 +02:00
" FROM pg_catalog.pg_trigger t \n "
" WHERE t.tgrelid = '%s' AND " ,
( pset . sversion > = 90000 ? " , true " : " " ) ,
2014-02-24 18:44:55 +01:00
( pset . sversion > = 90000 ? " t.tgisinternal " :
pset . sversion > = 80300 ?
" t.tgconstraint <> 0 AS tgisinternal " :
" false AS tgisinternal " ) , oid ) ;
2018-06-29 17:40:36 +02:00
if ( pset . sversion > = 110000 )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " (NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D') \n "
" OR EXISTS (SELECT 1 FROM pg_catalog.pg_depend WHERE objid = t.oid \n "
" AND refclassid = 'pg_catalog.pg_trigger'::pg_catalog.regclass)) " ) ;
2018-06-29 17:40:36 +02:00
else if ( pset . sversion > = 90000 )
2014-02-24 18:44:55 +01:00
/* display/warn about disabled internal triggers */
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf , " (NOT t.tgisinternal OR (t.tgisinternal AND t.tgenabled = 'D')) " ) ;
2011-04-10 17:42:00 +02:00
else if ( pset . sversion > = 80300 )
2014-02-24 18:44:55 +01:00
appendPQExpBufferStr ( & buf , " (t.tgconstraint = 0 OR (t.tgconstraint <> 0 AND t.tgenabled = 'D')) " ) ;
2011-04-10 17:42:00 +02:00
else
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & 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')) " ) ;
appendPQExpBufferStr ( & buf , " \n ORDER BY 1; " ) ;
2008-07-03 05:37:17 +02:00
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2011-04-10 17:42:00 +02:00
if ( ! result )
goto error_return ;
else
tuples = PQntuples ( result ) ;
2008-05-13 00:59:58 +02:00
2011-04-10 17:42:00 +02:00
if ( tuples > 0 )
{
bool have_heading ;
int category ;
/*
* split the output into 4 different categories . Enabled triggers ,
* disabled triggers and the two special ALWAYS and REPLICA
* configurations .
*/
2014-02-24 18:44:55 +01:00
for ( category = 0 ; category < = 4 ; category + + )
2003-03-27 17:57:39 +01:00
{
2011-04-10 17:42:00 +02:00
have_heading = false ;
for ( i = 0 ; i < tuples ; i + + )
2007-03-20 00:38:32 +01:00
{
2011-04-10 17:42:00 +02:00
bool list_trigger ;
const char * tgdef ;
const char * usingpos ;
const char * tgenabled ;
2014-02-24 18:44:55 +01:00
const char * tgisinternal ;
2011-04-10 17:42:00 +02:00
/*
* Check if this trigger falls into the current category
*/
tgenabled = PQgetvalue ( result , i , 2 ) ;
2014-02-24 18:44:55 +01:00
tgisinternal = PQgetvalue ( result , i , 3 ) ;
2011-04-10 17:42:00 +02:00
list_trigger = false ;
switch ( category )
{
case 0 :
if ( * tgenabled = = ' O ' | | * tgenabled = = ' t ' )
list_trigger = true ;
break ;
case 1 :
2014-02-24 18:44:55 +01:00
if ( ( * tgenabled = = ' D ' | | * tgenabled = = ' f ' ) & &
* tgisinternal = = ' f ' )
2011-04-10 17:42:00 +02:00
list_trigger = true ;
break ;
case 2 :
2014-02-24 18:44:55 +01:00
if ( ( * tgenabled = = ' D ' | | * tgenabled = = ' f ' ) & &
* tgisinternal = = ' t ' )
2011-04-10 17:42:00 +02:00
list_trigger = true ;
break ;
case 3 :
2014-02-24 18:44:55 +01:00
if ( * tgenabled = = ' A ' )
list_trigger = true ;
break ;
case 4 :
2011-04-10 17:42:00 +02:00
if ( * tgenabled = = ' R ' )
list_trigger = true ;
break ;
}
if ( list_trigger = = false )
continue ;
/* Print the category heading once */
if ( have_heading = = false )
2007-03-20 00:38:32 +01:00
{
switch ( category )
{
case 0 :
2011-04-10 17:42:00 +02:00
printfPQExpBuffer ( & buf , _ ( " Triggers: " ) ) ;
2007-03-20 00:38:32 +01:00
break ;
case 1 :
2014-02-24 18:44:55 +01:00
if ( pset . sversion > = 80300 )
printfPQExpBuffer ( & buf , _ ( " Disabled user triggers: " ) ) ;
else
printfPQExpBuffer ( & buf , _ ( " Disabled triggers: " ) ) ;
2007-03-20 00:38:32 +01:00
break ;
case 2 :
2014-05-06 18:12:18 +02:00
printfPQExpBuffer ( & buf , _ ( " Disabled internal triggers: " ) ) ;
2007-03-20 00:38:32 +01:00
break ;
case 3 :
2014-02-24 18:44:55 +01:00
printfPQExpBuffer ( & buf , _ ( " Triggers firing always: " ) ) ;
break ;
case 4 :
2011-04-10 17:42:00 +02:00
printfPQExpBuffer ( & buf , _ ( " Triggers firing on replica only: " ) ) ;
2007-03-20 00:38:32 +01:00
break ;
2008-05-13 00:59:58 +02:00
2007-03-20 00:38:32 +01:00
}
2008-05-13 00:59:58 +02:00
printTableAddFooter ( & cont , buf . data ) ;
2011-04-10 17:42:00 +02:00
have_heading = true ;
2008-05-13 00:59:58 +02:00
}
2011-04-10 17:42:00 +02:00
/* Everything after "TRIGGER" is echoed verbatim */
tgdef = PQgetvalue ( result , i , 1 ) ;
usingpos = strstr ( tgdef , " TRIGGER " ) ;
if ( usingpos )
tgdef = usingpos + 9 ;
printfPQExpBuffer ( & buf , " %s " , tgdef ) ;
printTableAddFooter ( & cont , buf . data ) ;
2007-03-20 00:38:32 +01:00
}
2007-01-20 22:17:30 +01:00
}
2011-04-10 17:42:00 +02:00
}
PQclear ( result ) ;
2010-10-10 19:43:33 +02:00
}
/*
* Finish printing the footer information about a table .
*/
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_MATVIEW | |
tableinfo . relkind = = RELKIND_FOREIGN_TABLE | |
2019-07-23 21:25:56 +02:00
tableinfo . relkind = = RELKIND_PARTITIONED_TABLE | |
2019-07-23 23:04:21 +02:00
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX | |
2019-07-23 21:25:56 +02:00
tableinfo . relkind = = RELKIND_TOASTVALUE )
2010-10-10 19:43:33 +02:00
{
2019-07-23 23:04:21 +02:00
bool is_partitioned ;
2010-10-10 19:43:33 +02:00
PGresult * result ;
int tuples ;
2007-01-20 22:17:30 +01:00
2019-07-23 23:04:21 +02:00
/* simplify some repeated tests below */
is_partitioned = ( tableinfo . relkind = = RELKIND_PARTITIONED_TABLE | |
tableinfo . relkind = = RELKIND_PARTITIONED_INDEX ) ;
2011-01-02 05:48:11 +01:00
/* print foreign server name */
2017-03-10 02:42:42 +01:00
if ( tableinfo . relkind = = RELKIND_FOREIGN_TABLE )
2011-01-02 05:48:11 +01:00
{
2012-06-10 21:20:04 +02:00
char * ftoptions ;
2011-08-11 17:45:47 +02:00
2011-01-02 05:48:11 +01:00
/* Footer information about foreign table */
printfPQExpBuffer ( & buf ,
2011-08-11 17:45:47 +02:00
" SELECT s.srvname, \n "
2017-07-27 01:35:35 +02:00
" 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 "
2011-01-02 05:48:11 +01:00
" FROM pg_catalog.pg_foreign_table f, \n "
" pg_catalog.pg_foreign_server s \n "
2017-07-27 01:35:35 +02:00
" WHERE f.ftrelid = '%s' AND s.oid = f.ftserver; " ,
2011-01-02 05:48:11 +01:00
oid ) ;
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2011-01-02 05:48:11 +01:00
if ( ! result )
goto error_return ;
else if ( PQntuples ( result ) ! = 1 )
{
PQclear ( result ) ;
goto error_return ;
}
2011-08-11 17:45:47 +02:00
/* Print server name */
2017-05-10 16:14:49 +02:00
printfPQExpBuffer ( & buf , _ ( " Server: %s " ) ,
2011-04-10 17:42:00 +02:00
PQgetvalue ( result , 0 , 0 ) ) ;
2011-01-02 05:48:11 +01:00
printTableAddFooter ( & cont , buf . data ) ;
2011-08-11 17:45:47 +02:00
/* Print per-table FDW options, if any */
ftoptions = PQgetvalue ( result , 0 , 1 ) ;
if ( ftoptions & & ftoptions [ 0 ] ! = ' \0 ' )
{
2017-06-13 20:38:35 +02:00
printfPQExpBuffer ( & buf , _ ( " FDW options: (%s) " ) , ftoptions ) ;
2011-08-11 17:45:47 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
2011-01-02 05:48:11 +01:00
PQclear ( result ) ;
}
2019-07-23 23:04:21 +02:00
/* print tables inherited from (exclude partitioned parents) */
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
printfPQExpBuffer ( & buf ,
2019-07-23 23:04:21 +02:00
" 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 )
" \n ORDER BY inhseqno; " ,
oid ) ;
2008-05-13 00:59:58 +02:00
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
goto error_return ;
else
2003-07-25 23:42:26 +02:00
{
2007-11-15 22:14:46 +01:00
const char * s = _ ( " Inherits " ) ;
2012-03-08 01:25:59 +01:00
int sw = pg_wcswidth ( s , strlen ( s ) , pset . encoding ) ;
2003-07-25 23:42:26 +02:00
2012-03-08 01:25:59 +01:00
tuples = PQntuples ( result ) ;
2003-07-25 23:42:26 +02:00
2012-03-08 01:25:59 +01:00
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 )
2015-07-02 11:32:48 +02:00
appendPQExpBufferChar ( & buf , ' , ' ) ;
2012-03-08 01:25:59 +01:00
printTableAddFooter ( & cont , buf . data ) ;
}
PQclear ( result ) ;
2003-07-25 23:42:26 +02:00
}
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
/* print child tables (with additional info if partitions) */
if ( pset . sversion > = 100000 )
printfPQExpBuffer ( & buf ,
2019-07-23 23:04:21 +02:00
" SELECT c.oid::pg_catalog.regclass, c.relkind, "
" 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 ) ;
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
else if ( pset . sversion > = 80300 )
printfPQExpBuffer ( & buf ,
2019-07-23 23:04:21 +02:00
" SELECT c.oid::pg_catalog.regclass, c.relkind, 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 ) ;
2009-07-07 22:32:20 +02:00
else
2017-07-27 01:35:35 +02:00
printfPQExpBuffer ( & buf ,
2019-07-23 23:04:21 +02:00
" SELECT c.oid::pg_catalog.regclass, c.relkind, 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.relname; " ,
oid ) ;
2009-07-03 20:56:50 +02:00
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2009-07-03 20:56:50 +02:00
if ( ! result )
goto error_return ;
2019-07-23 23:04:21 +02:00
tuples = PQntuples ( result ) ;
2009-07-03 20:56:50 +02:00
2017-11-22 19:10:39 +01:00
/*
* For a partitioned table with no partitions , always print the number
* of partitions as zero , even when verbose output is expected .
* Otherwise , we will not print " Partitions " section for a partitioned
* table without any partitions .
*/
2019-07-23 23:04:21 +02:00
if ( is_partitioned & & tuples = = 0 )
2017-11-22 19:10:39 +01:00
{
printfPQExpBuffer ( & buf , _ ( " Number of partitions: %d " ) , tuples ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
else if ( ! verbose )
2009-07-03 20:56:50 +02:00
{
/* print the number of child tables, if any */
if ( tuples > 0 )
{
2019-07-23 23:04:21 +02:00
if ( is_partitioned )
Implement table partitioning.
Table partitioning is like table inheritance and reuses much of the
existing infrastructure, but there are some important differences.
The parent is called a partitioned table and is always empty; it may
not have indexes or non-inherited constraints, since those make no
sense for a relation with no data of its own. The children are called
partitions and contain all of the actual data. Each partition has an
implicit partitioning constraint. Multiple inheritance is not
allowed, and partitioning and inheritance can't be mixed. Partitions
can't have extra columns and may not allow nulls unless the parent
does. Tuples inserted into the parent are automatically routed to the
correct partition, so tuple-routing ON INSERT triggers are not needed.
Tuple routing isn't yet supported for partitions which are foreign
tables, and it doesn't handle updates that cross partition boundaries.
Currently, tables can be range-partitioned or list-partitioned. List
partitioning is limited to a single column, but range partitioning can
involve multiple columns. A partitioning "column" can be an
expression.
Because table partitioning is less general than table inheritance, it
is hoped that it will be easier to reason about properties of
partitions, and therefore that this will serve as a better foundation
for a variety of possible optimizations, including query planner
optimizations. The tuple routing based which this patch does based on
the implicit partitioning constraints is an example of this, but it
seems likely that many other useful optimizations are also possible.
Amit Langote, reviewed and tested by Robert Haas, Ashutosh Bapat,
Amit Kapila, Rajkumar Raghuwanshi, Corey Huinker, Jaime Casanova,
Rushabh Lathia, Erik Rijkers, among others. Minor revisions by me.
2016-12-07 19:17:43 +01:00
printfPQExpBuffer ( & buf , _ ( " Number of partitions: %d (Use \\ d+ to list them.) " ) , tuples ) ;
2019-07-23 23:04:21 +02:00
else
printfPQExpBuffer ( & buf , _ ( " Number of child tables: %d (Use \\ d+ to list them.) " ) , tuples ) ;
2009-07-03 20:56:50 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
}
else
{
2009-07-07 18:28:38 +02:00
/* display the list of child tables */
2019-07-23 23:04:21 +02:00
const char * ct = is_partitioned ? _ ( " Partitions " ) : _ ( " Child tables " ) ;
2012-03-08 01:25:59 +01:00
int ctw = pg_wcswidth ( ct , strlen ( ct ) , pset . encoding ) ;
2009-07-07 18:28:38 +02:00
2009-07-03 20:56:50 +02:00
for ( i = 0 ; i < tuples ; i + + )
2009-07-07 18:28:38 +02:00
{
2019-07-23 23:04:21 +02:00
char child_relkind = * PQgetvalue ( result , i , 1 ) ;
2017-11-22 19:10:39 +01:00
2019-07-23 23:04:21 +02:00
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 , 2 ) )
appendPQExpBuffer ( & buf , " %s " , PQgetvalue ( result , i , 2 ) ) ;
if ( child_relkind = = RELKIND_PARTITIONED_TABLE | |
child_relkind = = RELKIND_PARTITIONED_INDEX )
appendPQExpBufferStr ( & buf , " , PARTITIONED " ) ;
2009-07-07 18:28:38 +02:00
if ( i < tuples - 1 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferChar ( & buf , ' , ' ) ;
2009-07-07 18:28:38 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
2009-07-03 20:56:50 +02:00
}
PQclear ( result ) ;
2010-01-29 00:21:13 +01:00
/* Table type */
if ( tableinfo . reloftype )
{
printfPQExpBuffer ( & buf , _ ( " Typed table of type: %s " ) , tableinfo . reloftype ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
2017-03-10 02:42:42 +01:00
if ( verbose & &
( tableinfo . relkind = = RELKIND_RELATION | |
tableinfo . relkind = = RELKIND_MATVIEW ) & &
2014-05-06 18:12:18 +02:00
/*
2017-03-10 02:42:42 +01:00
* No need to display default values ; we already display a REPLICA
2014-05-06 18:12:18 +02:00
* IDENTITY marker on indexes .
*/
2014-04-15 19:28:54 +02:00
tableinfo . relreplident ! = ' i ' & &
( ( strcmp ( schemaname , " pg_catalog " ) ! = 0 & & tableinfo . relreplident ! = ' d ' ) | |
( strcmp ( schemaname , " pg_catalog " ) = = 0 & & tableinfo . relreplident ! = ' n ' ) ) )
2013-11-08 18:30:43 +01:00
{
const char * s = _ ( " Replica Identity " ) ;
printfPQExpBuffer ( & buf , " %s: %s " ,
2013-11-10 15:20:52 +01:00
s ,
2014-03-26 16:13:17 +01:00
tableinfo . relreplident = = ' f ' ? " FULL " :
tableinfo . relreplident = = ' n ' ? " NOTHING " :
" ??? " ) ;
2013-11-08 18:30:43 +01:00
printTableAddFooter ( & cont , buf . data ) ;
}
2013-03-04 01:23:31 +01:00
/* OIDs, if verbose and not a materialized view */
2017-03-10 02:42:42 +01:00
if ( verbose & & tableinfo . relkind ! = RELKIND_MATVIEW & & tableinfo . hasoids )
2014-04-15 19:28:54 +02:00
printTableAddFooter ( & cont , _ ( " Has OIDs: yes " ) ) ;
2004-04-22 19:38:16 +02:00
2012-09-03 17:24:31 +02:00
/* Tablespace info */
2008-05-13 00:59:58 +02:00
add_tablespace_footer ( & cont , tableinfo . relkind , tableinfo . tablespace ,
true ) ;
tableam: introduce table AM infrastructure.
This introduces the concept of table access methods, i.e. CREATE
ACCESS METHOD ... TYPE TABLE and
CREATE TABLE ... USING (storage-engine).
No table access functionality is delegated to table AMs as of this
commit, that'll be done in following commits.
Subsequent commits will incrementally abstract table access
functionality to be routed through table access methods. That change
is too large to be reviewed & committed at once, so it'll be done
incrementally.
Docs will be updated at the end, as adding them incrementally would
likely make them less coherent, and definitely is a lot more work,
without a lot of benefit.
Table access methods are specified similar to index access methods,
i.e. pg_am.amhandler returns, as INTERNAL, a pointer to a struct with
callbacks. In contrast to index AMs that struct needs to live as long
as a backend, typically that's achieved by just returning a pointer to
a constant struct.
Psql's \d+ now displays a table's access method. That can be disabled
with HIDE_TABLEAM=true, which is mainly useful so regression tests can
be run against different AMs. It's quite possible that this behaviour
still needs to be fine tuned.
For now it's not allowed to set a table AM for a partitioned table, as
we've not resolved how partitions would inherit that. Disallowing
allows us to introduce, if we decide that's the way forward, such a
behaviour without a compatibility break.
Catversion bumped, to add the heap table AM and references to it.
Author: Haribabu Kommi, Andres Freund, Alvaro Herrera, Dimitri Golgov and others
Discussion:
https://postgr.es/m/20180703070645.wchpu5muyto5n647@alap3.anarazel.de
https://postgr.es/m/20160812231527.GA690404@alvherre.pgsql
https://postgr.es/m/20190107235616.6lur25ph22u5u5av@alap3.anarazel.de
https://postgr.es/m/20190304234700.w5tmhducs5wxgzls@alap3.anarazel.de
2019-03-06 18:54:38 +01:00
/* Access method info */
if ( verbose & & tableinfo . relam ! = NULL & & ! pset . hide_tableam )
{
printfPQExpBuffer ( & buf , _ ( " Access method: %s " ) , tableinfo . relam ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
* Includes tab completion. It's not magic, but it's very cool. At any
rate
it's better than what used to be there.
* Does proper SQL "host variable" substitution as pointed out by Andreas
Zeugwetter (thanks): select * from :foo; Also some changes in how ':'
and ';' are treated (escape with \ to send to backend). This does
_not_
affect the '::' cast operator, but perhaps others that contain : or ;
(but there are none right now).
* To show description with a <something> listing, append '?' to command
name, e.g., \df?. This seemed to be the convenient and logical
solution.
Or append a '+' to see more useless information, e.g., \df+.
* Fixed fflush()'ing bug pointed out by Jan during the regression test
discussion.
* Added LastOid variable. This ought to take care of TODO item "Add a
function to return the last inserted oid, for use in psql scripts"
(under CLIENTS)
E.g.,
insert into foo values(...);
insert into bar values(..., :LastOid);
\echo $LastOid
* \d command shows constraints, rules, and triggers defined on the table
(in addition to indices)
* Various fixes, optimizations, corrections
* Documentation update as well
Note: This now requires snprintf(), which, if necessary, is taken from
src/backend/port. This is certainly a little weird, but it should
suffice
until a source tree cleanup is done.
Enjoy.
--
Peter Eisentraut Sernanders väg 10:115
1999-11-26 05:24:17 +01:00
}
1999-11-04 22:56:02 +01:00
2012-09-03 17:24:31 +02:00
/* reloptions, if verbose */
if ( verbose & &
tableinfo . reloptions & & tableinfo . reloptions [ 0 ] ! = ' \0 ' )
{
const char * t = _ ( " Options " ) ;
printfPQExpBuffer ( & buf , " %s: %s " , t , tableinfo . reloptions ) ;
printTableAddFooter ( & cont , buf . data ) ;
}
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printTable ( & cont , pset . queryFout , false , pset . logfile ) ;
2002-04-24 07:24:00 +02:00
retval = true ;
error_return :
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
/* clean up */
2008-11-03 20:08:56 +01:00
if ( printTableInitialized )
printTableCleanup ( & cont ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
termPQExpBuffer ( & title ) ;
2002-12-21 02:07:07 +01:00
termPQExpBuffer ( & tmpbuf ) ;
2009-06-11 16:49:15 +02:00
2002-08-10 05:56:24 +02:00
if ( view_def )
free ( view_def ) ;
2002-04-24 07:24:00 +02:00
if ( res )
PQclear ( res ) ;
1999-11-04 22:56:02 +01:00
2002-04-24 07:24:00 +02:00
return retval ;
1999-11-04 22:56:02 +01:00
}
2005-10-15 04:49:52 +02:00
/*
2008-05-13 00:59:58 +02:00
* Add a tablespace description to a footer . If ' newline ' is true , it is added
* in a new line ; otherwise it ' s appended to the current value of the last
* footer .
2005-06-15 01:59:31 +02:00
*/
2008-05-13 00:59:58 +02:00
static void
add_tablespace_footer ( printTableContent * const cont , char relkind ,
Oid tablespace , const bool newline )
2004-07-12 22:41:13 +02:00
{
/* relkinds for which we support tablespaces */
2017-03-10 02:42:42 +01:00
if ( relkind = = RELKIND_RELATION | |
relkind = = RELKIND_MATVIEW | |
relkind = = RELKIND_INDEX | |
2019-04-18 00:17:43 +02:00
relkind = = RELKIND_PARTITIONED_TABLE | |
2019-07-23 21:25:56 +02:00
relkind = = RELKIND_PARTITIONED_INDEX | |
relkind = = RELKIND_TOASTVALUE )
2004-07-12 22:41:13 +02:00
{
/*
2005-10-15 04:49:52 +02:00
* We ignore the database default tablespace so that users not using
2008-07-03 05:37:17 +02:00
* tablespaces don ' t need to know about them . This case also covers
* pre - 8.0 servers , for which tablespace will always be 0.
2004-07-12 22:41:13 +02:00
*/
2004-08-29 07:07:03 +02:00
if ( tablespace ! = 0 )
2004-07-12 22:41:13 +02:00
{
2008-05-13 00:59:58 +02:00
PGresult * result = NULL ;
PQExpBufferData buf ;
2004-08-29 07:07:03 +02:00
2008-05-13 00:59:58 +02:00
initPQExpBuffer ( & buf ) ;
2008-07-03 05:37:17 +02:00
printfPQExpBuffer ( & buf ,
" SELECT spcname FROM pg_catalog.pg_tablespace \n "
2011-07-06 16:11:20 +02:00
" WHERE oid = '%u'; " , tablespace ) ;
2014-10-23 15:33:56 +02:00
result = PSQLexec ( buf . data ) ;
2008-05-13 00:59:58 +02:00
if ( ! result )
2017-07-27 17:57:29 +02:00
{
termPQExpBuffer ( & buf ) ;
2008-05-13 00:59:58 +02:00
return ;
2017-07-27 17:57:29 +02:00
}
2004-07-12 22:41:13 +02:00
/* Should always be the case, but.... */
2008-05-13 00:59:58 +02:00
if ( PQntuples ( result ) > 0 )
2004-07-12 22:41:13 +02:00
{
2008-05-13 00:59:58 +02:00
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 ) ;
2009-06-11 16:49:15 +02:00
2013-08-27 19:33:37 +02:00
/*-------
translator : before this string there ' s an index description like
' " foo_pkey " PRIMARY KEY , btree ( a ) ' */
2008-05-13 00:59:58 +02:00
appendPQExpBuffer ( & buf , _ ( " , tablespace \" %s \" " ) ,
PQgetvalue ( result , 0 , 0 ) ) ;
printTableSetFooter ( cont , buf . data ) ;
}
2004-07-12 22:41:13 +02:00
}
2008-05-13 00:59:58 +02:00
PQclear ( result ) ;
termPQExpBuffer ( & buf ) ;
2004-07-12 22:41:13 +02:00
}
}
}
2001-05-09 19:29:10 +02:00
/*
2005-08-14 20:49:30 +02:00
* \ du or \ dg
2001-05-09 19:29:10 +02:00
*
2005-08-14 20:49:30 +02:00
* Describes roles . Any schema portion of the pattern is ignored .
2001-05-09 19:29:10 +02:00
*/
bool
2016-04-08 22:56:27 +02:00
describeRoles ( const char * pattern , bool verbose , bool showSystem )
2001-05-09 19:29:10 +02:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
2001-05-09 19:29:10 +02:00
PGresult * res ;
2008-05-13 02:23:17 +02:00
printTableContent cont ;
printTableOpt myopt = pset . popt . topt ;
int ncols = 3 ;
int nrows = 0 ;
int i ;
int conns ;
const char align = ' l ' ;
char * * attr ;
2001-10-25 07:50:21 +02:00
2012-05-01 22:03:45 +02:00
myopt . default_footer = false ;
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion > = 80100 )
{
printfPQExpBuffer ( & buf ,
2009-06-11 16:49:15 +02:00
" SELECT r.rolname, r.rolsuper, r.rolinherit, \n "
" r.rolcreaterole, r.rolcreatedb, r.rolcanlogin, \n "
2012-03-22 07:08:25 +01:00
" r.rolconnlimit, r.rolvaliduntil, \n "
2009-06-11 16:49:15 +02:00
" ARRAY(SELECT b.rolname \n "
" FROM pg_catalog.pg_auth_members m \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid) \n "
2009-06-11 16:49:15 +02:00
" WHERE m.member = r.oid) as memberof " ) ;
2003-12-01 23:21:54 +01:00
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80200 )
{
appendPQExpBufferStr ( & buf , " \n , pg_catalog.shobj_description(r.oid, 'pg_authid') AS description " ) ;
ncols + + ;
}
2010-12-29 11:05:03 +01:00
if ( pset . sversion > = 90100 )
{
2011-04-10 17:42:00 +02:00
appendPQExpBufferStr ( & buf , " \n , r.rolreplication " ) ;
2010-12-29 11:05:03 +01:00
}
2006-02-12 04:22:21 +01:00
Row-Level Security Policies (RLS)
Building on the updatable security-barrier views work, add the
ability to define policies on tables to limit the set of rows
which are returned from a query and which are allowed to be added
to a table. Expressions defined by the policy for filtering are
added to the security barrier quals of the query, while expressions
defined to check records being added to a table are added to the
with-check options of the query.
New top-level commands are CREATE/ALTER/DROP POLICY and are
controlled by the table owner. Row Security is able to be enabled
and disabled by the owner on a per-table basis using
ALTER TABLE .. ENABLE/DISABLE ROW SECURITY.
Per discussion, ROW SECURITY is disabled on tables by default and
must be enabled for policies on the table to be used. If no
policies exist on a table with ROW SECURITY enabled, a default-deny
policy is used and no records will be visible.
By default, row security is applied at all times except for the
table owner and the superuser. A new GUC, row_security, is added
which can be set to ON, OFF, or FORCE. When set to FORCE, row
security will be applied even for the table owner and superusers.
When set to OFF, row security will be disabled when allowed and an
error will be thrown if the user does not have rights to bypass row
security.
Per discussion, pg_dump sets row_security = OFF by default to ensure
that exports and backups will have all data in the table or will
error if there are insufficient privileges to bypass row security.
A new option has been added to pg_dump, --enable-row-security, to
ask pg_dump to export with row security enabled.
A new role capability, BYPASSRLS, which can only be set by the
superuser, is added to allow other users to be able to bypass row
security using row_security = OFF.
Many thanks to the various individuals who have helped with the
design, particularly Robert Haas for his feedback.
Authors include Craig Ringer, KaiGai Kohei, Adam Brightwell, Dean
Rasheed, with additional changes and rework by me.
Reviewers have included all of the above, Greg Smith,
Jeff McCormick, and Robert Haas.
2014-09-19 17:18:35 +02:00
if ( pset . sversion > = 90500 )
{
appendPQExpBufferStr ( & buf , " \n , r.rolbypassrls " ) ;
}
2008-07-03 05:37:17 +02:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_roles r \n " ) ;
2016-04-08 22:56:27 +02:00
if ( ! showSystem & & ! pattern )
appendPQExpBufferStr ( & buf , " WHERE r.rolname !~ '^pg_' \n " ) ;
2008-07-03 05:37:17 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " r.rolname " , NULL , NULL ) ;
2009-06-11 16:49:15 +02:00
}
else
{
printfPQExpBuffer ( & buf ,
" SELECT u.usename AS rolname, \n "
" u.usesuper AS rolsuper, \n "
" true AS rolinherit, false AS rolcreaterole, \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" u.usecreatedb AS rolcreatedb, true AS rolcanlogin, \n "
2012-03-22 07:08:25 +01:00
" -1 AS rolconnlimit, "
" u.valuntil as rolvaliduntil, \n "
2009-06-11 16:49:15 +02:00
" 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 " ) ;
2008-07-03 05:37:17 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " u.usename " , NULL , NULL ) ;
2009-06-11 16:49:15 +02:00
}
2003-12-01 23:21:54 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2003-12-01 23:21:54 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2003-12-01 23:21:54 +01:00
if ( ! res )
return false ;
2008-05-13 02:23:17 +02:00
nrows = PQntuples ( res ) ;
2012-10-02 21:35:10 +02:00
attr = pg_malloc0 ( ( nrows + 1 ) * sizeof ( * attr ) ) ;
2003-12-01 23:21:54 +01:00
2008-05-13 02:23:17 +02:00
printTableInit ( & cont , & myopt , _ ( " List of roles " ) , ncols , nrows ) ;
printTableAddHeader ( & cont , gettext_noop ( " Role name " ) , true , align ) ;
printTableAddHeader ( & cont , gettext_noop ( " Attributes " ) , true , align ) ;
printTableAddHeader ( & cont , gettext_noop ( " Member of " ) , true , align ) ;
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80200 )
2008-05-13 02:23:17 +02:00
printTableAddHeader ( & cont , gettext_noop ( " Description " ) , true , align ) ;
for ( i = 0 ; i < nrows ; i + + )
{
2010-03-01 21:55:45 +01:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 0 ) , false , false ) ;
2008-05-13 02:23:17 +02:00
resetPQExpBuffer ( & buf ) ;
if ( strcmp ( PQgetvalue ( res , i , 1 ) , " t " ) = = 0 )
add_role_attribute ( & buf , _ ( " Superuser " ) ) ;
if ( strcmp ( PQgetvalue ( res , i , 2 ) , " t " ) ! = 0 )
add_role_attribute ( & buf , _ ( " No inheritance " ) ) ;
if ( strcmp ( PQgetvalue ( res , i , 3 ) , " t " ) = = 0 )
add_role_attribute ( & buf , _ ( " Create role " ) ) ;
if ( strcmp ( PQgetvalue ( res , i , 4 ) , " t " ) = = 0 )
add_role_attribute ( & buf , _ ( " Create DB " ) ) ;
if ( strcmp ( PQgetvalue ( res , i , 5 ) , " t " ) ! = 0 )
add_role_attribute ( & buf , _ ( " Cannot login " ) ) ;
2010-12-29 11:05:03 +01:00
if ( pset . sversion > = 90100 )
2012-03-22 07:08:25 +01:00
if ( strcmp ( PQgetvalue ( res , i , ( verbose ? 10 : 9 ) ) , " t " ) = = 0 )
2010-12-29 11:05:03 +01:00
add_role_attribute ( & buf , _ ( " Replication " ) ) ;
Code review for row security.
Buildfarm member tick identified an issue where the policies in the
relcache for a relation were were being replaced underneath a running
query, leading to segfaults while processing the policies to be added
to a query. Similar to how TupleDesc RuleLocks are handled, add in a
equalRSDesc() function to check if the policies have actually changed
and, if not, swap back the rsdesc field (using the original instead of
the temporairly built one; the whole structure is swapped and then
specific fields swapped back). This now passes a CLOBBER_CACHE_ALWAYS
for me and should resolve the buildfarm error.
In addition to addressing this, add a new chapter in Data Definition
under Privileges which explains row security and provides examples of
its usage, change \d to always list policies (even if row security is
disabled- but note that it is disabled, or enabled with no policies),
rework check_role_for_policy (it really didn't need the entire policy,
but it did need to be using has_privs_of_role()), and change the field
in pg_class to relrowsecurity from relhasrowsecurity, based on
Heikki's suggestion. Also from Heikki, only issue SET ROW_SECURITY in
pg_restore when talking to a 9.5+ server, list Bypass RLS in \du, and
document --enable-row-security options for pg_dump and pg_restore.
Lastly, fix a number of minor whitespace and typo issues from Heikki,
Dimitri, add a missing #include, per Peter E, fix a few minor
variable-assigned-but-not-used and resource leak issues from Coverity
and add tab completion for role attribute bypassrls as well.
2014-09-24 22:32:22 +02:00
if ( pset . sversion > = 90500 )
if ( strcmp ( PQgetvalue ( res , i , ( verbose ? 11 : 10 ) ) , " t " ) = = 0 )
add_role_attribute ( & buf , _ ( " Bypass RLS " ) ) ;
2008-05-13 02:23:17 +02:00
conns = atoi ( PQgetvalue ( res , i , 6 ) ) ;
if ( conns > = 0 )
{
if ( buf . len > 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferChar ( & buf , ' \n ' ) ;
2008-05-13 02:23:17 +02:00
if ( conns = = 0 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , _ ( " No connections " ) ) ;
2008-05-13 02:23:17 +02:00
else
2009-06-04 21:17:39 +02:00
appendPQExpBuffer ( & buf , ngettext ( " %d connection " ,
" %d connections " ,
conns ) ,
conns ) ;
2008-05-13 02:23:17 +02:00
}
2012-03-22 07:08:25 +01:00
if ( strcmp ( PQgetvalue ( res , i , 7 ) , " " ) ! = 0 )
{
if ( buf . len > 0 )
2017-08-16 05:34:39 +02:00
appendPQExpBufferChar ( & buf , ' \n ' ) ;
2012-03-22 07:08:25 +01:00
appendPQExpBufferStr ( & buf , _ ( " Password valid until " ) ) ;
appendPQExpBufferStr ( & buf , PQgetvalue ( res , i , 7 ) ) ;
}
2008-05-13 02:23:17 +02:00
attr [ i ] = pg_strdup ( buf . data ) ;
2010-03-01 21:55:45 +01:00
printTableAddCell ( & cont , attr [ i ] , false , false ) ;
2008-05-13 02:23:17 +02:00
2012-03-22 07:08:25 +01:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 8 ) , false , false ) ;
2008-05-13 02:23:17 +02:00
2008-07-03 05:37:17 +02:00
if ( verbose & & pset . sversion > = 80200 )
2012-03-22 07:08:25 +01:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 9 ) , false , false ) ;
2008-05-13 02:23:17 +02:00
}
termPQExpBuffer ( & buf ) ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printTable ( & cont , pset . queryFout , false , pset . logfile ) ;
2008-05-13 02:23:17 +02:00
printTableCleanup ( & cont ) ;
for ( i = 0 ; i < nrows ; i + + )
free ( attr [ i ] ) ;
free ( attr ) ;
2003-12-01 23:21:54 +01:00
PQclear ( res ) ;
return true ;
}
2009-06-12 18:17:29 +02:00
static void
2008-05-13 02:23:17 +02:00
add_role_attribute ( PQExpBuffer buf , const char * const str )
{
if ( buf - > len > 0 )
2009-11-11 22:07:41 +01:00
appendPQExpBufferStr ( buf , " , " ) ;
2008-05-13 02:23:17 +02:00
appendPQExpBufferStr ( buf , str ) ;
}
2009-10-08 00:14:26 +02:00
/*
* \ drds
*/
bool
listDbRoleSettings ( const char * pattern , const char * pattern2 )
{
2010-02-26 03:01:40 +01:00
PQExpBufferData buf ;
PGresult * res ;
2009-10-08 00:14:26 +02:00
printQueryOpt myopt = pset . popt ;
2017-07-27 17:57:29 +02:00
bool havewhere ;
2009-10-08 00:14:26 +02:00
2017-07-27 17:57:29 +02:00
if ( pset . sversion < 90000 )
2009-10-08 00:14:26 +02:00
{
2017-07-27 17:57:29 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support per-database role settings. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2017-07-27 17:57:29 +02:00
return true ;
2009-10-08 00:14:26 +02:00
}
2017-07-27 17:57:29 +02:00
initPQExpBuffer ( & 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 " ) ) ;
havewhere = processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " r.rolname " , NULL , NULL ) ;
processSQLNamePattern ( pset . db , & buf , pattern2 , havewhere , false ,
NULL , " d.datname " , NULL , NULL ) ;
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2017-07-27 17:57:29 +02:00
termPQExpBuffer ( & buf ) ;
2009-10-08 00:14:26 +02:00
if ( ! res )
return false ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
/*
* Most functions in this file are content to print an empty table when
* there are no matching objects . We intentionally deviate from that
* here , but only in ! quiet mode , because of the possibility that the user
* is confused about what the two pattern arguments mean .
*/
2009-10-08 00:14:26 +02:00
if ( PQntuples ( res ) = = 0 & & ! pset . quiet )
{
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
if ( pattern & & pattern2 )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any settings for role \" %s \" and database \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern , pattern2 ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
else if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any settings for role \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
2009-10-08 00:14:26 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any settings. " ) ;
2009-10-08 00:14:26 +02:00
}
else
{
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of settings " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2009-10-08 00:14:26 +02:00
}
PQclear ( res ) ;
return true ;
}
2003-12-01 23:21:54 +01:00
1999-11-04 22:56:02 +01:00
/*
* listTables ( )
*
2009-04-04 02:44:30 +02:00
* handler for \ dt , \ di , etc .
1999-11-04 22:56:02 +01:00
*
2002-08-10 05:56:24 +02:00
* tabtypes is an array of characters , specifying what info is desired :
1999-11-04 22:56:02 +01:00
* t - tables
2001-06-30 19:26:12 +02:00
* i - indexes
1999-11-04 22:56:02 +01:00
* v - views
2013-03-04 01:23:31 +01:00
* m - materialized views
1999-11-04 22:56:02 +01:00
* s - sequences
2011-01-02 05:48:11 +01:00
* E - foreign table ( Note : different from ' f ' , the relkind value )
1999-11-04 22:56:02 +01:00
* ( any order of the above is fine )
*/
bool
2009-01-06 22:10:30 +01:00
listTables ( const char * tabtypes , const char * pattern , bool verbose , bool showSystem )
1999-11-04 22:56:02 +01:00
{
2002-08-10 05:56:24 +02:00
bool showTables = strchr ( tabtypes , ' t ' ) ! = NULL ;
bool showIndexes = strchr ( tabtypes , ' i ' ) ! = NULL ;
bool showViews = strchr ( tabtypes , ' v ' ) ! = NULL ;
2013-03-04 01:23:31 +01:00
bool showMatViews = strchr ( tabtypes , ' m ' ) ! = NULL ;
2002-08-10 05:56:24 +02:00
bool showSeq = strchr ( tabtypes , ' s ' ) ! = NULL ;
2011-01-02 05:48:11 +01:00
bool showForeign = strchr ( tabtypes , ' E ' ) ! = NULL ;
1999-11-05 00:14:30 +01:00
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
1999-11-05 00:14:30 +01:00
PGresult * res ;
2000-01-14 23:18:03 +01:00
printQueryOpt myopt = pset . popt ;
2019-07-03 17:46:34 +02:00
int cols_so_far ;
bool translate_columns [ ] = { false , false , true , false , false , false , false , false } ;
1999-11-05 00:14:30 +01:00
2017-06-20 00:32:22 +02:00
/* If tabtypes is empty, we default to \dtvmsE (but see also command.c) */
2013-03-04 01:23:31 +01:00
if ( ! ( showTables | | showIndexes | | showViews | | showMatViews | | showSeq | | showForeign ) )
showTables = showViews = showMatViews = showSeq = showForeign = true ;
2000-04-16 22:04:51 +02:00
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
2000-04-16 22:04:51 +02:00
2006-05-28 04:27:08 +02:00
/*
2017-03-10 02:42:42 +01:00
* Note : as of Pg 8.2 , we no longer use relkind ' s ' ( special ) , but we keep
* it here for backwards compatibility .
2006-05-28 04:27:08 +02:00
*/
2002-04-24 07:24:00 +02:00
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT n.nspname as \" %s \" , \n "
" c.relname as \" %s \" , \n "
2013-03-04 01:23:31 +01:00
" CASE c.relkind "
2017-03-10 02:42:42 +01:00
" 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' "
2013-03-04 01:23:31 +01:00
" WHEN 's' THEN '%s' "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHEN " CppAsString2 ( RELKIND_FOREIGN_TABLE ) " THEN '%s' "
" WHEN " CppAsString2 ( RELKIND_PARTITIONED_TABLE ) " THEN '%s' "
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
" WHEN " CppAsString2 ( RELKIND_PARTITIONED_INDEX ) " THEN '%s' "
2013-03-04 01:23:31 +01:00
" END as \" %s \" , \n "
2008-07-03 05:37:17 +02:00
" pg_catalog.pg_get_userbyid(c.relowner) as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
2008-07-03 05:37:17 +02:00
gettext_noop ( " table " ) ,
gettext_noop ( " view " ) ,
2013-03-04 01:23:31 +01:00
gettext_noop ( " materialized view " ) ,
2008-07-03 05:37:17 +02:00
gettext_noop ( " index " ) ,
gettext_noop ( " sequence " ) ,
gettext_noop ( " special " ) ,
2011-01-02 05:48:11 +01:00
gettext_noop ( " foreign table " ) ,
2018-11-19 20:54:26 +01:00
gettext_noop ( " partitioned table " ) ,
gettext_noop ( " partitioned index " ) ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Type " ) ,
gettext_noop ( " Owner " ) ) ;
2019-07-03 17:46:34 +02:00
cols_so_far = 4 ;
2000-01-12 20:36:36 +01:00
2004-09-10 06:10:53 +02:00
if ( showIndexes )
2019-07-03 17:46:34 +02:00
{
2004-09-10 06:10:53 +02:00
appendPQExpBuffer ( & buf ,
2019-07-03 17:46:34 +02:00
" , \n c2.relname as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Table " ) ) ;
2019-07-03 17:46:34 +02:00
cols_so_far + + ;
}
2004-09-10 06:10:53 +02:00
2008-07-03 05:37:17 +02:00
if ( verbose )
2011-04-08 21:52:49 +02:00
{
2019-07-03 17:46:34 +02:00
/*
* Show whether a relation is permanent , temporary , or unlogged . Like
* describeOneTableDetails ( ) , we consider that persistence emerged in
* v9 .1 , even though related concepts existed before .
*/
if ( pset . sversion > = 90100 )
{
appendPQExpBuffer ( & buf ,
" , \n CASE c.relpersistence WHEN 'p' THEN '%s' WHEN 't' THEN '%s' WHEN 'u' THEN '%s' END as \" %s \" " ,
gettext_noop ( " permanent " ) ,
gettext_noop ( " temporary " ) ,
gettext_noop ( " unlogged " ) ,
gettext_noop ( " Persistence " ) ) ;
translate_columns [ cols_so_far ] = true ;
}
/*
* We don ' t bother to count cols_so_far below here , as there ' s no need
* to ; this might change with future additions to the output columns .
*/
2011-04-08 21:52:49 +02:00
/*
2017-02-06 10:33:58 +01:00
* As of PostgreSQL 9.0 , use pg_table_size ( ) to show a more accurate
2011-04-10 17:42:00 +02:00
* size of a table , including FSM , VM and TOAST tables .
2011-04-08 21:52:49 +02:00
*/
if ( pset . sversion > = 90000 )
appendPQExpBuffer ( & buf ,
" , \n pg_catalog.pg_size_pretty(pg_catalog.pg_table_size(c.oid)) as \" %s \" " ,
gettext_noop ( " Size " ) ) ;
else if ( pset . sversion > = 80100 )
appendPQExpBuffer ( & buf ,
" , \n pg_catalog.pg_size_pretty(pg_catalog.pg_relation_size(c.oid)) as \" %s \" " ,
gettext_noop ( " Size " ) ) ;
2002-04-24 07:24:00 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.obj_description(c.oid, 'pg_class') as \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2011-04-08 21:52:49 +02:00
}
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_class c "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" \n LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace " ) ;
2002-09-04 22:31:48 +02:00
if ( showIndexes )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" \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 " ) ;
2002-04-24 07:24:00 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n WHERE c.relkind IN ( " ) ;
2001-06-30 19:26:12 +02:00
if ( showTables )
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_RELATION ) " , "
CppAsString2 ( RELKIND_PARTITIONED_TABLE ) " , " ) ;
1999-11-05 00:14:30 +01:00
if ( showViews )
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_VIEW ) " , " ) ;
2013-03-04 01:23:31 +01:00
if ( showMatViews )
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_MATVIEW ) " , " ) ;
2001-06-30 19:26:12 +02:00
if ( showIndexes )
Local partitioned indexes
When CREATE INDEX is run on a partitioned table, create catalog entries
for an index on the partitioned table (which is just a placeholder since
the table proper has no data of its own), and recurse to create actual
indexes on the existing partitions; create them in future partitions
also.
As a convenience gadget, if the new index definition matches some
existing index in partitions, these are picked up and used instead of
creating new ones. Whichever way these indexes come about, they become
attached to the index on the parent table and are dropped alongside it,
and cannot be dropped on isolation unless they are detached first.
To support pg_dump'ing these indexes, add commands
CREATE INDEX ON ONLY <table>
(which creates the index on the parent partitioned table, without
recursing) and
ALTER INDEX ATTACH PARTITION
(which is used after the indexes have been created individually on each
partition, to attach them to the parent index). These reconstruct prior
database state exactly.
Reviewed-by: (in alphabetical order) Peter Eisentraut, Robert Haas, Amit
Langote, Jesper Pedersen, Simon Riggs, David Rowley
Discussion: https://postgr.es/m/20171113170646.gzweigyrgg6pwsg4@alvherre.pgsql
2018-01-19 15:49:22 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_INDEX ) " , "
CppAsString2 ( RELKIND_PARTITIONED_INDEX ) " , " ) ;
2001-06-30 19:26:12 +02:00
if ( showSeq )
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_SEQUENCE ) " , " ) ;
2009-04-02 17:15:32 +02:00
if ( showSystem | | pattern )
Phase 2 of pgindent updates.
Change pg_bsd_indent to follow upstream rules for placement of comments
to the right of code, and remove pgindent hack that caused comments
following #endif to not obey the general rule.
Commit e3860ffa4dd0dad0dd9eea4be9cc1412373a8c89 wasn't actually using
the published version of pg_bsd_indent, but a hacked-up version that
tried to minimize the amount of movement of comments to the right of
code. The situation of interest is where such a comment has to be
moved to the right of its default placement at column 33 because there's
code there. BSD indent has always moved right in units of tab stops
in such cases --- but in the previous incarnation, indent was working
in 8-space tab stops, while now it knows we use 4-space tabs. So the
net result is that in about half the cases, such comments are placed
one tab stop left of before. This is better all around: it leaves
more room on the line for comment text, and it means that in such
cases the comment uniformly starts at the next 4-space tab stop after
the code, rather than sometimes one and sometimes two tabs after.
Also, ensure that comments following #endif are indented the same
as comments following other preprocessor commands such as #else.
That inconsistency turns out to have been self-inflicted damage
from a poorly-thought-through post-indent "fixup" in pgindent.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:18:54 +02:00
appendPQExpBufferStr ( & buf , " 's', " ) ; /* was RELKIND_SPECIAL */
2011-01-02 05:48:11 +01:00
if ( showForeign )
2017-03-10 02:42:42 +01:00
appendPQExpBufferStr ( & buf , CppAsString2 ( RELKIND_FOREIGN_TABLE ) " , " ) ;
2011-01-02 05:48:11 +01:00
2014-05-06 18:12:18 +02:00
appendPQExpBufferStr ( & buf , " '' " ) ; /* dummy */
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ) \n " ) ;
1999-11-05 00:14:30 +01:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-04-04 02:41:11 +02:00
/*
* TOAST objects are suppressed unconditionally . Since we don ' t provide
2017-03-10 02:42:42 +01:00
* any way to select RELKIND_TOASTVALUE above , we would never show toast
* tables in any case ; it seems a bit confusing to allow their indexes to
* be shown . Use plain \ d if you really need to look at a TOAST
* table / index .
2009-04-04 02:41:11 +02:00
*/
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname !~ '^pg_toast' \n " ) ;
2002-09-22 22:44:22 +02:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.relname " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
1999-11-04 22:56:02 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1,2; " ) ;
1999-11-04 22:56:02 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
1999-11-05 00:14:30 +01:00
if ( ! res )
return false ;
1999-11-04 22:56:02 +01:00
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
/*
* Most functions in this file are content to print an empty table when
* there are no matching objects . We intentionally deviate from that
* here , but only in ! quiet mode , for historical reasons .
*/
2006-08-29 17:19:51 +02:00
if ( PQntuples ( res ) = = 0 & & ! pset . quiet )
2000-04-12 19:17:23 +02:00
{
2002-08-10 05:56:24 +02:00
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any relation named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
2000-04-12 19:17:23 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any relations. " ) ;
2000-04-12 19:17:23 +02:00
}
1999-11-05 00:14:30 +01:00
else
{
myopt . nullPrint = NULL ;
2001-06-30 19:26:12 +02:00
myopt . title = _ ( " List of relations " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
1999-11-04 22:56:02 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
1999-11-05 00:14:30 +01:00
}
1999-11-04 22:56:02 +01:00
1999-11-05 00:14:30 +01:00
PQclear ( res ) ;
return true ;
1999-11-04 22:56:02 +01:00
}
2002-03-19 03:32:21 +01:00
2019-04-07 13:59:12 +02:00
/*
* \ dP
* Takes an optional regexp to select particular relations
*
* As with \ d , you can specify the kinds of relations you want :
*
* t for tables
* i for indexes
*
* And there ' s additional flags :
*
* n to list non - leaf partitioned tables
*
* and you can mix and match these in any order .
*/
bool
listPartitionedTables ( const char * reltypes , const char * pattern , bool verbose )
{
bool showTables = strchr ( reltypes , ' t ' ) ! = NULL ;
bool showIndexes = strchr ( reltypes , ' i ' ) ! = NULL ;
bool showNested = strchr ( reltypes , ' n ' ) ! = NULL ;
PQExpBufferData buf ;
PQExpBufferData title ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2019-05-22 18:55:34 +02:00
bool translate_columns [ ] = { false , false , false , false , false , false , false , false , false } ;
2019-04-07 13:59:12 +02:00
const char * tabletitle ;
bool mixed_output = false ;
/*
* Note : Declarative table partitioning is only supported as of Pg 10.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 ) ) ) ;
return true ;
}
/* If no relation kind was selected, show them all */
if ( ! showTables & & ! showIndexes )
showTables = showIndexes = true ;
if ( showIndexes & & ! showTables )
tabletitle = _ ( " List of partitioned indexes " ) ; /* \dPi */
else if ( 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 ,
2019-04-18 00:35:41 +02:00
" , \n inh.inhparent::regclass as \" %s \" " ,
2019-04-07 13:59:12 +02:00
gettext_noop ( " Parent name " ) ) ;
if ( showIndexes )
appendPQExpBuffer ( & buf ,
" , \n c2.oid::regclass as \" %s \" " ,
2019-04-18 00:35:41 +02:00
gettext_noop ( " Table " ) ) ;
2019-04-07 13:59:12 +02:00
if ( verbose )
{
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 ,
" \n FROM 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 ,
2019-04-18 00:35:41 +02:00
" \n LEFT JOIN pg_catalog.pg_inherits inh ON c.oid = inh.inhrelid " ) ;
2019-04-07 13:59:12 +02:00
if ( verbose )
{
if ( pset . sversion < 120000 )
{
2019-07-04 03:01:13 +02:00
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 " ) ;
2019-04-07 13:59:12 +02:00
}
else
{
/* PostgreSQL 12 has pg_partition_tree function */
2019-07-04 03:01:13 +02:00
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 " ) ;
2019-04-07 13:59:12 +02:00
}
}
appendPQExpBufferStr ( & buf , " \n WHERE 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 <> 'information_schema' \n " ) ;
/*
* TOAST objects are suppressed unconditionally . Since we don ' t provide
* any way to select RELKIND_TOASTVALUE above , we would never show toast
* tables in any case ; it seems a bit confusing to allow their indexes to
* be shown . Use plain \ d if you really need to look at a TOAST
* table / index .
*/
appendPQExpBufferStr ( & buf , " AND n.nspname !~ '^pg_toast' \n " ) ;
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.relname " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
appendPQExpBuffer ( & buf , " ORDER BY \" Schema \" , %s%s \" Name \" ; " ,
mixed_output ? " \" Type \" DESC, " : " " ,
showNested | | pattern ? " \" Parent name \" NULLS FIRST, " : " " ) ;
res = PSQLexec ( buf . data ) ;
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
initPQExpBuffer ( & title ) ;
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & title , tabletitle ) ;
2019-04-07 13:59:12 +02:00
myopt . nullPrint = NULL ;
myopt . title = title . data ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
myopt . n_translate_columns = lengthof ( translate_columns ) ;
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
termPQExpBuffer ( & title ) ;
PQclear ( res ) ;
return true ;
}
2002-04-24 07:24:00 +02:00
2011-01-20 06:00:30 +01:00
/*
* \ dL
*
* Describes languages .
*/
bool
listLanguages ( const char * pattern , bool verbose , bool showSystem )
{
PQExpBufferData buf ;
2011-04-10 17:42:00 +02:00
PGresult * res ;
2011-01-20 06:00:30 +01:00
printQueryOpt myopt = pset . popt ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT l.lanname AS \" %s \" , \n " ,
gettext_noop ( " Name " ) ) ;
if ( pset . sversion > = 80300 )
2011-04-10 17:42:00 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(l.lanowner) as \" %s \" , \n " ,
2011-04-10 17:42:00 +02:00
gettext_noop ( " Owner " ) ) ;
2011-01-20 06:00:30 +01:00
appendPQExpBuffer ( & buf ,
2011-08-08 18:26:13 +02:00
" l.lanpltrusted AS \" %s \" " ,
gettext_noop ( " Trusted " ) ) ;
2011-01-20 06:00:30 +01:00
if ( verbose )
{
2011-04-10 17:42:00 +02:00
appendPQExpBuffer ( & buf ,
" , \n NOT l.lanispl AS \" %s \" , \n "
2017-07-27 01:35:35 +02:00
" l.lanplcallfoid::pg_catalog.regprocedure AS \" %s \" , \n "
" l.lanvalidator::pg_catalog.regprocedure AS \" %s \" , \n " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " Internal language " ) ,
gettext_noop ( " Call handler " ) ,
2011-04-10 17:42:00 +02:00
gettext_noop ( " Validator " ) ) ;
if ( pset . sversion > = 90000 )
2017-07-27 01:35:35 +02:00
appendPQExpBuffer ( & buf , " l.laninline::pg_catalog.regprocedure AS \" %s \" , \n " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " Inline handler " ) ) ;
2011-04-10 17:42:00 +02:00
printACLColumn ( & buf , " l.lanacl " ) ;
2011-01-20 06:00:30 +01:00
}
appendPQExpBuffer ( & buf ,
2011-08-08 18:26:13 +02:00
" , \n d.description AS \" %s \" "
2011-08-04 18:22:26 +02:00
" \n FROM pg_catalog.pg_language l \n "
" LEFT JOIN pg_catalog.pg_description d \n "
" ON d.classoid = l.tableoid AND d.objoid = l.oid \n "
2011-08-08 18:26:13 +02:00
" AND d.objsubid = 0 \n " ,
gettext_noop ( " Description " ) ) ;
2011-01-20 06:00:30 +01:00
2011-08-04 18:22:26 +02:00
if ( pattern )
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " l.lanname " , NULL , NULL ) ;
2011-01-20 06:00:30 +01:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE l.lanplcallfoid != 0 \n " ) ;
2011-08-04 18:22:26 +02:00
2011-01-20 06:00:30 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2011-01-20 06:00:30 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-01-20 06:00:30 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of languages " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2011-01-20 06:00:30 +01:00
PQclear ( res ) ;
return true ;
}
2002-03-19 03:32:21 +01:00
/*
2002-08-10 05:56:24 +02:00
* \ dD
2002-03-19 03:32:21 +01:00
*
2002-08-10 05:56:24 +02:00
* Describes domains .
2002-03-19 03:32:21 +01:00
*/
bool
2011-08-08 18:26:13 +02:00
listDomains ( const char * pattern , bool verbose , bool showSystem )
2002-03-19 03:32:21 +01:00
{
2002-04-24 07:24:00 +02:00
PQExpBufferData buf ;
2002-03-19 03:32:21 +01:00
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2002-04-24 07:24:00 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2002-09-04 22:31:48 +02:00
" SELECT n.nspname as \" %s \" , \n "
" t.typname as \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.format_type(t.typbasetype, t.typtypmod) as \" %s \" , \n " ,
2011-04-18 00:09:22 +02:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Type " ) ) ;
2011-08-11 17:16:29 +02:00
2011-04-18 00:09:22 +02:00
if ( pset . sversion > = 90100 )
2016-11-03 17:00:00 +01:00
appendPQExpBuffer ( & buf ,
" (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 " ,
gettext_noop ( " Collation " ) ) ;
2011-04-18 00:09:22 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" CASE WHEN t.typnotnull THEN 'not null' END as \" %s \" , \n "
2016-11-03 17:00:00 +01:00
" t.typdefault as \" %s \" , \n "
2009-02-23 16:59:55 +01:00
" 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 \n "
2011-08-08 18:26:13 +02:00
" ), ' ') as \" %s \" " ,
2016-11-03 17:00:00 +01:00
gettext_noop ( " Nullable " ) ,
gettext_noop ( " Default " ) ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Check " ) ) ;
2002-08-10 05:56:24 +02:00
2011-08-08 18:26:13 +02:00
if ( verbose )
2011-12-19 23:05:19 +01:00
{
if ( pset . sversion > = 90200 )
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2011-12-19 23:05:19 +01:00
printACLColumn ( & buf , " t.typacl " ) ;
}
2011-08-08 18:26:13 +02:00
appendPQExpBuffer ( & buf ,
" , \n d.description as \" %s \" " ,
gettext_noop ( " Description " ) ) ;
2011-12-19 23:05:19 +01:00
}
2011-08-08 18:26:13 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_type t \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace \n " ) ;
2011-08-08 18:26:13 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" LEFT JOIN pg_catalog.pg_description d "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" ON d.classoid = t.tableoid AND d.objoid = t.oid "
2013-11-18 17:29:01 +01:00
" AND d.objsubid = 0 \n " ) ;
2011-08-08 18:26:13 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE t.typtype = 'd' \n " ) ;
2011-08-08 18:26:13 +02:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " t.typname " , NULL ,
" pg_catalog.pg_type_is_visible(t.oid) " ) ;
2002-08-10 05:56:24 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2002-03-19 03:32:21 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-04-24 07:24:00 +02:00
termPQExpBuffer ( & buf ) ;
2002-03-19 03:32:21 +01:00
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2002-04-24 07:24:00 +02:00
myopt . title = _ ( " List of domains " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2002-03-19 03:32:21 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2002-03-19 03:32:21 +01:00
PQclear ( res ) ;
return true ;
}
2002-08-10 05:56:24 +02:00
2002-12-12 22:02:25 +01:00
/*
* \ dc
*
* Describes conversions .
*/
bool
2011-08-08 18:26:13 +02:00
listConversions ( const char * pattern , bool verbose , bool showSystem )
2002-12-12 22:02:25 +01:00
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
static const bool translate_columns [ ] =
2014-05-06 18:12:18 +02:00
{ false , false , false , false , true , false } ;
2002-12-12 22:02:25 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT n.nspname AS \" %s \" , \n "
" c.conname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_encoding_to_char(c.conforencoding) AS \" %s \" , \n "
" pg_catalog.pg_encoding_to_char(c.contoencoding) AS \" %s \" , \n "
2002-12-12 22:02:25 +01:00
" CASE WHEN c.condefault THEN '%s' \n "
2011-08-08 18:26:13 +02:00
" ELSE '%s' END AS \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Source " ) ,
gettext_noop ( " Destination " ) ,
gettext_noop ( " yes " ) , gettext_noop ( " no " ) ,
gettext_noop ( " Default? " ) ) ;
2002-12-12 22:02:25 +01:00
2011-08-08 18:26:13 +02:00
if ( verbose )
appendPQExpBuffer ( & buf ,
" , \n d.description AS \" %s \" " ,
gettext_noop ( " Description " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_conversion c \n "
" JOIN pg_catalog.pg_namespace n "
" ON n.oid = c.connamespace \n " ) ;
2011-08-08 18:26:13 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" LEFT JOIN pg_catalog.pg_description d "
" ON d.classoid = c.tableoid \n "
" AND d.objoid = c.oid "
" AND d.objsubid = 0 \n " ) ;
2011-08-08 18:26:13 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE true \n " ) ;
2011-08-08 18:26:13 +02:00
2009-06-11 16:49:15 +02:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
2014-05-06 18:12:18 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2009-01-06 22:10:30 +01:00
2006-10-10 01:30:33 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.conname " , NULL ,
" pg_catalog.pg_conversion_is_visible(c.oid) " ) ;
2002-12-12 22:02:25 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2002-12-12 22:02:25 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-12-12 22:02:25 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of conversions " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2002-12-12 22:02:25 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2002-12-12 22:02:25 +01:00
PQclear ( res ) ;
return true ;
}
2012-07-18 16:16:16 +02:00
/*
* \ dy
*
* Describes Event Triggers .
*/
bool
listEventTriggers ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
static const bool translate_columns [ ] =
2013-05-29 22:58:43 +02:00
{ false , false , false , true , false , false , false } ;
2012-07-18 16:16:16 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
" 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 "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" from pg_catalog.unnest(evttags) as t(x)), ', ') as \" %s \" " ,
2012-07-18 16:16:16 +02:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Event " ) ,
gettext_noop ( " Owner " ) ,
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
gettext_noop ( " enabled " ) ,
gettext_noop ( " replica " ) ,
gettext_noop ( " always " ) ,
gettext_noop ( " disabled " ) ,
2012-07-18 16:16:16 +02:00
gettext_noop ( " Enabled " ) ,
2018-08-15 17:01:39 +02:00
gettext_noop ( " Function " ) ,
2012-07-18 16:16:16 +02:00
gettext_noop ( " Tags " ) ) ;
if ( verbose )
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.obj_description(e.oid, 'pg_event_trigger') as \" %s \" " ,
2012-07-18 16:16:16 +02:00
gettext_noop ( " Description " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
" \n FROM pg_catalog.pg_event_trigger e " ) ;
2012-07-18 16:16:16 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " evtname " , NULL , NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1 " ) ;
2012-07-18 16:16:16 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2012-07-18 16:16:16 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of event triggers " ) ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2012-07-18 16:16:16 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2012-07-18 16:16:16 +02:00
PQclear ( res ) ;
return true ;
}
2002-12-12 22:02:25 +01:00
/*
* \ dC
*
* Describes casts .
*/
bool
2011-08-04 18:22:26 +02:00
listCasts ( const char * pattern , bool verbose )
2002-12-12 22:02:25 +01:00
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
static const bool translate_columns [ ] = { false , false , false , true , false } ;
2002-12-12 22:02:25 +01:00
initPQExpBuffer ( & buf ) ;
2009-06-11 16:49:15 +02:00
2002-12-12 22:02:25 +01:00
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT pg_catalog.format_type(castsource, NULL) AS \" %s \" , \n "
2018-08-31 22:45:33 +02:00
" pg_catalog.format_type(casttarget, NULL) AS \" %s \" , \n " ,
2011-08-04 18:22:26 +02:00
gettext_noop ( " Source type " ) ,
2018-08-31 22:45:33 +02:00
gettext_noop ( " Target type " ) ) ;
/*
* We don ' t attempt to localize ' ( binary coercible ) ' or ' ( with inout ) ' ,
* because there ' s too much risk of gettext translating a function name
* that happens to match some string in the PO database .
*/
if ( pset . sversion > = 80400 )
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 " ) ) ;
else
appendPQExpBuffer ( & buf ,
" CASE WHEN c.castfunc = 0 THEN '(binary coercible)' \n "
" ELSE p.proname \n "
" END AS \" %s \" , \n " ,
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 ,
2011-08-04 18:22:26 +02:00
gettext_noop ( " no " ) ,
2018-08-31 22:45:33 +02:00
COERCION_CODE_ASSIGNMENT ,
2011-08-04 18:22:26 +02:00
gettext_noop ( " in assignment " ) ,
gettext_noop ( " yes " ) ,
gettext_noop ( " Implicit? " ) ) ;
if ( verbose )
appendPQExpBuffer ( & buf ,
2018-08-31 22:45:33 +02:00
" , \n d.description AS \" %s \" " ,
2011-08-04 18:22:26 +02:00
gettext_noop ( " Description " ) ) ;
2018-08-31 22:45:33 +02:00
/*
* We need a left join to pg_proc for binary casts ; the others are just
* paranoia .
*/
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
2018-08-31 22:45:33 +02:00
" \n FROM pg_catalog.pg_cast c LEFT JOIN pg_catalog.pg_proc p \n "
2013-11-18 17:29:01 +01:00
" 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 " ) ;
2011-08-04 18:22:26 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
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 " ) ;
2011-08-04 18:22:26 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " WHERE ( (true " ) ;
2002-12-12 22:02:25 +01:00
2008-11-06 16:18:36 +01:00
/*
* Match name pattern against either internal or external name of either
* castsource or casttarget
*/
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" ns.nspname " , " ts.typname " ,
" pg_catalog.format_type(ts.oid, NULL) " ,
" pg_catalog.pg_type_is_visible(ts.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ) OR (true " ) ;
2008-11-06 16:18:36 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" nt.nspname " , " tt.typname " ,
" pg_catalog.format_type(tt.oid, NULL) " ,
" pg_catalog.pg_type_is_visible(tt.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ) ) \n ORDER BY 1, 2; " ) ;
2008-11-06 16:18:36 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2002-12-12 22:02:25 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of casts " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2002-12-12 22:02:25 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2002-12-12 22:02:25 +01:00
PQclear ( res ) ;
return true ;
}
2011-02-12 14:54:13 +01:00
/*
* \ dO
*
2011-04-09 20:08:41 +02:00
* Describes collations .
2011-02-12 14:54:13 +01:00
*/
bool
listCollations ( const char * pattern , bool verbose , bool showSystem )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2019-03-22 12:09:32 +01:00
static const bool translate_columns [ ] = { false , false , false , false , false , true , false } ;
2011-02-12 14:54:13 +01:00
2012-05-10 09:11:38 +02:00
if ( pset . sversion < 90100 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support collations. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2012-05-10 09:11:38 +02:00
return true ;
}
2011-02-12 14:54:13 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT n.nspname AS \" %s \" , \n "
" c.collname AS \" %s \" , \n "
" c.collcollate AS \" %s \" , \n "
" c.collctype AS \" %s \" " ,
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Collate " ) ,
gettext_noop ( " Ctype " ) ) ;
2017-03-23 20:25:34 +01:00
if ( pset . sversion > = 100000 )
appendPQExpBuffer ( & buf ,
" , \n CASE c.collprovider WHEN 'd' THEN 'default' WHEN 'c' THEN 'libc' WHEN 'i' THEN 'icu' END AS \" %s \" " ,
gettext_noop ( " Provider " ) ) ;
2019-03-22 12:09:32 +01:00
else
appendPQExpBuffer ( & buf ,
" , \n 'libc' AS \" %s \" " ,
gettext_noop ( " Provider " ) ) ;
if ( pset . sversion > = 120000 )
appendPQExpBuffer ( & buf ,
" , \n CASE WHEN c.collisdeterministic THEN '%s' ELSE '%s' END AS \" %s \" " ,
gettext_noop ( " yes " ) , gettext_noop ( " no " ) ,
gettext_noop ( " Deterministic? " ) ) ;
else
appendPQExpBuffer ( & buf ,
" , \n '%s' AS \" %s \" " ,
gettext_noop ( " yes " ) ,
gettext_noop ( " Deterministic? " ) ) ;
2017-03-23 20:25:34 +01:00
2011-02-12 14:54:13 +01:00
if ( verbose )
appendPQExpBuffer ( & buf ,
2011-04-10 17:42:00 +02:00
" , \n pg_catalog.obj_description(c.oid, 'pg_collation') AS \" %s \" " ,
2011-02-12 14:54:13 +01:00
gettext_noop ( " Description " ) ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" \n FROM pg_catalog.pg_collation c, pg_catalog.pg_namespace n \n "
2014-05-06 18:12:18 +02:00
" WHERE n.oid = c.collnamespace \n " ) ;
2011-02-12 14:54:13 +01:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND n.nspname <> 'pg_catalog' \n "
2014-05-06 18:12:18 +02:00
" AND n.nspname <> 'information_schema' \n " ) ;
2011-02-12 14:54:13 +01:00
2011-04-09 20:08:41 +02:00
/*
* Hide collations that aren ' t usable in the current database ' s encoding .
* If you think to change this , note that pg_collation_is_visible rejects
* unusable collations , so you will need to hack name pattern processing
* somehow to avoid inconsistent behavior .
*/
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " AND c.collencoding IN (-1, pg_catalog.pg_char_to_encoding(pg_catalog.getdatabaseencoding())) \n " ) ;
2011-04-09 20:08:41 +02:00
2011-02-12 14:54:13 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.collname " , NULL ,
" pg_catalog.pg_collation_is_visible(c.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2011-02-12 14:54:13 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-02-12 14:54:13 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of collations " ) ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2011-02-12 14:54:13 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2011-02-12 14:54:13 +01:00
PQclear ( res ) ;
return true ;
}
2003-01-07 21:56:07 +01:00
/*
* \ dn
*
* Describes schemas ( namespaces )
*/
bool
2010-11-07 02:41:14 +01:00
listSchemas ( const char * pattern , bool verbose , bool showSystem )
2003-01-07 21:56:07 +01:00
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2004-08-29 07:07:03 +02:00
" SELECT n.nspname AS \" %s \" , \n "
2008-07-03 05:37:17 +02:00
" pg_catalog.pg_get_userbyid(n.nspowner) AS \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ) ;
2004-08-29 07:07:03 +02:00
2004-07-13 18:48:16 +02:00
if ( verbose )
2008-12-31 19:07:47 +01:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " n.nspacl " ) ;
2004-07-13 18:48:16 +02:00
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" , \n pg_catalog.obj_description(n.oid, 'pg_namespace') AS \" %s \" " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2008-12-31 19:07:47 +01:00
}
2004-08-29 07:07:03 +02:00
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_namespace n \n " ) ;
2004-07-13 18:48:16 +02:00
2010-11-07 02:41:14 +01:00
if ( ! showSystem & & ! pattern )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' \n " ) ;
2010-11-07 02:41:14 +01:00
processSQLNamePattern ( pset . db , & buf , pattern ,
! showSystem & & ! pattern , false ,
2006-10-10 01:30:33 +02:00
NULL , " n.nspname " , NULL ,
NULL ) ;
2003-01-07 21:56:07 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2003-01-07 21:56:07 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2003-01-07 21:56:07 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of schemas " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2003-01-07 21:56:07 +01:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2003-01-07 21:56:07 +01:00
PQclear ( res ) ;
return true ;
}
2007-08-21 03:11:32 +02:00
/*
* \ dFp
* list text search parsers
*/
bool
listTSParsers ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion < 80300 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support full text search. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-07-03 05:37:17 +02:00
return true ;
}
2007-08-21 03:11:32 +02:00
if ( verbose )
return listTSParsersVerbose ( pattern ) ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
2007-08-21 03:11:32 +02:00
" n.nspname as \" %s \" , \n "
" p.prsname as \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(p.oid, 'pg_ts_parser') as \" %s \" \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Description " )
2007-08-21 03:11:32 +02:00
) ;
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
" n.nspname " , " p.prsname " , NULL ,
" pg_catalog.pg_ts_parser_is_visible(p.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of text search parsers " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return true ;
}
/*
* full description of parsers
*/
static bool
listTSParsersVerbose ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
int i ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT p.oid, \n "
" n.nspname, \n "
" p.prsname \n "
2007-08-21 03:11:32 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = p.prsnamespace \n "
2007-08-21 03:11:32 +02:00
) ;
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
" n.nspname " , " p.prsname " , NULL ,
" pg_catalog.pg_ts_parser_is_visible(p.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
if ( PQntuples ( res ) = = 0 )
{
if ( ! pset . quiet )
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
{
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any text search parser named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any text search parsers. " ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
}
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return false ;
}
for ( i = 0 ; i < PQntuples ( res ) ; i + + )
{
const char * oid ;
const char * nspname = NULL ;
const char * 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 ) ;
return false ;
}
if ( cancel_pressed )
{
PQclear ( res ) ;
return false ;
}
}
PQclear ( res ) ;
return true ;
}
static bool
describeOneTSParser ( const char * oid , const char * nspname , const char * prsname )
{
PQExpBufferData buf ;
PGresult * res ;
2017-07-27 18:12:37 +02:00
PQExpBufferData title ;
2007-08-21 03:11:32 +02:00
printQueryOpt myopt = pset . popt ;
2008-07-15 00:00:04 +02:00
static const bool translate_columns [ ] = { true , false , false } ;
2007-08-21 03:11:32 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT '%s' AS \" %s \" , \n "
" p.prsstart::pg_catalog.regproc AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(p.prsstart, 'pg_proc') as \" %s \" \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
" WHERE p.oid = '%s' \n "
" UNION ALL \n "
" SELECT '%s', \n "
" p.prstoken::pg_catalog.regproc, \n "
2017-05-17 22:31:56 +02:00
" pg_catalog.obj_description(p.prstoken, 'pg_proc') \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
" WHERE p.oid = '%s' \n "
" UNION ALL \n "
" SELECT '%s', \n "
" p.prsend::pg_catalog.regproc, \n "
" pg_catalog.obj_description(p.prsend, 'pg_proc') \n "
" FROM pg_catalog.pg_ts_parser p \n "
" WHERE p.oid = '%s' \n "
" UNION ALL \n "
" SELECT '%s', \n "
" p.prsheadline::pg_catalog.regproc, \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(p.prsheadline, 'pg_proc') \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
" WHERE p.oid = '%s' \n "
" UNION ALL \n "
" SELECT '%s', \n "
" p.prslextype::pg_catalog.regproc, \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(p.prslextype, 'pg_proc') \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_parser p \n "
2011-07-06 16:11:20 +02:00
" WHERE p.oid = '%s'; " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Start parse " ) ,
gettext_noop ( " Method " ) ,
gettext_noop ( " Function " ) ,
gettext_noop ( " Description " ) ,
2007-08-21 03:11:32 +02:00
oid ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Get next token " ) ,
oid ,
gettext_noop ( " End parse " ) ,
oid ,
gettext_noop ( " Get headline " ) ,
oid ,
gettext_noop ( " Get token types " ) ,
oid ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2017-07-27 18:12:37 +02:00
initPQExpBuffer ( & title ) ;
2007-08-21 03:11:32 +02:00
if ( nspname )
2017-07-27 18:12:37 +02:00
printfPQExpBuffer ( & title , _ ( " Text search parser \" %s.%s \" " ) ,
nspname , prsname ) ;
2007-08-21 03:11:32 +02:00
else
2017-07-27 18:12:37 +02:00
printfPQExpBuffer ( & title , _ ( " Text search parser \" %s \" " ) , prsname ) ;
myopt . title = title . data ;
2007-08-21 03:11:32 +02:00
myopt . footers = NULL ;
2012-05-01 22:03:45 +02:00
myopt . topt . default_footer = false ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = lengthof ( translate_columns ) ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT t.alias as \" %s \" , \n "
" t.description as \" %s \" \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" FROM pg_catalog.ts_token_type( '%s'::pg_catalog.oid ) as t \n "
2007-08-21 03:11:32 +02:00
" ORDER BY 1; " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Token name " ) ,
gettext_noop ( " Description " ) ,
2007-08-21 03:11:32 +02:00
oid ) ;
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
if ( nspname )
2017-07-27 18:12:37 +02:00
printfPQExpBuffer ( & title , _ ( " Token types for parser \" %s.%s \" " ) ,
nspname , prsname ) ;
2007-08-21 03:11:32 +02:00
else
2017-07-27 18:12:37 +02:00
printfPQExpBuffer ( & title , _ ( " Token types for parser \" %s \" " ) , prsname ) ;
myopt . title = title . data ;
2007-08-21 03:11:32 +02:00
myopt . footers = NULL ;
2012-05-01 22:03:45 +02:00
myopt . topt . default_footer = true ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
myopt . translate_columns = NULL ;
Fix translatability markings in psql, and add defenses against future bugs.
Several previous commits have added columns to various \d queries without
updating their translate_columns[] arrays, leading to potentially incorrect
translations in NLS-enabled builds. Offenders include commit 893686762
(added prosecdef to \df+), c9ac00e6e (added description to \dc+) and
3b17efdfd (added description to \dC+). Fix those cases back to 9.3 or
9.2 as appropriate.
Since this is evidently more easily missed than one would like, in HEAD
also add an Assert that the supplied array is long enough. This requires
an API change for printQuery(), so it seems inappropriate for back
branches, but presumably all future changes will be tested in HEAD anyway.
In HEAD and 9.3, also clean up a whole lot of sloppiness in the emitted
SQL for \dy (event triggers): lack of translatability due to failing to
pass words-to-be-translated through gettext_noop(), inadequate schema
qualification, and sloppy formatting resulting in unnecessarily ugly
-E output.
Peter Eisentraut and Tom Lane, per bug #8702 from Sergey Burladyan
2014-01-04 22:05:16 +01:00
myopt . n_translate_columns = 0 ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
2017-07-27 18:12:37 +02:00
termPQExpBuffer ( & title ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return true ;
}
/*
* \ dFd
* list text search dictionaries
*/
bool
listTSDictionaries ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion < 80300 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support full text search. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-07-03 05:37:17 +02:00
return true ;
}
2007-08-21 03:11:32 +02:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
2007-08-21 03:11:32 +02:00
" n.nspname as \" %s \" , \n "
" d.dictname as \" %s \" , \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ) ;
2007-08-21 03:11:32 +02:00
if ( verbose )
{
appendPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" ( SELECT COALESCE(nt.nspname, '(null)')::pg_catalog.text || '.' || t.tmplname FROM \n "
" pg_catalog.pg_ts_template t \n "
" LEFT JOIN pg_catalog.pg_namespace nt ON nt.oid = t.tmplnamespace \n "
" WHERE d.dicttemplate = t.oid ) AS \" %s \" , \n "
" d.dictinitoption as \" %s \" , \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Template " ) ,
gettext_noop ( " Init options " ) ) ;
2007-08-21 03:11:32 +02:00
}
appendPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(d.oid, 'pg_ts_dict') as \" %s \" \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Description " ) ) ;
2007-08-21 03:11:32 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " FROM pg_catalog.pg_ts_dict d \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = d.dictnamespace \n " ) ;
2007-08-21 03:11:32 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
" n.nspname " , " d.dictname " , NULL ,
" pg_catalog.pg_ts_dict_is_visible(d.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of text search dictionaries " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return true ;
}
/*
* \ dFt
* list text search templates
*/
bool
listTSTemplates ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion < 80300 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support full text search. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-07-03 05:37:17 +02:00
return true ;
}
2007-08-21 03:11:32 +02:00
initPQExpBuffer ( & buf ) ;
2007-08-22 04:25:34 +02:00
if ( verbose )
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
2007-08-22 04:25:34 +02:00
" n.nspname AS \" %s \" , \n "
" t.tmplname AS \" %s \" , \n "
" t.tmplinit::pg_catalog.regproc AS \" %s \" , \n "
" t.tmpllexize::pg_catalog.regproc AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \" %s \" \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Init " ) ,
gettext_noop ( " Lexize " ) ,
gettext_noop ( " Description " ) ) ;
2007-08-22 04:25:34 +02:00
else
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
2007-08-22 04:25:34 +02:00
" n.nspname AS \" %s \" , \n "
" t.tmplname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(t.oid, 'pg_ts_template') AS \" %s \" \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Description " ) ) ;
2007-08-21 03:11:32 +02:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " FROM pg_catalog.pg_ts_template t \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = t.tmplnamespace \n " ) ;
2007-08-21 03:11:32 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
" n.nspname " , " t.tmplname " , NULL ,
" pg_catalog.pg_ts_template_is_visible(t.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of text search templates " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return true ;
}
/*
* \ dF
* list text search configurations
*/
bool
listTSConfigs ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-07-03 05:37:17 +02:00
if ( pset . sversion < 80300 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support full text search. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-07-03 05:37:17 +02:00
return true ;
}
2007-08-21 03:11:32 +02:00
if ( verbose )
return listTSConfigsVerbose ( pattern ) ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
2007-08-21 03:11:32 +02:00
" n.nspname as \" %s \" , \n "
" c.cfgname as \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.obj_description(c.oid, 'pg_ts_config') as \" %s \" \n "
2007-08-21 03:11:32 +02:00
" FROM pg_catalog.pg_ts_config c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace \n " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Schema " ) ,
gettext_noop ( " Name " ) ,
gettext_noop ( " Description " )
2007-08-21 03:11:32 +02:00
) ;
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
" n.nspname " , " c.cfgname " , NULL ,
" pg_catalog.pg_ts_config_is_visible(c.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of text search configurations " ) ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return true ;
}
static bool
listTSConfigsVerbose ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
int i ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT c.oid, c.cfgname, \n "
2017-04-14 05:47:46 +02:00
" n.nspname, \n "
" p.prsname, \n "
" np.nspname as pnspname \n "
" FROM pg_catalog.pg_ts_config c \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.cfgnamespace, \n "
2017-04-14 05:47:46 +02:00
" pg_catalog.pg_ts_parser p \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace np ON np.oid = p.prsnamespace \n "
2007-08-21 03:11:32 +02:00
" WHERE p.oid = c.cfgparser \n "
) ;
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
" n.nspname " , " c.cfgname " , NULL ,
" pg_catalog.pg_ts_config_is_visible(c.oid) " ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 3, 2; " ) ;
2007-08-21 03:11:32 +02:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
if ( PQntuples ( res ) = = 0 )
{
if ( ! pset . quiet )
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
{
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any text search configuration named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any text search configurations. " ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
}
2007-08-21 03:11:32 +02:00
PQclear ( res ) ;
return false ;
}
for ( i = 0 ; i < PQntuples ( res ) ; i + + )
{
const char * oid ;
const char * cfgname ;
const char * nspname = NULL ;
const char * prsname ;
const char * 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 ) ;
return false ;
}
if ( cancel_pressed )
{
PQclear ( res ) ;
return false ;
}
}
PQclear ( res ) ;
return true ;
}
static bool
describeOneTSConfig ( const char * oid , const char * nspname , const char * cfgname ,
const char * pnspname , const char * prsname )
{
PQExpBufferData buf ,
title ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-04-14 05:47:46 +02:00
" SELECT \n "
" ( SELECT t.alias FROM \n "
" pg_catalog.ts_token_type(c.cfgparser) AS t \n "
" WHERE t.tokid = m.maptokentype ) AS \" %s \" , \n "
" pg_catalog.btrim( \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" ARRAY( SELECT mm.mapdict::pg_catalog.regdictionary \n "
2017-04-14 05:47:46 +02:00
" FROM pg_catalog.pg_ts_config_map AS mm \n "
" WHERE mm.mapcfg = m.mapcfg AND mm.maptokentype = m.maptokentype \n "
" ORDER BY mapcfg, maptokentype, mapseqno \n "
" ) :: pg_catalog.text, \n "
" '{}') AS \" %s \" \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" FROM pg_catalog.pg_ts_config AS c, pg_catalog.pg_ts_config_map AS m \n "
2017-04-14 05:47:46 +02:00
" WHERE c.oid = '%s' AND m.mapcfg = c.oid \n "
" GROUP BY m.mapcfg, m.maptokentype, c.cfgparser \n "
2011-07-06 16:11:20 +02:00
" ORDER BY 1; " ,
2007-12-12 22:41:47 +01:00
gettext_noop ( " Token " ) ,
gettext_noop ( " Dictionaries " ) ,
2007-08-21 03:11:32 +02:00
oid ) ;
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
initPQExpBuffer ( & title ) ;
if ( nspname )
2007-12-12 22:41:47 +01:00
appendPQExpBuffer ( & title , _ ( " Text search configuration \" %s.%s \" " ) ,
nspname , cfgname ) ;
2007-08-21 03:11:32 +02:00
else
2007-12-12 22:41:47 +01:00
appendPQExpBuffer ( & title , _ ( " Text search configuration \" %s \" " ) ,
cfgname ) ;
2007-08-21 03:11:32 +02:00
if ( pnspname )
2007-12-12 22:41:47 +01:00
appendPQExpBuffer ( & title , _ ( " \n Parser: \" %s.%s \" " ) ,
pnspname , prsname ) ;
2007-08-21 03:11:32 +02:00
else
2007-12-12 22:41:47 +01:00
appendPQExpBuffer ( & title , _ ( " \n Parser: \" %s \" " ) ,
prsname ) ;
2007-08-21 03:11:32 +02:00
myopt . nullPrint = NULL ;
myopt . title = title . data ;
myopt . footers = NULL ;
2012-05-01 22:03:45 +02:00
myopt . topt . default_footer = false ;
2008-07-15 00:00:04 +02:00
myopt . translate_header = true ;
2007-08-21 03:11:32 +02:00
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2007-08-21 03:11:32 +02:00
termPQExpBuffer ( & title ) ;
PQclear ( res ) ;
return true ;
}
2008-12-19 17:25:19 +01:00
/*
* \ dew
*
* Describes foreign - data wrappers
*/
bool
listForeignDataWrappers ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-12-31 19:33:03 +01:00
if ( pset . sversion < 80400 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support foreign-data wrappers. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-12-31 19:33:03 +01:00
return true ;
}
2008-12-19 17:25:19 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2011-08-08 22:29:57 +02:00
" SELECT fdw.fdwname AS \" %s \" , \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" pg_catalog.pg_get_userbyid(fdw.fdwowner) AS \" %s \" , \n " ,
2008-12-19 17:25:19 +01:00
gettext_noop ( " Name " ) ,
2011-02-19 06:06:18 +01:00
gettext_noop ( " Owner " ) ) ;
if ( pset . sversion > = 90100 )
appendPQExpBuffer ( & buf ,
2011-08-08 22:29:57 +02:00
" fdw.fdwhandler::pg_catalog.regproc AS \" %s \" , \n " ,
2011-02-19 06:06:18 +01:00
gettext_noop ( " Handler " ) ) ;
appendPQExpBuffer ( & buf ,
2011-08-08 22:29:57 +02:00
" fdw.fdwvalidator::pg_catalog.regproc AS \" %s \" " ,
2009-02-24 11:06:36 +01:00
gettext_noop ( " Validator " ) ) ;
2008-12-19 17:25:19 +01:00
if ( verbose )
2008-12-31 19:07:47 +01:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " fdwacl " ) ;
2008-12-19 17:25:19 +01:00
appendPQExpBuffer ( & buf ,
2011-08-25 18:47:30 +02:00
" , \n CASE WHEN fdwoptions IS NULL THEN '' ELSE "
2017-07-27 01:35:35 +02:00
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
" pg_catalog.quote_ident(option_name) || ' ' || "
" pg_catalog.quote_literal(option_value) FROM "
" pg_catalog.pg_options_to_table(fdwoptions)), ', ') || ')' "
2011-08-25 18:47:30 +02:00
" END AS \" %s \" " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " FDW options " ) ) ;
2011-08-08 22:29:57 +02:00
if ( pset . sversion > = 90100 )
appendPQExpBuffer ( & buf ,
" , \n d.description AS \" %s \" " ,
gettext_noop ( " Description " ) ) ;
2008-12-31 19:07:47 +01:00
}
2008-12-19 17:25:19 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_foreign_data_wrapper fdw \n " ) ;
2011-08-08 22:29:57 +02:00
if ( verbose & & pset . sversion > = 90100 )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" LEFT JOIN pg_catalog.pg_description d \n "
" ON d.classoid = fdw.tableoid "
" AND d.objoid = fdw.oid AND d.objsubid = 0 \n " ) ;
2008-12-19 17:25:19 +01:00
2008-12-31 19:07:47 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
2008-12-19 17:25:19 +01:00
NULL , " fdwname " , NULL , NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2008-12-19 17:25:19 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2008-12-19 17:25:19 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of foreign-data wrappers " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2008-12-19 17:25:19 +01:00
PQclear ( res ) ;
return true ;
}
/*
* \ des
*
2009-03-25 14:11:43 +01:00
* Describes foreign servers .
2008-12-19 17:25:19 +01:00
*/
bool
listForeignServers ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-12-31 19:33:03 +01:00
if ( pset . sversion < 80400 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support foreign servers. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-12-31 19:33:03 +01:00
return true ;
}
2008-12-19 17:25:19 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT s.srvname AS \" %s \" , \n "
" pg_catalog.pg_get_userbyid(s.srvowner) AS \" %s \" , \n "
2008-12-31 19:07:47 +01:00
" f.fdwname AS \" %s \" " ,
2008-12-19 17:25:19 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ,
gettext_noop ( " Foreign-data wrapper " ) ) ;
if ( verbose )
2008-12-31 19:07:47 +01:00
{
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " , \n " ) ;
2008-12-31 19:07:47 +01:00
printACLColumn ( & buf , " s.srvacl " ) ;
2008-12-19 17:25:19 +01:00
appendPQExpBuffer ( & buf ,
2008-12-31 19:07:47 +01:00
" , \n "
" s.srvtype AS \" %s \" , \n "
" s.srvversion AS \" %s \" , \n "
2011-08-25 18:47:30 +02:00
" CASE WHEN srvoptions IS NULL THEN '' ELSE "
2017-07-27 01:35:35 +02:00
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
" pg_catalog.quote_ident(option_name) || ' ' || "
" pg_catalog.quote_literal(option_value) FROM "
" pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')' "
2011-08-25 18:47:30 +02:00
" END AS \" %s \" , \n "
2011-08-08 22:29:57 +02:00
" d.description AS \" %s \" " ,
2008-12-19 17:25:19 +01:00
gettext_noop ( " Type " ) ,
gettext_noop ( " Version " ) ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " FDW options " ) ,
2011-08-08 22:29:57 +02:00
gettext_noop ( " Description " ) ) ;
2008-12-31 19:07:47 +01:00
}
2008-12-19 17:25:19 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_foreign_server s \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid=s.srvfdw \n " ) ;
2008-12-19 17:25:19 +01:00
2011-08-08 22:29:57 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
2017-07-27 01:35:35 +02:00
" LEFT JOIN pg_catalog.pg_description d \n "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" ON d.classoid = s.tableoid AND d.objoid = s.oid "
2013-11-18 17:29:01 +01:00
" AND d.objsubid = 0 \n " ) ;
2011-08-08 22:29:57 +02:00
2008-12-31 19:07:47 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
2008-12-19 17:25:19 +01:00
NULL , " s.srvname " , NULL , NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2008-12-19 17:25:19 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2008-12-19 17:25:19 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of foreign servers " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2008-12-19 17:25:19 +01:00
PQclear ( res ) ;
return true ;
}
/*
* \ deu
*
* Describes user mappings .
*/
bool
listUserMappings ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2008-12-31 19:33:03 +01:00
if ( pset . sversion < 80400 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support user mappings. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2008-12-31 19:33:03 +01:00
return true ;
}
2008-12-19 17:25:19 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT um.srvname AS \" %s \" , \n "
" um.usename AS \" %s \" " ,
gettext_noop ( " Server " ) ,
2009-03-25 14:11:43 +01:00
gettext_noop ( " User name " ) ) ;
2008-12-19 17:25:19 +01:00
if ( verbose )
appendPQExpBuffer ( & buf ,
2011-08-25 18:47:30 +02:00
" , \n CASE WHEN umoptions IS NULL THEN '' ELSE "
2017-07-27 01:35:35 +02:00
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
" pg_catalog.quote_ident(option_name) || ' ' || "
" pg_catalog.quote_literal(option_value) FROM "
" pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' "
2011-08-25 18:47:30 +02:00
" END AS \" %s \" " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " FDW options " ) ) ;
2008-12-19 17:25:19 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " \n FROM pg_catalog.pg_user_mappings um \n " ) ;
2008-12-19 17:25:19 +01:00
2008-12-31 19:07:47 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
2008-12-19 17:25:19 +01:00
NULL , " um.srvname " , " um.usename " , NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2008-12-19 17:25:19 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2008-12-19 17:25:19 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of user mappings " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2008-12-19 17:25:19 +01:00
PQclear ( res ) ;
return true ;
}
2008-12-31 19:07:47 +01:00
2011-01-02 05:48:11 +01:00
/*
* \ det
*
* Describes foreign tables .
*/
bool
listForeignTables ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
if ( pset . sversion < 90100 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support foreign tables. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2011-01-02 05:48:11 +01:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT n.nspname AS \" %s \" , \n "
" c.relname AS \" %s \" , \n "
" s.srvname AS \" %s \" " ,
gettext_noop ( " Schema " ) ,
gettext_noop ( " Table " ) ,
gettext_noop ( " Server " ) ) ;
if ( verbose )
appendPQExpBuffer ( & buf ,
2011-08-25 18:47:30 +02:00
" , \n CASE WHEN ftoptions IS NULL THEN '' ELSE "
2017-07-27 01:35:35 +02:00
" '(' || pg_catalog.array_to_string(ARRAY(SELECT "
" pg_catalog.quote_ident(option_name) || ' ' || "
" pg_catalog.quote_literal(option_value) FROM "
" pg_catalog.pg_options_to_table(ftoptions)), ', ') || ')' "
2011-08-25 18:47:30 +02:00
" END AS \" %s \" , \n "
2011-08-08 22:29:57 +02:00
" d.description AS \" %s \" " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " FDW options " ) ,
2011-08-08 22:29:57 +02:00
gettext_noop ( " Description " ) ) ;
2011-01-02 05:48:11 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_foreign_table ft \n "
" INNER JOIN pg_catalog.pg_class c "
" ON c.oid = ft.ftrelid \n "
" INNER JOIN pg_catalog.pg_namespace n "
" ON n.oid = c.relnamespace \n "
" INNER JOIN pg_catalog.pg_foreign_server s "
" ON s.oid = ft.ftserver \n " ) ;
2011-08-08 22:29:57 +02:00
if ( verbose )
2013-11-18 17:29:01 +01:00
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 " ) ;
2011-01-02 05:48:11 +01:00
2011-08-08 22:29:57 +02:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
2016-01-29 10:28:02 +01:00
" n.nspname " , " c.relname " , NULL ,
" pg_catalog.pg_table_is_visible(c.oid) " ) ;
2011-01-02 05:48:11 +01:00
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1, 2; " ) ;
2011-01-02 05:48:11 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-01-02 05:48:11 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of foreign tables " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2011-01-02 05:48:11 +01:00
PQclear ( res ) ;
return true ;
}
2011-02-08 22:08:41 +01:00
/*
* \ dx
*
* Briefly describes installed extensions .
*/
bool
listExtensions ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
if ( pset . sversion < 90100 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support extensions. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2011-02-08 22:08:41 +01:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT e.extname AS \" %s \" , "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" e.extversion AS \" %s \" , n.nspname AS \" %s \" , c.description AS \" %s \" \n "
2011-02-08 22:08:41 +01:00
" FROM pg_catalog.pg_extension e "
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" LEFT JOIN pg_catalog.pg_namespace n ON n.oid = e.extnamespace "
" LEFT JOIN pg_catalog.pg_description c ON c.objoid = e.oid "
" AND c.classoid = 'pg_catalog.pg_extension'::pg_catalog.regclass \n " ,
2011-02-08 22:08:41 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Version " ) ,
gettext_noop ( " Schema " ) ,
gettext_noop ( " Description " ) ) ;
processSQLNamePattern ( pset . db , & buf , pattern ,
false , false ,
NULL , " e.extname " , NULL ,
NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2011-02-08 22:08:41 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-02-08 22:08:41 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of installed extensions " ) ;
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2011-02-08 22:08:41 +01:00
PQclear ( res ) ;
return true ;
}
/*
* \ dx +
*
* List contents of installed extensions .
*/
bool
listExtensionContents ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
int i ;
if ( pset . sversion < 90100 )
{
Fix assorted places in psql to print version numbers >= 10 in new style.
This is somewhat cosmetic, since as long as you know what you are looking
at, "10.0" is a serviceable substitute for "10". But there is a potential
for confusion between version numbers with minor numbers and those without
--- we don't want people asking "why is psql saying 10.0 when my server is
10.2". Therefore, back-patch as far as practical, which turns out to be
9.3. I could have redone the patch to use fprintf(stderr) in place of
psql_error(), but it seems more work than is warranted for branches that
will be EOL or nearly so by the time v10 comes out.
Although only psql seems to contain any code that needs this, I chose
to put the support function into fe_utils, since it seems likely we'll
need it in other client programs in future. (In 9.3-9.5, use dumputils.c,
the predecessor of fe_utils/string_utils.c.)
In HEAD, also fix the backend code that whines about loadable-library
version mismatch. I don't see much need to back-patch that.
2016-08-16 21:58:30 +02:00
char sverbuf [ 32 ] ;
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support extensions. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2011-02-08 22:08:41 +01:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT e.extname, e.oid \n "
" FROM pg_catalog.pg_extension e \n " ) ;
processSQLNamePattern ( pset . db , & buf , pattern ,
false , false ,
NULL , " e.extname " , NULL ,
NULL ) ;
2013-11-18 17:29:01 +01:00
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
2011-02-08 22:08:41 +01:00
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-02-08 22:08:41 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
if ( PQntuples ( res ) = = 0 )
{
if ( ! pset . quiet )
{
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any extension named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
2011-02-08 22:08:41 +01:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any extensions. " ) ;
2011-02-08 22:08:41 +01:00
}
PQclear ( res ) ;
return false ;
}
for ( i = 0 ; i < PQntuples ( res ) ; i + + )
{
const char * extname ;
const char * oid ;
extname = PQgetvalue ( res , i , 0 ) ;
oid = PQgetvalue ( res , i , 1 ) ;
if ( ! listOneExtensionContents ( extname , oid ) )
{
PQclear ( res ) ;
return false ;
}
if ( cancel_pressed )
{
PQclear ( res ) ;
return false ;
}
}
PQclear ( res ) ;
return true ;
}
static bool
listOneExtensionContents ( const char * extname , const char * oid )
{
PQExpBufferData buf ;
PGresult * res ;
2017-07-27 18:12:37 +02:00
PQExpBufferData title ;
2011-02-08 22:08:41 +01:00
printQueryOpt myopt = pset . popt ;
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
Phase 3 of pgindent updates.
Don't move parenthesized lines to the left, even if that means they
flow past the right margin.
By default, BSD indent lines up statement continuation lines that are
within parentheses so that they start just to the right of the preceding
left parenthesis. However, traditionally, if that resulted in the
continuation line extending to the right of the desired right margin,
then indent would push it left just far enough to not overrun the margin,
if it could do so without making the continuation line start to the left of
the current statement indent. That makes for a weird mix of indentations
unless one has been completely rigid about never violating the 80-column
limit.
This behavior has been pretty universally panned by Postgres developers.
Hence, disable it with indent's new -lpl switch, so that parenthesized
lines are always lined up with the preceding left paren.
This patch is much less interesting than the first round of indent
changes, but also bulkier, so I thought it best to separate the effects.
Discussion: https://postgr.es/m/E1dAmxK-0006EE-1r@gemulon.postgresql.org
Discussion: https://postgr.es/m/30527.1495162840@sss.pgh.pa.us
2017-06-21 21:35:54 +02:00
" SELECT pg_catalog.pg_describe_object(classid, objid, 0) AS \" %s \" \n "
2011-02-08 22:08:41 +01:00
" FROM pg_catalog.pg_depend \n "
" WHERE refclassid = 'pg_catalog.pg_extension'::pg_catalog.regclass AND refobjid = '%s' AND deptype = 'e' \n "
" ORDER BY 1; " ,
2017-06-13 20:38:35 +02:00
gettext_noop ( " Object description " ) ,
2011-02-08 22:08:41 +01:00
oid ) ;
2014-10-23 15:33:56 +02:00
res = PSQLexec ( buf . data ) ;
2011-02-08 22:08:41 +01:00
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
2017-07-27 18:12:37 +02:00
initPQExpBuffer ( & title ) ;
printfPQExpBuffer ( & title , _ ( " Objects in extension \" %s \" " ) , extname ) ;
myopt . title = title . data ;
2011-02-08 22:08:41 +01:00
myopt . translate_header = true ;
Fix behavior of printTable() and friends with externally-invoked pager.
The formatting modes that depend on knowledge of the terminal window width
did not work right when printing a query result that's been fetched in
sections (as a result of FETCH_SIZE). ExecQueryUsingCursor() would force
use of the pager as soon as there's more than one result section, and then
print.c would see an output file pointer that's not stdout and incorrectly
conclude that the terminal window width isn't relevant.
This has been broken all along for non-expanded "wrapped" output format,
and as of 9.5 the issue affects expanded mode as well. The problem also
caused "\pset expanded auto" mode to invariably *not* switch to expanded
output in a segmented result, which seems to me to be exactly backwards.
To fix, we need to pass down an "is_pager" flag to inform the print.c
subroutines that some calling level has already replaced stdout with a
pager pipe, so they should (a) not do that again and (b) nonetheless honor
the window size. (Notably, this makes the first is_pager test in
print_aligned_text() not be dead code anymore.)
This patch is a bit invasive because there are so many existing calls of
printQuery()/printTable(), but fortunately all but a couple can just pass
"false" for the added parameter.
Back-patch to 9.5 but no further. Given the lack of field complaints,
it's not clear that we should change the behavior in stable branches.
Also, the API change for printQuery()/printTable() might possibly break
third-party code, again something we don't like to do in stable branches.
However, it's not quite too late to do this in 9.5, and with the larger
scope of the problem there, it seems worth doing.
2015-12-03 00:20:33 +01:00
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
2011-02-08 22:08:41 +01:00
2017-07-27 18:12:37 +02:00
termPQExpBuffer ( & title ) ;
2011-02-08 22:08:41 +01:00
PQclear ( res ) ;
return true ;
}
2017-07-27 17:57:29 +02:00
/*
* \ dRp
2017-01-19 18:00:00 +01:00
* Lists publications .
*
* Takes an optional regexp to select particular publications
*/
bool
listPublications ( const char * pattern )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2018-04-07 17:24:53 +02:00
static const bool translate_columns [ ] = { false , false , false , false , false , false , false } ;
2017-01-19 18:00:00 +01:00
if ( pset . sversion < 100000 )
{
char sverbuf [ 32 ] ;
2017-05-17 22:31:56 +02:00
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support publications. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2017-01-19 18:00:00 +01:00
return true ;
}
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
" SELECT pubname AS \" %s \" , \n "
" pg_catalog.pg_get_userbyid(pubowner) AS \" %s \" , \n "
2017-06-15 16:46:41 +02:00
" puballtables AS \" %s \" , \n "
2017-01-19 18:00:00 +01:00
" pubinsert AS \" %s \" , \n "
" pubupdate AS \" %s \" , \n "
2018-04-07 17:24:53 +02:00
" pubdelete AS \" %s \" " ,
2017-01-19 18:00:00 +01:00
gettext_noop ( " Name " ) ,
gettext_noop ( " Owner " ) ,
2017-06-15 16:46:41 +02:00
gettext_noop ( " All tables " ) ,
2017-01-19 18:00:00 +01:00
gettext_noop ( " Inserts " ) ,
gettext_noop ( " Updates " ) ,
gettext_noop ( " Deletes " ) ) ;
2018-04-07 17:24:53 +02:00
if ( pset . sversion > = 110000 )
appendPQExpBuffer ( & buf ,
" , \n pubtruncate AS \" %s \" " ,
gettext_noop ( " Truncates " ) ) ;
2017-01-19 18:00:00 +01:00
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_publication \n " ) ;
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " pubname " , NULL ,
NULL ) ;
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
res = PSQLexec ( buf . data ) ;
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of publications " ) ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
myopt . n_translate_columns = lengthof ( translate_columns ) ;
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
PQclear ( res ) ;
return true ;
}
2017-07-27 17:57:29 +02:00
/*
* \ dRp +
2017-01-19 18:00:00 +01:00
* Describes publications including the contents .
*
* Takes an optional regexp to select particular publications
*/
bool
describePublications ( const char * pattern )
{
PQExpBufferData buf ;
2017-05-17 22:31:56 +02:00
int i ;
PGresult * res ;
2018-04-07 17:24:53 +02:00
bool has_pubtruncate ;
2017-01-19 18:00:00 +01:00
if ( pset . sversion < 100000 )
{
char sverbuf [ 32 ] ;
2017-05-17 22:31:56 +02:00
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support publications. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2017-01-19 18:00:00 +01:00
return true ;
}
2018-04-07 17:24:53 +02:00
has_pubtruncate = ( pset . sversion > = 110000 ) ;
2017-01-19 18:00:00 +01:00
initPQExpBuffer ( & buf ) ;
printfPQExpBuffer ( & buf ,
2017-07-28 23:44:48 +02:00
" SELECT oid, pubname, \n "
" pg_catalog.pg_get_userbyid(pubowner) AS owner, \n "
2018-04-07 17:24:53 +02:00
" puballtables, pubinsert, pubupdate, pubdelete " ) ;
if ( has_pubtruncate )
2019-07-04 03:01:13 +02:00
appendPQExpBufferStr ( & buf ,
" , pubtruncate " ) ;
appendPQExpBufferStr ( & buf ,
" \n FROM pg_catalog.pg_publication \n " ) ;
2017-01-19 18:00:00 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , false , false ,
NULL , " pubname " , NULL ,
NULL ) ;
appendPQExpBufferStr ( & buf , " ORDER BY 2; " ) ;
res = PSQLexec ( buf . data ) ;
if ( ! res )
{
termPQExpBuffer ( & buf ) ;
return false ;
}
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
if ( PQntuples ( res ) = = 0 )
{
if ( ! pset . quiet )
{
if ( pattern )
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any publication named \" %s \" . " ,
2019-05-22 18:55:34 +02:00
pattern ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
else
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " Did not find any publications. " ) ;
Standardize describe.c's behavior for no-matching-objects a bit more.
Most functions in this file are content to print an empty table if there
are no matching objects. In some, the behavior is to loop over all
matching objects and print a table for each one; therefore, without any
extra logic, nothing at all would be printed if no objects match.
We accept that outcome in QUIET mode, but in normal mode it seems better
to print a helpful message. The new \dRp+ command had not gotten that
memo; fix it.
listDbRoleSettings() is out of step on this, but I think it's better for
it to print a custom message rather than an empty table, because of the
possibility that the user is confused about what the pattern arguments mean
or which is which. The original message wording was entirely useless for
clarifying that, though, not to mention being unlike the wordings used
elsewhere. Improve the text, and also print the messages with psql_error
as is the general custom here.
listTables() is also out in left field, but since it's such a heavily
used function, I'm hesitant to change its behavior so much as to print
an empty table rather than a custom message. People are probably used
to getting a message. But we can make the wording more standardized and
helpful, and print it with psql_error rather than printing to stdout.
In both listDbRoleSettings and listTables, we play dumb and emit an
empty table, not a custom message, in QUIET mode. That was true before
and I see no need to change it.
Several of the places printing such messages risked dumping core if
no pattern string had been provided; make them more wary. (This case
is presently unreachable in describeTableDetails; but it shouldn't be
assuming that command.c will never pass it a null. The text search
functions would only reach the case if a database contained no text
search objects, which is also currently impossible since we pin the
built-in objects, but again it seems unwise to assume that here.)
Daniel Gustafsson, tweaked a bit by me
Discussion: https://postgr.es/m/3641F19B-336A-431A-86CE-A80562505C5E@yesql.se
2017-07-27 19:30:59 +02:00
}
termPQExpBuffer ( & buf ) ;
PQclear ( res ) ;
return false ;
}
2017-01-19 18:00:00 +01:00
for ( i = 0 ; i < PQntuples ( res ) ; i + + )
{
const char align = ' l ' ;
2017-07-28 23:44:48 +02:00
int ncols = 5 ;
2017-01-19 18:00:00 +01:00
int nrows = 1 ;
int tables = 0 ;
PGresult * tabres ;
char * pubid = PQgetvalue ( res , i , 0 ) ;
char * pubname = PQgetvalue ( res , i , 1 ) ;
2017-07-28 23:44:48 +02:00
bool puballtables = strcmp ( PQgetvalue ( res , i , 3 ) , " t " ) = = 0 ;
2017-01-19 18:00:00 +01:00
int j ;
PQExpBufferData title ;
printTableOpt myopt = pset . popt . topt ;
printTableContent cont ;
2018-04-07 17:24:53 +02:00
if ( has_pubtruncate )
ncols + + ;
2017-01-19 18:00:00 +01:00
initPQExpBuffer ( & title ) ;
printfPQExpBuffer ( & title , _ ( " Publication %s " ) , pubname ) ;
printTableInit ( & cont , & myopt , title . data , ncols , nrows ) ;
2017-07-28 23:44:48 +02:00
printTableAddHeader ( & cont , gettext_noop ( " Owner " ) , true , align ) ;
2017-06-15 16:46:41 +02:00
printTableAddHeader ( & cont , gettext_noop ( " All tables " ) , true , align ) ;
2017-01-19 18:00:00 +01:00
printTableAddHeader ( & cont , gettext_noop ( " Inserts " ) , true , align ) ;
printTableAddHeader ( & cont , gettext_noop ( " Updates " ) , true , align ) ;
printTableAddHeader ( & cont , gettext_noop ( " Deletes " ) , true , align ) ;
2018-04-07 17:24:53 +02:00
if ( has_pubtruncate )
printTableAddHeader ( & cont , gettext_noop ( " Truncates " ) , true , align ) ;
2017-01-19 18:00:00 +01:00
2017-06-15 16:46:41 +02:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 2 ) , false , false ) ;
2017-01-19 18:00:00 +01:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 3 ) , false , false ) ;
printTableAddCell ( & cont , PQgetvalue ( res , i , 4 ) , false , false ) ;
printTableAddCell ( & cont , PQgetvalue ( res , i , 5 ) , false , false ) ;
2017-07-28 23:44:48 +02:00
printTableAddCell ( & cont , PQgetvalue ( res , i , 6 ) , false , false ) ;
2018-04-07 17:24:53 +02:00
if ( has_pubtruncate )
printTableAddCell ( & cont , PQgetvalue ( res , i , 7 ) , false , false ) ;
2017-01-19 18:00:00 +01:00
2017-06-15 16:46:41 +02:00
if ( ! puballtables )
{
2017-01-19 18:00:00 +01:00
printfPQExpBuffer ( & buf ,
" SELECT n.nspname, c.relname \n "
" FROM 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 ) ;
2017-06-15 16:46:41 +02:00
tabres = PSQLexec ( buf . data ) ;
if ( ! tabres )
{
printTableCleanup ( & cont ) ;
PQclear ( res ) ;
termPQExpBuffer ( & buf ) ;
termPQExpBuffer ( & title ) ;
return false ;
}
else
tables = PQntuples ( tabres ) ;
2017-01-19 18:00:00 +01:00
2017-06-15 16:46:41 +02:00
if ( tables > 0 )
printTableAddFooter ( & cont , _ ( " Tables: " ) ) ;
2017-01-19 18:00:00 +01:00
2017-06-15 16:46:41 +02:00
for ( j = 0 ; j < tables ; j + + )
{
printfPQExpBuffer ( & buf , " \" %s.%s \" " ,
PQgetvalue ( tabres , j , 0 ) ,
PQgetvalue ( tabres , j , 1 ) ) ;
2017-01-19 18:00:00 +01:00
2017-06-15 16:46:41 +02:00
printTableAddFooter ( & cont , buf . data ) ;
}
PQclear ( tabres ) ;
2017-01-19 18:00:00 +01:00
}
printTable ( & cont , pset . queryFout , false , pset . logfile ) ;
printTableCleanup ( & cont ) ;
termPQExpBuffer ( & title ) ;
}
termPQExpBuffer ( & buf ) ;
PQclear ( res ) ;
return true ;
}
2017-07-27 17:57:29 +02:00
/*
* \ dRs
2017-01-19 18:00:00 +01:00
* Describes subscriptions .
*
* Takes an optional regexp to select particular subscriptions
*/
bool
describeSubscriptions ( const char * pattern , bool verbose )
{
PQExpBufferData buf ;
PGresult * res ;
printQueryOpt myopt = pset . popt ;
2017-04-14 19:58:46 +02:00
static const bool translate_columns [ ] = { false , false , false , false ,
2017-05-17 22:31:56 +02:00
false , false } ;
2017-01-19 18:00:00 +01:00
if ( pset . sversion < 100000 )
{
char sverbuf [ 32 ] ;
2017-05-17 22:31:56 +02:00
Unified logging system for command-line programs
This unifies the various ad hoc logging (message printing, error
printing) systems used throughout the command-line programs.
Features:
- Program name is automatically prefixed.
- Message string does not end with newline. This removes a common
source of inconsistencies and omissions.
- Additionally, a final newline is automatically stripped, simplifying
use of PQerrorMessage() etc., another common source of mistakes.
- I converted error message strings to use %m where possible.
- As a result of the above several points, more translatable message
strings can be shared between different components and between
frontends and backend, without gratuitous punctuation or whitespace
differences.
- There is support for setting a "log level". This is not meant to be
user-facing, but can be used internally to implement debug or
verbose modes.
- Lazy argument evaluation, so no significant overhead if logging at
some level is disabled.
- Some color in the messages, similar to gcc and clang. Set
PG_COLOR=auto to try it out. Some colors are predefined, but can be
customized by setting PG_COLORS.
- Common files (common/, fe_utils/, etc.) can handle logging much more
simply by just using one API without worrying too much about the
context of the calling program, requiring callbacks, or having to
pass "progname" around everywhere.
- Some programs called setvbuf() to make sure that stderr is
unbuffered, even on Windows. But not all programs did that. This
is now done centrally.
Soft goals:
- Reduces vertical space use and visual complexity of error reporting
in the source code.
- Encourages more deliberate classification of messages. For example,
in some cases it wasn't clear without analyzing the surrounding code
whether a message was meant as an error or just an info.
- Concepts and terms are vaguely aligned with popular logging
frameworks such as log4j and Python logging.
This is all just about printing stuff out. Nothing affects program
flow (e.g., fatal exits). The uses are just too varied to do that.
Some existing code had wrappers that do some kind of print-and-exit,
and I adapted those.
I tried to keep the output mostly the same, but there is a lot of
historical baggage to unwind and special cases to consider, and I
might not always have succeeded. One significant change is that
pg_rewind used to write all error messages to stdout. That is now
changed to stderr.
Reviewed-by: Donald Dong <xdong@csumb.edu>
Reviewed-by: Arthur Zakirov <a.zakirov@postgrespro.ru>
Discussion: https://www.postgresql.org/message-id/flat/6a609b43-4f57-7348-6480-bd022f924310@2ndquadrant.com
2019-04-01 14:24:37 +02:00
pg_log_error ( " The server (version %s) does not support subscriptions. " ,
2019-05-22 18:55:34 +02:00
formatPGVersionNumber ( pset . sversion , false ,
sverbuf , sizeof ( sverbuf ) ) ) ;
2017-01-19 18:00:00 +01:00
return true ;
}
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 )
{
appendPQExpBuffer ( & buf ,
2017-04-14 19:58:46 +02:00
" , subsynccommit AS \" %s \" \n "
2017-01-19 18:00:00 +01:00
" , subconninfo AS \" %s \" \n " ,
2017-04-14 19:58:46 +02:00
gettext_noop ( " Synchronous commit " ) ,
2017-01-19 18:00:00 +01:00
gettext_noop ( " Conninfo " ) ) ;
}
2017-02-06 10:33:58 +01:00
/* Only display subscriptions in current database. */
2017-01-19 18:00:00 +01:00
appendPQExpBufferStr ( & buf ,
" FROM pg_catalog.pg_subscription \n "
" WHERE subdbid = (SELECT oid \n "
" FROM pg_catalog.pg_database \n "
2017-11-02 03:16:14 +01:00
" WHERE datname = pg_catalog.current_database()) " ) ;
2017-01-19 18:00:00 +01:00
processSQLNamePattern ( pset . db , & buf , pattern , true , false ,
NULL , " subname " , NULL ,
NULL ) ;
appendPQExpBufferStr ( & buf , " ORDER BY 1; " ) ;
res = PSQLexec ( buf . data ) ;
termPQExpBuffer ( & buf ) ;
if ( ! res )
return false ;
myopt . nullPrint = NULL ;
myopt . title = _ ( " List of subscriptions " ) ;
myopt . translate_header = true ;
myopt . translate_columns = translate_columns ;
myopt . n_translate_columns = lengthof ( translate_columns ) ;
printQuery ( res , & myopt , pset . queryFout , false , pset . logfile ) ;
PQclear ( res ) ;
return true ;
}
2008-12-31 19:07:47 +01:00
/*
* printACLColumn
*
* Helper function for consistently formatting ACL ( privilege ) columns .
2014-05-06 18:12:18 +02:00
* The proper targetlist entry is appended to buf . Note lack of any
2008-12-31 19:07:47 +01:00
* whitespace or comma decoration .
*/
static void
printACLColumn ( PQExpBuffer buf , const char * colname )
{
if ( pset . sversion > = 80100 )
appendPQExpBuffer ( buf ,
" pg_catalog.array_to_string(%s, E' \\ n') AS \" %s \" " ,
colname , gettext_noop ( " Access privileges " ) ) ;
else
appendPQExpBuffer ( buf ,
" pg_catalog.array_to_string(%s, ' \\ n') AS \" %s \" " ,
colname , gettext_noop ( " Access privileges " ) ) ;
}