Improve psql's tabular display of wrapped-around data by inserting markers

in the formerly-always-blank columns just to left and right of the data.
Different marking is used for a line break caused by a newline in the data
than for a straight wraparound.  A newline break is signaled by a "+" in the
right margin column in ASCII mode, or a carriage return arrow in UNICODE mode.
Wraparound is signaled by a dot in the right margin as well as the following
left margin in ASCII mode, or an ellipsis symbol in the same places in UNICODE
mode.  "\pset linestyle old-ascii" is added to make the previous behavior
available if anyone really wants it.

In passing, this commit also cleans up a few regression test files that
had unintended spacing differences from the current actual output.

Roger Leigh, reviewed by Gabrielle Roth and other members of PDXPUG.
This commit is contained in:
Tom Lane 2009-11-22 05:20:41 +00:00
parent 93d3bac564
commit 1753337cf5
19 changed files with 374 additions and 260 deletions

View File

@ -829,51 +829,51 @@ DROP SERVER fdtest;
DROP FOREIGN DATA WRAPPER postgresql; DROP FOREIGN DATA WRAPPER postgresql;
-- test asynchronous notifications -- test asynchronous notifications
SELECT dblink_connect('dbname=contrib_regression'); SELECT dblink_connect('dbname=contrib_regression');
dblink_connect dblink_connect
---------------- ----------------
OK OK
(1 row) (1 row)
--should return listen --should return listen
SELECT dblink_exec('LISTEN regression'); SELECT dblink_exec('LISTEN regression');
dblink_exec dblink_exec
------------- -------------
LISTEN LISTEN
(1 row) (1 row)
--should return listen --should return listen
SELECT dblink_exec('LISTEN foobar'); SELECT dblink_exec('LISTEN foobar');
dblink_exec dblink_exec
------------- -------------
LISTEN LISTEN
(1 row) (1 row)
SELECT dblink_exec('NOTIFY regression'); SELECT dblink_exec('NOTIFY regression');
dblink_exec dblink_exec
------------- -------------
NOTIFY NOTIFY
(1 row) (1 row)
SELECT dblink_exec('NOTIFY foobar'); SELECT dblink_exec('NOTIFY foobar');
dblink_exec dblink_exec
------------- -------------
NOTIFY NOTIFY
(1 row) (1 row)
SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify(); SELECT notify_name, be_pid = (select t.be_pid from dblink('select pg_backend_pid()') as t(be_pid int)) AS is_self_notify, extra from dblink_get_notify();
notify_name | is_self_notify | extra notify_name | is_self_notify | extra
-------------+----------------+------- -------------+----------------+-------
regression | t | regression | t |
foobar | t | foobar | t |
(2 rows) (2 rows)
SELECT * from dblink_get_notify(); SELECT * from dblink_get_notify();
notify_name | be_pid | extra notify_name | be_pid | extra
-------------+--------+------- -------------+--------+-------
(0 rows) (0 rows)
SELECT dblink_disconnect(); SELECT dblink_disconnect();
dblink_disconnect dblink_disconnect
------------------- -------------------
OK OK
(1 row) (1 row)

View File

@ -17,7 +17,7 @@ CREATE TABLE ctest (data text, res text, salt text);
INSERT INTO ctest VALUES ('password', '', ''); INSERT INTO ctest VALUES ('password', '', '');
UPDATE ctest SET salt = gen_salt('bf', 8); UPDATE ctest SET salt = gen_salt('bf', 8);
UPDATE ctest SET res = crypt(data, salt); UPDATE ctest SET res = crypt(data, salt);
SELECT res = crypt(data, res) AS "worked" SELECT res = crypt(data, res) AS "worked"
FROM ctest; FROM ctest;
worked worked
-------- --------

View File

@ -6,21 +6,21 @@ SET bytea_output TO escape;
select armor(''); select armor('');
armor armor
----------------------------- -----------------------------
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----+
+
=twTO =twTO +
-----END PGP MESSAGE----- -----END PGP MESSAGE----- +
(1 row) (1 row)
select armor('test'); select armor('test');
armor armor
----------------------------- -----------------------------
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE-----+
+
dGVzdA== dGVzdA== +
=+G7Q =+G7Q +
-----END PGP MESSAGE----- -----END PGP MESSAGE----- +
(1 row) (1 row)
@ -40,12 +40,12 @@ select armor('0123456789abcdef0123456789abcdef0123456789abcdef
0123456789abcdef0123456789abcdef0123456789abcdef'); 0123456789abcdef0123456789abcdef0123456789abcdef');
armor armor
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
-----BEGIN PGP MESSAGE----- -----BEGIN PGP MESSAGE----- +
+
MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmCjAxMjM0NTY3 MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmCjAxMjM0NTY3+
ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZg== ODlhYmNkZWYwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OWFiY2RlZg== +
=JFw5 =JFw5 +
-----END PGP MESSAGE----- -----END PGP MESSAGE----- +
(1 row) (1 row)

View File

@ -11,7 +11,7 @@ yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE=
=JcP+ =JcP+
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -25,7 +25,7 @@ UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA==
=XtrP =XtrP
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -39,7 +39,7 @@ jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI
=rCZt =rCZt
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -53,7 +53,7 @@ lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog==
=fB6S =fB6S
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -68,7 +68,7 @@ u9YkgfJfsuRJmgQ9tmo=
=60ui =60ui
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -82,7 +82,7 @@ jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE
=moGf =moGf
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -97,7 +97,7 @@ KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA==
=NyLk =NyLk
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -111,7 +111,7 @@ jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m
=FxbQ =FxbQ
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -126,7 +126,7 @@ Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw==
=YvkV =YvkV
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -140,7 +140,7 @@ jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK
=dbXm =dbXm
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -154,7 +154,7 @@ z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg==
=VJKg =VJKg
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -168,7 +168,7 @@ Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw==
=cg+i =cg+i
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -182,7 +182,7 @@ jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9
=aHmC =aHmC
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -196,7 +196,7 @@ q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw==
=K0LS =K0LS
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -210,7 +210,7 @@ rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w==
=RGts =RGts
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -224,7 +224,7 @@ jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO
=SUrU =SUrU
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -238,7 +238,7 @@ jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+
=XZrG =XZrG
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'foobar'); '), 'foobar');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -253,7 +253,7 @@ tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw==
=XKKG =XKKG
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), '0123456789abcdefghij'); '), '0123456789abcdefghij');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -267,7 +267,7 @@ CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg==
=gWDh =gWDh
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54'); '), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)
@ -281,7 +281,7 @@ FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q==
=OxOF =OxOF
-----END PGP MESSAGE----- -----END PGP MESSAGE-----
'), 'x'); '), 'x');
pgp_sym_decrypt pgp_sym_decrypt
----------------- -----------------
Secret message. Secret message.
(1 row) (1 row)

View File

@ -742,8 +742,8 @@ select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc
3 | ewri2 3 | ewri2
12 | 12 |
13 | <a href="qwe<qwe>"> 13 | <a href="qwe<qwe>">
12 | 12 | +
: |
19 | /usr/local/fff 19 | /usr/local/fff
12 | 12 |
19 | /awdf/dwqe/4325 19 | /awdf/dwqe/4325
@ -775,8 +775,8 @@ select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc
20 | -4.2 20 | -4.2
12 | . 12 | .
22 | 234 22 | 234
12 | 12 | +
: |
12 | < 12 | <
1 | i 1 | i
12 | 12 |
@ -2330,8 +2330,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('sea&thousand&years')); ', to_tsquery('sea&thousand&years'));
headline headline
-------------------------------------------- --------------------------------------------
<b>sea</b> a <b>thousand</b> <b>years</b>, <b>sea</b> a <b>thousand</b> <b>years</b>,+
A <b>thousand</b> <b>years</b> to trace A <b>thousand</b> <b>years</b> to trace +
The granite features of this cliff The granite features of this cliff
(1 row) (1 row)
@ -2347,8 +2347,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('granite&sea')); ', to_tsquery('granite&sea'));
headline headline
------------------------------------------- -------------------------------------------
<b>sea</b> a thousand years, <b>sea</b> a thousand years, +
A thousand years to trace A thousand years to trace +
The <b>granite</b> features of this cliff The <b>granite</b> features of this cliff
(1 row) (1 row)
@ -2364,8 +2364,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('sea')); ', to_tsquery('sea'));
headline headline
------------------------------------ ------------------------------------
<b>sea</b> a thousand years, <b>sea</b> a thousand years, +
A thousand years to trace A thousand years to trace +
The granite features of this cliff The granite features of this cliff
(1 row) (1 row)
@ -2384,17 +2384,17 @@ ff-bg
to_tsquery('sea&foo'), 'HighlightAll=true'); to_tsquery('sea&foo'), 'HighlightAll=true');
headline headline
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
+
<html> <html> +
<!-- some comment --> <!-- some comment --> +
<body> <body> +
<b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> +
<a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a> <a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>+
ff-bg ff-bg +
<script> <script> +
document.write(15); document.write(15); +
</script> </script> +
</body> </body> +
</html> </html>
(1 row) (1 row)

View File

@ -742,8 +742,8 @@ select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc
3 | ewri2 3 | ewri2
12 | 12 |
13 | <a href="qwe<qwe>"> 13 | <a href="qwe<qwe>">
12 | 12 | +
: |
19 | /usr/local/fff 19 | /usr/local/fff
12 | 12 |
19 | /awdf/dwqe/4325 19 | /awdf/dwqe/4325
@ -775,8 +775,8 @@ select * from parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.werc
20 | -4.2 20 | -4.2
12 | . 12 | .
22 | 234 22 | 234
12 | 12 | +
: |
12 | < 12 | <
1 | i 1 | i
12 | 12 |
@ -2330,8 +2330,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('sea&thousand&years')); ', to_tsquery('sea&thousand&years'));
headline headline
-------------------------------------------- --------------------------------------------
<b>sea</b> a <b>thousand</b> <b>years</b>, <b>sea</b> a <b>thousand</b> <b>years</b>,+
A <b>thousand</b> <b>years</b> to trace A <b>thousand</b> <b>years</b> to trace +
The granite features of this cliff The granite features of this cliff
(1 row) (1 row)
@ -2347,8 +2347,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('granite&sea')); ', to_tsquery('granite&sea'));
headline headline
------------------------------------------- -------------------------------------------
<b>sea</b> a thousand years, <b>sea</b> a thousand years, +
A thousand years to trace A thousand years to trace +
The <b>granite</b> features of this cliff The <b>granite</b> features of this cliff
(1 row) (1 row)
@ -2364,8 +2364,8 @@ Upon a woman s face. E. J. Pratt (1882 1964)
', to_tsquery('sea')); ', to_tsquery('sea'));
headline headline
------------------------------------ ------------------------------------
<b>sea</b> a thousand years, <b>sea</b> a thousand years, +
A thousand years to trace A thousand years to trace +
The granite features of this cliff The granite features of this cliff
(1 row) (1 row)
@ -2384,17 +2384,17 @@ ff-bg
to_tsquery('sea&foo'), 'HighlightAll=true'); to_tsquery('sea&foo'), 'HighlightAll=true');
headline headline
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
+
<html> <html> +
<!-- some comment --> <!-- some comment --> +
<body> <body> +
<b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> +
<a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a> <a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>+
ff-bg ff-bg +
<script> <script> +
document.write(15); document.write(15); +
</script> </script> +
</body> </body> +
</html> </html>
(1 row) (1 row)

View File

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.232 2009/10/13 21:04:01 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/psql-ref.sgml,v 1.233 2009/11/22 05:20:41 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -1765,30 +1765,54 @@ lo_import 152801
<listitem> <listitem>
<para> <para>
Sets the border line drawing style to one Sets the border line drawing style to one
of <literal>ascii</literal> or <literal>unicode</literal>. of <literal>ascii</literal>, <literal>old-ascii</literal>
or <literal>unicode</literal>.
Unique abbreviations are allowed. (That would mean one Unique abbreviations are allowed. (That would mean one
letter is enough.) letter is enough.)
</para> </para>
<para> <para>
<quote>ASCII</quote> uses plain <acronym>ASCII</acronym> characters. <literal>ascii</literal> style uses plain <acronym>ASCII</acronym>
characters. Newlines in data are shown using
a <literal>+</literal> symbol in the right-hand margin.
When the data wraps from one line
to the next without a newline character, a dot (<literal>.</>)
is shown in the right-hand margin of the first line, and
again in the left-hand margin of the following line.
</para> </para>
<para> <para>
<quote>Unicode</quote> uses Unicode box-drawing characters. <literal>old-ascii</literal> style uses plain <acronym>ASCII</>
characters, using the formatting style used
in <productname>PostgreSQL</productname> 8.4 and earlier.
Newlines in data are shown using a <literal>:</literal>
symbol in place of the left-hand column separator.
When the data wraps from one line
to the next without a newline character, a <literal>;</>
symbol is used in place of the left-hand column separator.
</para>
<para>
<literal>unicode</literal> style uses Unicode box-drawing characters.
Newlines in data are shown using a carriage return symbol
in the right-hand margin. When the data wraps from one line
to the next without a newline character, an ellipsis symbol
is shown in the right-hand margin of the first line, and
again in the left-hand margin of the following line.
</para> </para>
<para> <para>
When the selected output format is one that draws lines or boxes When the selected output format is one that draws lines or boxes
around the data, this setting controls how the lines are drawn. around the data, this setting also determines the characters
with which the lines are drawn.
Plain <acronym>ASCII</acronym> characters work everywhere, but Plain <acronym>ASCII</acronym> characters work everywhere, but
Unicode characters look nicer on displays that recognize them. Unicode characters look nicer on displays that recognize them.
</para> </para>
<para> <para>
If this option has not been set, the default behavior is to If this option has not been set, the default behavior is to use
use Unicode characters if the client character set encoding <literal>unicode</literal> style if the client character set encoding
is UTF-8, otherwise <acronym>ASCII</acronym> characters. is UTF-8, otherwise <literal>ascii</literal> style.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.210 2009/10/13 21:04:01 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.211 2009/11/22 05:20:41 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
#include "command.h" #include "command.h"
@ -1795,11 +1795,13 @@ do_pset(const char *param, const char *value, printQueryOpt *popt, bool quiet)
; ;
else if (pg_strncasecmp("ascii", value, vallen) == 0) else if (pg_strncasecmp("ascii", value, vallen) == 0)
popt->topt.line_style = &pg_asciiformat; popt->topt.line_style = &pg_asciiformat;
else if (pg_strncasecmp("old-ascii", value, vallen) == 0)
popt->topt.line_style = &pg_asciiformat_old;
else if (pg_strncasecmp("unicode", value, vallen) == 0) else if (pg_strncasecmp("unicode", value, vallen) == 0)
popt->topt.line_style = &pg_utf8format; popt->topt.line_style = &pg_utf8format;
else else
{ {
psql_error("\\pset: allowed line styles are ascii, unicode\n"); psql_error("\\pset: allowed line styles are ascii, old-ascii, unicode\n");
return false; return false;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.117 2009/10/13 21:04:01 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/print.c,v 1.118 2009/11/22 05:20:41 tgl Exp $
*/ */
#include "postgres_fe.h" #include "postgres_fe.h"
@ -54,9 +54,37 @@ const printTextFormat pg_asciiformat =
{ "-", "+", "+", "+" }, { "-", "+", "+", "+" },
{ "", "|", "|", "|" } { "", "|", "|", "|" }
}, },
"|",
"|",
"|",
" ",
"+",
" ",
"+",
".",
".",
true
};
const printTextFormat pg_asciiformat_old =
{
"old-ascii",
{
{ "-", "+", "+", "+" },
{ "-", "+", "+", "+" },
{ "-", "+", "+", "+" },
{ "", "|", "|", "|" }
},
":", ":",
";", ";",
" " " ",
"+",
" ",
" ",
" ",
" ",
" ",
false
}; };
const printTextFormat pg_utf8format = const printTextFormat pg_utf8format =
@ -72,12 +100,23 @@ const printTextFormat pg_utf8format =
/* N/A, │, │, │ */ /* N/A, │, │, │ */
{ "", "\342\224\202", "\342\224\202", "\342\224\202" } { "", "\342\224\202", "\342\224\202", "\342\224\202" }
}, },
/* ╎ */ /* │ */
"\342\225\216", "\342\224\202",
/* ┊ */ /* │ */
"\342\224\212", "\342\224\202",
/* ╷ */ /* │ */
"\342\225\267" "\342\224\202",
" ",
/* ↵ */
"\342\206\265",
" ",
/* ↵ */
"\342\206\265",
/* … */
"\342\200\246",
/* … */
"\342\200\246",
true
}; };
@ -476,6 +515,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
bool *header_done; /* Have all header lines been output? */ bool *header_done; /* Have all header lines been output? */
int *bytes_output; /* Bytes output for column value */ int *bytes_output; /* Bytes output for column value */
printTextLineWrap *wrap; /* Wrap status for each column */
int output_columns = 0; /* Width of interactive console */ int output_columns = 0; /* Width of interactive console */
bool is_pager = false; bool is_pager = false;
@ -499,6 +539,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
format_buf = pg_local_calloc(col_count, sizeof(*format_buf)); format_buf = pg_local_calloc(col_count, sizeof(*format_buf));
header_done = pg_local_calloc(col_count, sizeof(*header_done)); header_done = pg_local_calloc(col_count, sizeof(*header_done));
bytes_output = pg_local_calloc(col_count, sizeof(*bytes_output)); bytes_output = pg_local_calloc(col_count, sizeof(*bytes_output));
wrap = pg_local_calloc(col_count, sizeof(*wrap));
} }
else else
{ {
@ -513,6 +554,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
format_buf = NULL; format_buf = NULL;
header_done = NULL; header_done = NULL;
bytes_output = NULL; bytes_output = NULL;
wrap = NULL;
} }
/* scan all column headers, find maximum width and max max_nl_lines */ /* scan all column headers, find maximum width and max max_nl_lines */
@ -575,7 +617,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
/* adjust the total display width based on border style */ /* adjust the total display width based on border style */
if (opt_border == 0) if (opt_border == 0)
width_total = col_count - 1; width_total = col_count;
else if (opt_border == 1) else if (opt_border == 1)
width_total = col_count * 3 - 1; width_total = col_count * 3 - 1;
else else
@ -770,16 +812,18 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
while (more_col_wrapping) while (more_col_wrapping)
{ {
if (opt_border == 2) if (opt_border == 2)
fprintf(fout, "%s%c", dformat->leftvrule, fputs(dformat->leftvrule, fout);
curr_nl_line ? '+' : ' ');
else if (opt_border == 1)
fputc(curr_nl_line ? '+' : ' ', fout);
for (i = 0; i < cont->ncolumns; i++) for (i = 0; i < cont->ncolumns; i++)
{ {
struct lineptr *this_line = col_lineptrs[i] + curr_nl_line; struct lineptr *this_line = col_lineptrs[i] + curr_nl_line;
unsigned int nbspace; unsigned int nbspace;
if (opt_border != 0 ||
(format->wrap_right_border == false && i > 0))
fputs(curr_nl_line ? format->header_nl_left : " ",
fout);
if (!header_done[i]) if (!header_done[i])
{ {
nbspace = width_wrap[i] - this_line->width; nbspace = width_wrap[i] - this_line->width;
@ -796,21 +840,18 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
} }
else else
fprintf(fout, "%*s", width_wrap[i], ""); fprintf(fout, "%*s", width_wrap[i], "");
if (i < col_count - 1)
{ if (opt_border != 0 || format->wrap_right_border == true)
if (opt_border == 0) fputs(!header_done[i] ? format->header_nl_right : " ",
fputc(curr_nl_line ? '+' : ' ', fout); fout);
else
fprintf(fout, " %s%c", dformat->midvrule, if (opt_border != 0 && i < col_count - 1)
curr_nl_line ? '+' : ' '); fputs(dformat->midvrule, fout);
}
} }
curr_nl_line++; curr_nl_line++;
if (opt_border == 2) if (opt_border == 2)
fprintf(fout, " %s", dformat->rightvrule); fputs(dformat->rightvrule, fout);
else if (opt_border == 1)
fputc(' ', fout);
fputc('\n', fout); fputc('\n', fout);
} }
@ -861,9 +902,7 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
/* left border */ /* left border */
if (opt_border == 2) if (opt_border == 2)
fprintf(fout, "%s ", dformat->leftvrule); fputs(dformat->leftvrule, fout);
else if (opt_border == 1)
fputc(' ', fout);
/* for each column */ /* for each column */
for (j = 0; j < col_count; j++) for (j = 0; j < col_count; j++)
@ -874,6 +913,17 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
int chars_to_output = width_wrap[j]; int chars_to_output = width_wrap[j];
bool finalspaces = (opt_border == 2 || j < col_count - 1); bool finalspaces = (opt_border == 2 || j < col_count - 1);
/* Print left-hand wrap or newline mark */
if (opt_border != 0)
{
if (wrap[j] == PRINT_LINE_WRAP_WRAP)
fputs(format->wrap_left, fout);
else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
fputs(format->nl_left, fout);
else
fputc(' ', fout);
}
if (!this_line->ptr) if (!this_line->ptr)
{ {
/* Past newline lines so just pad for other columns */ /* Past newline lines so just pad for other columns */
@ -908,8 +958,6 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
/* spaces second */ /* spaces second */
fprintf(fout, "%.*s", bytes_to_output, fprintf(fout, "%.*s", bytes_to_output,
this_line->ptr + bytes_output[j]); this_line->ptr + bytes_output[j]);
if (finalspaces)
fprintf(fout, "%*s", width_wrap[j] - chars_to_output, "");
} }
bytes_output[j] += bytes_to_output; bytes_output[j] += bytes_to_output;
@ -927,29 +975,54 @@ print_aligned_text(const printTableContent *cont, FILE *fout)
} }
} }
/* print a divider, if not the last column */ /* Determine next line's wrap status for this column */
if (j < col_count - 1) wrap[j] = PRINT_LINE_WRAP_NONE;
if (col_lineptrs[j][curr_nl_line[j]].ptr != NULL)
{ {
if (opt_border == 0) if (bytes_output[j] != 0)
fputc(' ', fout); wrap[j] = PRINT_LINE_WRAP_WRAP;
/* Next value is beyond past newlines? */ else if (curr_nl_line[j] != 0)
wrap[j] = PRINT_LINE_WRAP_NEWLINE;
}
/*
* If left-aligned, pad out remaining space if needed (not
* last column, and/or wrap marks required).
*/
if (cont->aligns[j] != 'r') /* Left aligned cell */
{
if (finalspaces ||
wrap[j] == PRINT_LINE_WRAP_WRAP ||
wrap[j] == PRINT_LINE_WRAP_NEWLINE)
fprintf(fout, "%*s",
width_wrap[j] - chars_to_output, "");
}
/* Print right-hand wrap or newline mark */
if (wrap[j] == PRINT_LINE_WRAP_WRAP)
fputs(format->wrap_right, fout);
else if (wrap[j] == PRINT_LINE_WRAP_NEWLINE)
fputs(format->nl_right, fout);
else if (opt_border == 2 || j < col_count - 1)
fputc(' ', fout);
/* Print column divider, if not the last column */
if (opt_border != 0 && j < col_count - 1)
{
if (wrap[j+1] == PRINT_LINE_WRAP_WRAP)
fputs(format->midvrule_wrap, fout);
else if (wrap[j+1] == PRINT_LINE_WRAP_NEWLINE)
fputs(format->midvrule_nl, fout);
else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL) else if (col_lineptrs[j + 1][curr_nl_line[j + 1]].ptr == NULL)
fprintf(fout, " %s ", format->midvrule_blank); fputs(format->midvrule_blank, fout);
/* In wrapping of value? */
else if (bytes_output[j + 1] != 0)
fprintf(fout, " %s ", format->midvrule_wrap);
/* After first newline value */
else if (curr_nl_line[j + 1] != 0)
fprintf(fout, " %s ", format->midvrule_cont);
/* Ordinary line */
else else
fprintf(fout, " %s ", dformat->midvrule); fputs(dformat->midvrule, fout);
} }
} }
/* end-of-row border */ /* end-of-row border */
if (opt_border == 2) if (opt_border == 2)
fprintf(fout, " %s", dformat->rightvrule); fputs(dformat->rightvrule, fout);
fputc('\n', fout); fputc('\n', fout);
} while (more_lines); } while (more_lines);
@ -1196,9 +1269,7 @@ print_aligned_vertical(const printTableContent *cont, FILE *fout)
fprintf(fout, "%*s", hwidth, ""); fprintf(fout, "%*s", hwidth, "");
if (opt_border > 0) if (opt_border > 0)
fprintf(fout, " %s ", fprintf(fout, " %s ", dformat->midvrule);
(line_count == 0) ?
format->midvrule_cont : dformat->midvrule);
else else
fputc(' ', fout); fputc(' ', fout);

View File

@ -3,7 +3,7 @@
* *
* Copyright (c) 2000-2009, PostgreSQL Global Development Group * Copyright (c) 2000-2009, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/bin/psql/print.h,v 1.41 2009/10/13 21:04:01 tgl Exp $ * $PostgreSQL: pgsql/src/bin/psql/print.h,v 1.42 2009/11/22 05:20:41 tgl Exp $
*/ */
#ifndef PRINT_H #ifndef PRINT_H
#define PRINT_H #define PRINT_H
@ -41,14 +41,30 @@ typedef enum printTextRule
PRINT_RULE_DATA /* data line (hrule is unused here) */ PRINT_RULE_DATA /* data line (hrule is unused here) */
} printTextRule; } printTextRule;
typedef enum printTextLineWrap
{
/* Line wrapping conditions */
PRINT_LINE_WRAP_NONE, /* No wrapping */
PRINT_LINE_WRAP_WRAP, /* Wraparound due to overlength line */
PRINT_LINE_WRAP_NEWLINE /* Newline in data */
} printTextLineWrap;
typedef struct printTextFormat typedef struct printTextFormat
{ {
/* A complete line style */ /* A complete line style */
const char *name; /* for display purposes */ const char *name; /* for display purposes */
printTextLineFormat lrule[4]; /* indexed by enum printTextRule */ printTextLineFormat lrule[4]; /* indexed by enum printTextRule */
const char *midvrule_cont; /* vertical line for continue after newline */ const char *midvrule_nl; /* vertical line for continue after newline */
const char *midvrule_wrap; /* vertical line for wrapped data */ const char *midvrule_wrap; /* vertical line for wrapped data */
const char *midvrule_blank; /* vertical line for blank data */ const char *midvrule_blank; /* vertical line for blank data */
const char *header_nl_left; /* left mark after newline */
const char *header_nl_right; /* right mark for newline */
const char *nl_left; /* left mark after newline */
const char *nl_right; /* right mark for newline */
const char *wrap_left; /* left mark after wrapped data */
const char *wrap_right; /* right mark for wrapped data */
bool wrap_right_border; /* use right-hand border for wrap marks
* when border=0? */
} printTextFormat; } printTextFormat;
typedef struct printTableOpt typedef struct printTableOpt
@ -125,6 +141,7 @@ typedef struct printQueryOpt
extern const printTextFormat pg_asciiformat; extern const printTextFormat pg_asciiformat;
extern const printTextFormat pg_asciiformat_old;
extern const printTextFormat pg_utf8format; extern const printTextFormat pg_utf8format;

View File

@ -53,7 +53,7 @@ SELECT casttestfunc('foo'::text); -- Should work now
SELECT 1234::int4::casttesttype; -- No cast yet, should fail SELECT 1234::int4::casttesttype; -- No cast yet, should fail
ERROR: cannot cast type integer to casttesttype ERROR: cannot cast type integer to casttesttype
LINE 1: SELECT 1234::int4::casttesttype; LINE 1: SELECT 1234::int4::casttesttype;
^ ^
CREATE CAST (int4 AS casttesttype) WITH INOUT; CREATE CAST (int4 AS casttesttype) WITH INOUT;
SELECT 1234::int4::casttesttype; -- Should work now SELECT 1234::int4::casttesttype; -- Should work now
casttesttype casttesttype

View File

@ -71,9 +71,9 @@ RESET SESSION AUTHORIZATION;
Access privileges Access privileges
Schema | Name | Type | Access privileges | Column access privileges Schema | Name | Type | Access privileges | Column access privileges
--------+----------+-------+--------------------------------------------------+-------------------------- --------+----------+-------+--------------------------------------------------+--------------------------
public | deptest1 | table | regression_user0=arwdDxt/regression_user0 | public | deptest1 | table | regression_user0=arwdDxt/regression_user0 +|
: regression_user1=a*r*w*d*D*x*t*/regression_user0 | | | regression_user1=a*r*w*d*D*x*t*/regression_user0+|
: regression_user2=arwdDxt/regression_user1 | | | regression_user2=arwdDxt/regression_user1 |
(1 row) (1 row)
DROP OWNED BY regression_user1; DROP OWNED BY regression_user1;

View File

@ -366,14 +366,14 @@ GRANT USAGE ON FOREIGN SERVER s6 TO regress_test_role2 WITH GRANT OPTION;
List of foreign servers List of foreign servers
Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options
------+-------------------+----------------------+-----------------------------------------+--------+---------+------------------------------ ------+-------------------+----------------------+-----------------------------------------+--------+---------+------------------------------
s1 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user | | 1.0 | {servername=s1} s1 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user +| | 1.0 | {servername=s1}
: regress_test_role=U/foreign_data_user | | | regress_test_role=U/foreign_data_user | | |
s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b} s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b}
s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521} s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521}
s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b} s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b}
s5 | foreign_data_user | foo | | | 15.0 | s5 | foreign_data_user | foo | | | 15.0 |
s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user | | 16.0 | {host=a,dbname=b} s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user +| | 16.0 | {host=a,dbname=b}
: regress_test_role2=U*/foreign_data_user | | | regress_test_role2=U*/foreign_data_user | | |
s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b} s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b}
s8 | foreign_data_user | postgresql | | | | {host=localhost,dbname=s8db} s8 | foreign_data_user | postgresql | | | | {host=localhost,dbname=s8db}
t1 | regress_test_role | foo | | | | t1 | regress_test_role | foo | | | |
@ -417,14 +417,14 @@ access to foreign-data wrapper foo
List of foreign servers List of foreign servers
Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options Name | Owner | Foreign-data wrapper | Access privileges | Type | Version | Options
------+-----------------------+----------------------+-----------------------------------------+--------+---------+--------------------------------- ------+-----------------------+----------------------+-----------------------------------------+--------+---------+---------------------------------
s1 | regress_test_indirect | foo | foreign_data_user=U/foreign_data_user | | 1.1 | {servername=s1} s1 | regress_test_indirect | foo | foreign_data_user=U/foreign_data_user +| | 1.1 | {servername=s1}
: regress_test_role=U/foreign_data_user | | | regress_test_role=U/foreign_data_user | | |
s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b} s2 | foreign_data_user | foo | | | 1.1 | {host=a,dbname=b}
s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521} s3 | foreign_data_user | foo | | oracle | | {tnsname=orcl,port=1521}
s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b} s4 | foreign_data_user | foo | | oracle | | {host=a,dbname=b}
s5 | foreign_data_user | foo | | | 15.0 | s5 | foreign_data_user | foo | | | 15.0 |
s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user | | 16.0 | {host=a,dbname=b} s6 | foreign_data_user | foo | foreign_data_user=U/foreign_data_user +| | 16.0 | {host=a,dbname=b}
: regress_test_role2=U*/foreign_data_user | | | regress_test_role2=U*/foreign_data_user | | |
s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b} s7 | foreign_data_user | foo | | oracle | 17.0 | {host=a,dbname=b}
s8 | foreign_data_user | postgresql | | | | {dbname=db1,connect_timeout=30} s8 | foreign_data_user | postgresql | | | | {dbname=db1,connect_timeout=30}
t1 | regress_test_role | foo | | | | t1 | regress_test_role | foo | | | |

View File

@ -85,10 +85,10 @@ INSERT INTO FKTABLE VALUES (NULL, NULL, 0);
-- Insert failed rows into FK TABLE -- Insert failed rows into FK TABLE
INSERT INTO FKTABLE VALUES (100, 2, 4); INSERT INTO FKTABLE VALUES (100, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname"
DETAIL: Key (ftest1,ftest2)=(100,2) is not present in table "pktable". DETAIL: Key (ftest1, ftest2)=(100, 2) is not present in table "pktable".
INSERT INTO FKTABLE VALUES (2, 2, 4); INSERT INTO FKTABLE VALUES (2, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname"
DETAIL: Key (ftest1,ftest2)=(2,2) is not present in table "pktable". DETAIL: Key (ftest1, ftest2)=(2, 2) is not present in table "pktable".
INSERT INTO FKTABLE VALUES (NULL, 2, 4); INSERT INTO FKTABLE VALUES (NULL, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
@ -195,10 +195,10 @@ INSERT INTO FKTABLE VALUES (NULL, NULL, 0);
-- Insert failed rows into FK TABLE -- Insert failed rows into FK TABLE
INSERT INTO FKTABLE VALUES (100, 2, 4); INSERT INTO FKTABLE VALUES (100, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2"
DETAIL: Key (ftest1,ftest2)=(100,2) is not present in table "pktable". DETAIL: Key (ftest1, ftest2)=(100, 2) is not present in table "pktable".
INSERT INTO FKTABLE VALUES (2, 2, 4); INSERT INTO FKTABLE VALUES (2, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2"
DETAIL: Key (ftest1,ftest2)=(2,2) is not present in table "pktable". DETAIL: Key (ftest1, ftest2)=(2, 2) is not present in table "pktable".
INSERT INTO FKTABLE VALUES (NULL, 2, 4); INSERT INTO FKTABLE VALUES (NULL, 2, 4);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname2"
DETAIL: MATCH FULL does not allow mixing of null and nonnull key values. DETAIL: MATCH FULL does not allow mixing of null and nonnull key values.
@ -359,7 +359,7 @@ INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5);
-- Insert a failed values -- Insert a failed values
INSERT INTO FKTABLE VALUES (1, 2, 7, 6); INSERT INTO FKTABLE VALUES (1, 2, 7, 6);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3"
DETAIL: Key (ftest1,ftest2,ftest3)=(1,2,7) is not present in table "pktable". DETAIL: Key (ftest1, ftest2, ftest3)=(1, 2, 7) is not present in table "pktable".
-- Show FKTABLE -- Show FKTABLE
SELECT * from FKTABLE; SELECT * from FKTABLE;
ftest1 | ftest2 | ftest3 | ftest4 ftest1 | ftest2 | ftest3 | ftest4
@ -374,13 +374,13 @@ SELECT * from FKTABLE;
-- Try to update something that should fail -- Try to update something that should fail
UPDATE PKTABLE set ptest2=5 where ptest2=2; UPDATE PKTABLE set ptest2=5 where ptest2=2;
ERROR: update or delete on table "pktable" violates foreign key constraint "constrname3" on table "fktable" ERROR: update or delete on table "pktable" violates foreign key constraint "constrname3" on table "fktable"
DETAIL: Key (ptest1,ptest2,ptest3)=(1,2,3) is still referenced from table "fktable". DETAIL: Key (ptest1, ptest2, ptest3)=(1, 2, 3) is still referenced from table "fktable".
-- Try to update something that should succeed -- Try to update something that should succeed
UPDATE PKTABLE set ptest1=1 WHERE ptest2=3; UPDATE PKTABLE set ptest1=1 WHERE ptest2=3;
-- Try to delete something that should fail -- Try to delete something that should fail
DELETE FROM PKTABLE where ptest1=1 and ptest2=2 and ptest3=3; DELETE FROM PKTABLE where ptest1=1 and ptest2=2 and ptest3=3;
ERROR: update or delete on table "pktable" violates foreign key constraint "constrname3" on table "fktable" ERROR: update or delete on table "pktable" violates foreign key constraint "constrname3" on table "fktable"
DETAIL: Key (ptest1,ptest2,ptest3)=(1,2,3) is still referenced from table "fktable". DETAIL: Key (ptest1, ptest2, ptest3)=(1, 2, 3) is still referenced from table "fktable".
-- Try to delete something that should work -- Try to delete something that should work
DELETE FROM PKTABLE where ptest1=2; DELETE FROM PKTABLE where ptest1=2;
-- Show PKTABLE and FKTABLE -- Show PKTABLE and FKTABLE
@ -424,7 +424,7 @@ INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5);
-- Insert a failed values -- Insert a failed values
INSERT INTO FKTABLE VALUES (1, 2, 7, 6); INSERT INTO FKTABLE VALUES (1, 2, 7, 6);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3"
DETAIL: Key (ftest1,ftest2,ftest3)=(1,2,7) is not present in table "pktable". DETAIL: Key (ftest1, ftest2, ftest3)=(1, 2, 7) is not present in table "pktable".
-- Show FKTABLE -- Show FKTABLE
SELECT * from FKTABLE; SELECT * from FKTABLE;
ftest1 | ftest2 | ftest3 | ftest4 ftest1 | ftest2 | ftest3 | ftest4
@ -522,7 +522,7 @@ INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5);
-- Insert a failed values -- Insert a failed values
INSERT INTO FKTABLE VALUES (1, 2, 7, 6); INSERT INTO FKTABLE VALUES (1, 2, 7, 6);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3"
DETAIL: Key (ftest1,ftest2,ftest3)=(1,2,7) is not present in table "pktable". DETAIL: Key (ftest1, ftest2, ftest3)=(1, 2, 7) is not present in table "pktable".
-- Show FKTABLE -- Show FKTABLE
SELECT * from FKTABLE; SELECT * from FKTABLE;
ftest1 | ftest2 | ftest3 | ftest4 ftest1 | ftest2 | ftest3 | ftest4
@ -628,7 +628,7 @@ INSERT INTO FKTABLE VALUES (NULL, 3, 4, 5);
-- Insert a failed values -- Insert a failed values
INSERT INTO FKTABLE VALUES (1, 2, 7, 6); INSERT INTO FKTABLE VALUES (1, 2, 7, 6);
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3"
DETAIL: Key (ftest1,ftest2,ftest3)=(1,2,7) is not present in table "pktable". DETAIL: Key (ftest1, ftest2, ftest3)=(1, 2, 7) is not present in table "pktable".
-- Show FKTABLE -- Show FKTABLE
SELECT * from FKTABLE; SELECT * from FKTABLE;
ftest1 | ftest2 | ftest3 | ftest4 ftest1 | ftest2 | ftest3 | ftest4
@ -645,7 +645,7 @@ SELECT * from FKTABLE;
-- Try to update something that will fail -- Try to update something that will fail
UPDATE PKTABLE set ptest2=5 where ptest2=2; UPDATE PKTABLE set ptest2=5 where ptest2=2;
ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3" ERROR: insert or update on table "fktable" violates foreign key constraint "constrname3"
DETAIL: Key (ftest1,ftest2,ftest3)=(1,-1,3) is not present in table "pktable". DETAIL: Key (ftest1, ftest2, ftest3)=(1, -1, 3) is not present in table "pktable".
-- Try to update something that will set default -- Try to update something that will set default
UPDATE PKTABLE set ptest1=0, ptest2=5, ptest3=10 where ptest2=2; UPDATE PKTABLE set ptest1=0, ptest2=5, ptest3=10 where ptest2=2;
UPDATE PKTABLE set ptest2=10 where ptest2=4; UPDATE PKTABLE set ptest2=10 where ptest2=4;
@ -896,19 +896,19 @@ insert into pktable(base1, ptest1) values (2, 2);
-- let's insert a non-existant fktable value -- let's insert a non-existant fktable value
insert into fktable(ftest1, ftest2) values (3, 1); insert into fktable(ftest1, ftest2) values (3, 1);
ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey" ERROR: insert or update on table "fktable" violates foreign key constraint "fktable_ftest1_fkey"
DETAIL: Key (ftest1,ftest2)=(3,1) is not present in table "pktable". DETAIL: Key (ftest1, ftest2)=(3, 1) is not present in table "pktable".
-- let's make a valid row for that -- let's make a valid row for that
insert into pktable(base1,ptest1) values (3, 1); insert into pktable(base1,ptest1) values (3, 1);
insert into fktable(ftest1, ftest2) values (3, 1); insert into fktable(ftest1, ftest2) values (3, 1);
-- let's try removing a row that should fail from pktable -- let's try removing a row that should fail from pktable
delete from pktable where base1>2; delete from pktable where base1>2;
ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable"
DETAIL: Key (base1,ptest1)=(3,1) is still referenced from table "fktable". DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable".
-- okay, let's try updating all of the base1 values to *4 -- okay, let's try updating all of the base1 values to *4
-- which should fail. -- which should fail.
update pktable set base1=base1*4; update pktable set base1=base1*4;
ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable" ERROR: update or delete on table "pktable" violates foreign key constraint "fktable_ftest1_fkey" on table "fktable"
DETAIL: Key (base1,ptest1)=(3,1) is still referenced from table "fktable". DETAIL: Key (base1, ptest1)=(3, 1) is still referenced from table "fktable".
-- okay, let's try an update that should work. -- okay, let's try an update that should work.
update pktable set base1=base1*4 where base1<3; update pktable set base1=base1*4 where base1<3;
-- and a delete that should work -- and a delete that should work
@ -929,15 +929,15 @@ insert into pktable (base1, ptest1, base2, ptest2) values (1, 3, 2, 2);
-- fails (3,2) isn't in base1, ptest1 -- fails (3,2) isn't in base1, ptest1
insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2); insert into pktable (base1, ptest1, base2, ptest2) values (2, 3, 3, 2);
ERROR: insert or update on table "pktable" violates foreign key constraint "pktable_base2_fkey" ERROR: insert or update on table "pktable" violates foreign key constraint "pktable_base2_fkey"
DETAIL: Key (base2,ptest2)=(3,2) is not present in table "pktable". DETAIL: Key (base2, ptest2)=(3, 2) is not present in table "pktable".
-- fails (2,2) is being referenced -- fails (2,2) is being referenced
delete from pktable where base1=2; delete from pktable where base1=2;
ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable"
DETAIL: Key (base1,ptest1)=(2,2) is still referenced from table "pktable". DETAIL: Key (base1, ptest1)=(2, 2) is still referenced from table "pktable".
-- fails (1,1) is being referenced (twice) -- fails (1,1) is being referenced (twice)
update pktable set base1=3 where base1=1; update pktable set base1=3 where base1=1;
ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable" ERROR: update or delete on table "pktable" violates foreign key constraint "pktable_base2_fkey" on table "pktable"
DETAIL: Key (base1,ptest1)=(1,1) is still referenced from table "pktable". DETAIL: Key (base1, ptest1)=(1, 1) is still referenced from table "pktable".
-- this sequence of two deletes will work, since after the first there will be no (2,*) references -- this sequence of two deletes will work, since after the first there will be no (2,*) references
delete from pktable where base2=2; delete from pktable where base2=2;
delete from pktable where base1=2; delete from pktable where base1=2;

View File

@ -685,7 +685,7 @@ language plpgsql
set work_mem = '1MB'; set work_mem = '1MB';
select myfunc(0); select myfunc(0);
ERROR: division by zero ERROR: division by zero
CONTEXT: SQL statement "SELECT 1/ $1 " CONTEXT: SQL statement "SELECT 1/$1"
PL/pgSQL function "myfunc" line 3 at PERFORM PL/pgSQL function "myfunc" line 3 at PERFORM
select current_setting('work_mem'); select current_setting('work_mem');
current_setting current_setting

View File

@ -154,20 +154,20 @@ SELECT name, statement, parameter_types FROM pg_prepared_statements
ORDER BY name; ORDER BY name;
name | statement | parameter_types name | statement | parameter_types
------+---------------------------------------------------------------------+-------------------------------------------------------- ------+---------------------------------------------------------------------+--------------------------------------------------------
q2 | PREPARE q2(text) AS | {text} q2 | PREPARE q2(text) AS +| {text}
: SELECT datname, datistemplate, datallowconn | SELECT datname, datistemplate, datallowconn +|
: FROM pg_database WHERE datname = $1; | FROM pg_database WHERE datname = $1; |
q3 | PREPARE q3(text, int, float, boolean, oid, smallint) AS | {text,integer,"double precision",boolean,oid,smallint} q3 | PREPARE q3(text, int, float, boolean, oid, smallint) AS +| {text,integer,"double precision",boolean,oid,smallint}
: SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR | SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR +|
: ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int) | ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int)+|
: ORDER BY unique1; | ORDER BY unique1; |
q5 | PREPARE q5(int, text) AS | {integer,text} q5 | PREPARE q5(int, text) AS +| {integer,text}
: SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 | SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +|
: ORDER BY unique1; | ORDER BY unique1; |
q6 | PREPARE q6 AS | {integer,name} q6 | PREPARE q6 AS +| {integer,name}
: SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; | SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2; |
q7 | PREPARE q7(unknown) AS | {path} q7 | PREPARE q7(unknown) AS +| {path}
: SELECT * FROM road WHERE thepath = $1; | SELECT * FROM road WHERE thepath = $1; |
(5 rows) (5 rows)
-- test DEALLOCATE ALL; -- test DEALLOCATE ALL;

View File

@ -377,10 +377,10 @@ SELECT * FROM main_table ORDER BY a, b;
SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a'; SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_a';
pg_get_triggerdef pg_get_triggerdef
-------------------------------------------------- --------------------------------------------------
CREATE TRIGGER modified_a CREATE TRIGGER modified_a +
BEFORE UPDATE OF a ON main_table BEFORE UPDATE OF a ON main_table +
FOR EACH ROW FOR EACH ROW +
WHEN (old.a <> new.a) WHEN (old.a <> new.a) +
EXECUTE PROCEDURE trigger_func('modified_a') EXECUTE PROCEDURE trigger_func('modified_a')
(1 row) (1 row)
@ -393,10 +393,10 @@ SELECT pg_get_triggerdef(oid, false) FROM pg_trigger WHERE tgrelid = 'main_table
SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any'; SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'modified_any';
pg_get_triggerdef pg_get_triggerdef
---------------------------------------------------- ----------------------------------------------------
CREATE TRIGGER modified_any CREATE TRIGGER modified_any +
BEFORE UPDATE OF a ON main_table BEFORE UPDATE OF a ON main_table +
FOR EACH ROW FOR EACH ROW +
WHEN (old.* IS DISTINCT FROM new.*) WHEN (old.* IS DISTINCT FROM new.*) +
EXECUTE PROCEDURE trigger_func('modified_any') EXECUTE PROCEDURE trigger_func('modified_any')
(1 row) (1 row)
@ -427,9 +427,9 @@ SELECT pg_get_triggerdef(oid) FROM pg_trigger WHERE tgrelid = 'main_table'::regc
SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig'; SELECT pg_get_triggerdef(oid, true) FROM pg_trigger WHERE tgrelid = 'main_table'::regclass AND tgname = 'after_upd_a_b_row_trig';
pg_get_triggerdef pg_get_triggerdef
--------------------------------------------------------- ---------------------------------------------------------
CREATE TRIGGER after_upd_a_b_row_trig CREATE TRIGGER after_upd_a_b_row_trig +
AFTER UPDATE OF a, b ON main_table AFTER UPDATE OF a, b ON main_table +
FOR EACH ROW FOR EACH ROW +
EXECUTE PROCEDURE trigger_func('after_upd_a_b_row') EXECUTE PROCEDURE trigger_func('after_upd_a_b_row')
(1 row) (1 row)

View File

@ -344,8 +344,8 @@ SELECT * FROM ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.w
3 | ewri2 3 | ewri2
12 | 12 |
13 | <a href="qwe<qwe>"> 13 | <a href="qwe<qwe>">
12 | 12 | +
: |
19 | /usr/local/fff 19 | /usr/local/fff
12 | 12 |
19 | /awdf/dwqe/4325 19 | /awdf/dwqe/4325
@ -377,8 +377,8 @@ SELECT * FROM ts_parse('default', '345 qwe@efd.r '' http://www.com/ http://aew.w
20 | -4.2 20 | -4.2
12 | . 12 | .
22 | 234 22 | 234
12 | 12 | +
: |
12 | < 12 | <
1 | i 1 | i
12 | 12 |
@ -559,9 +559,9 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'paint&water')); ', to_tsquery('english', 'paint&water'));
ts_headline ts_headline
----------------------------------------- -----------------------------------------
<b>painted</b> Ocean. <b>painted</b> Ocean. +
<b>Water</b>, <b>water</b>, every where <b>Water</b>, <b>water</b>, every where+
And all the boards did shrink; And all the boards did shrink; +
<b>Water</b>, <b>water</b>, every <b>Water</b>, <b>water</b>, every
(1 row) (1 row)
@ -578,9 +578,9 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'breath&motion&water')); ', to_tsquery('english', 'breath&motion&water'));
ts_headline ts_headline
---------------------------------- ----------------------------------
<b>breath</b> nor <b>motion</b>, <b>breath</b> nor <b>motion</b>,+
As idle as a painted Ship As idle as a painted Ship +
Upon a painted Ocean. Upon a painted Ocean. +
<b>Water</b>, <b>water</b> <b>Water</b>, <b>water</b>
(1 row) (1 row)
@ -597,9 +597,9 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'ocean')); ', to_tsquery('english', 'ocean'));
ts_headline ts_headline
---------------------------------- ----------------------------------
<b>Ocean</b>. <b>Ocean</b>. +
Water, water, every where Water, water, every where +
And all the boards did shrink; And all the boards did shrink;+
Water, water, every where Water, water, every where
(1 row) (1 row)
@ -618,17 +618,17 @@ ff-bg
to_tsquery('english', 'sea&foo'), 'HighlightAll=true'); to_tsquery('english', 'sea&foo'), 'HighlightAll=true');
ts_headline ts_headline
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
+
<html> <html> +
<!-- some comment --> <!-- some comment --> +
<body> <body> +
<b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> <b>Sea</b> view wow <u><b>foo</b> bar</u> <i>qq</i> +
<a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a> <a href="http://www.google.com/foo.bar.html" target="_blank">YES &nbsp;</a>+
ff-bg ff-bg +
<script> <script> +
document.write(15); document.write(15); +
</script> </script> +
</body> </body> +
</html> </html>
(1 row) (1 row)
@ -646,13 +646,13 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'ocean'), 'MaxFragments=1'); ', to_tsquery('english', 'ocean'), 'MaxFragments=1');
ts_headline ts_headline
------------------------------------ ------------------------------------
after day, after day, +
We stuck, nor breath nor motion, We stuck, nor breath nor motion,+
As idle as a painted Ship As idle as a painted Ship +
Upon a painted <b>Ocean</b>. Upon a painted <b>Ocean</b>. +
Water, water, every where Water, water, every where +
And all the boards did shrink; And all the boards did shrink; +
Water, water, every where, Water, water, every where, +
Nor any drop Nor any drop
(1 row) (1 row)
@ -670,13 +670,13 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2'); ', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2');
ts_headline ts_headline
---------------------------------------------- ----------------------------------------------
after day, day after day, after day, day after day, +
We <b>stuck</b>, nor breath nor motion, We <b>stuck</b>, nor breath nor motion, +
As idle as a painted Ship As idle as a painted Ship +
Upon a painted Ocean. Upon a painted Ocean. +
Water, water, every where Water, water, every where +
And all the boards did shrink; And all the boards did shrink; +
Water, water, every where ... drop to drink. Water, water, every where ... drop to drink.+
S. T. <b>Coleridge</b> S. T. <b>Coleridge</b>
(1 row) (1 row)
@ -694,9 +694,9 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1'); ', to_tsquery('english', 'ocean & seahorse'), 'MaxFragments=1');
ts_headline ts_headline
------------------------------------ ------------------------------------
+
Day after day, day after day, Day after day, day after day, +
We stuck, nor breath nor motion, We stuck, nor breath nor motion,+
As idle as As idle as
(1 row) (1 row)
@ -714,13 +714,13 @@ S. T. Coleridge (1772-1834)
', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***'); ', to_tsquery('english', 'Coleridge & stuck'), 'MaxFragments=2,FragmentDelimiter=***');
ts_headline ts_headline
-------------------------------------------- --------------------------------------------
after day, day after day, after day, day after day, +
We <b>stuck</b>, nor breath nor motion, We <b>stuck</b>, nor breath nor motion, +
As idle as a painted Ship As idle as a painted Ship +
Upon a painted Ocean. Upon a painted Ocean. +
Water, water, every where Water, water, every where +
And all the boards did shrink; And all the boards did shrink; +
Water, water, every where***drop to drink. Water, water, every where***drop to drink.+
S. T. <b>Coleridge</b> S. T. <b>Coleridge</b>
(1 row) (1 row)

View File

@ -279,16 +279,16 @@ SELECT pg_get_viewdef('vsubdepartment'::regclass);
SELECT pg_get_viewdef('vsubdepartment'::regclass, true); SELECT pg_get_viewdef('vsubdepartment'::regclass, true);
pg_get_viewdef pg_get_viewdef
-------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------
WITH RECURSIVE subdepartment AS ( WITH RECURSIVE subdepartment AS ( +
SELECT department.id, department.parent_department, department.name SELECT department.id, department.parent_department, department.name+
FROM department FROM department +
WHERE department.name = 'A'::text WHERE department.name = 'A'::text +
UNION ALL UNION ALL +
SELECT d.id, d.parent_department, d.name SELECT d.id, d.parent_department, d.name +
FROM department d, subdepartment sd FROM department d, subdepartment sd +
WHERE d.parent_department = sd.id WHERE d.parent_department = sd.id +
) ) +
SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name SELECT subdepartment.id, subdepartment.parent_department, subdepartment.name +
FROM subdepartment; FROM subdepartment;
(1 row) (1 row)