From: Valery Popov <v.popov@postgrespro.ru>
To: pgsql-hackers@postgresql.org
To: " <michael.paquier@gmail.com>
Cc: david@pgmasters.net
Subject: Re: Password identifiers, protocol aging and SCRAM protocol
Date: Tue, 15 Mar 2016 17:46:33 +0300
Message-ID: <56E82049.8040204@postgrespro.ru> (raw)
In-Reply-To: <CAB7nPqTssJpBUZ8g9oUTPJ6RPLCZYFtPypzdYgHL1gtuskxwkw@mail.gmail.com>
References: <CAB7nPqSMXU35g=W9X74HVeQp0uvgJxvYOuA4A-A3M+0wfEBv-w@mail.gmail.com>
<56E6D98F.1070701@pgmasters.net>
<CAB7nPqQYim-=PBHa19p04wSBbgGT=+ts1qWeQj2FG9HSmBX78Q@mail.gmail.com>
<CAB7nPqTssJpBUZ8g9oUTPJ6RPLCZYFtPypzdYgHL1gtuskxwkw@mail.gmail.com>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-hackers>
Hi, All
On 03/15/2016 02:07 AM, Michael Paquier wrote:
> Sure. I'll provide them shortly with all the comments addressed. Up to
> now I just had a couple of comments about docs and whitespaces, so I
> didn't really bother sending a new set, but this meritates a rebase.
> And here they are. I have addressed the documentation and the
> whitespaces reported up to now at the same time.
I've applied all of 0001-0009 patches from the new set with no any
warnings to today's master branch.
Then compiled with configure options:
./configure --enable-debug --enable-nls --enable-cassert
--enable-tap-tests --with-perl
All regression tests passed successfully.
make check-world passed successfully.
make installcheck-world failed on several contrib modules:
dblink, file_fdw, hstore, pgcrypto, pgstattuple, postgres_fdw,
tablefunc. The tests results are attached.
Documentation looks good.
Where may be a problem with make check-world and make installcheck-world
results?
--
Regards,
Valery Popov
Postgres Professional http://www.postgrespro.com
The Russian Postgres Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackersAttachments:dblink.diffs (text/plain, 31.5K) download
*** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/dblink/expected/dblink.out 2016-03-15 14:32:12.917977851 +0300
--- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/dblink/results/dblink.out 2016-03-15 15:35:27.756996876 +0300
***************
*** 16,1128 ****
-- list the primary key fields
SELECT *
FROM dblink_get_pkey('foo');
! position | colname
! ----------+---------
! 1 | f1
! 2 | f2
! (2 rows)
!
! -- build an insert statement based on a local tuple,
! -- replacing the primary key values with new ones
! SELECT dblink_build_sql_insert('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
! dblink_build_sql_insert
! -----------------------------------------------------------
! INSERT INTO foo(f1,f2,f3) VALUES('99','xyz','{a0,b0,c0}')
! (1 row)
!
! -- too many pk fields, should fail
! SELECT dblink_build_sql_insert('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
! ERROR: invalid attribute number 4
! -- build an update statement based on a local tuple,
! -- replacing the primary key values with new ones
! SELECT dblink_build_sql_update('foo','1 2',2,'{"0", "a"}','{"99", "xyz"}');
! dblink_build_sql_update
! ----------------------------------------------------------------------------------------
! UPDATE foo SET f1 = '99', f2 = 'xyz', f3 = '{a0,b0,c0}' WHERE f1 = '99' AND f2 = 'xyz'
! (1 row)
!
! -- too many pk fields, should fail
! SELECT dblink_build_sql_update('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}','{"99", "xyz", "{za0,zb0,zc0}"}');
! ERROR: invalid attribute number 4
! -- build a delete statement based on a local tuple,
! SELECT dblink_build_sql_delete('foo','1 2',2,'{"0", "a"}');
! dblink_build_sql_delete
! ---------------------------------------------
! DELETE FROM foo WHERE f1 = '0' AND f2 = 'a'
! (1 row)
!
! -- too many pk fields, should fail
! SELECT dblink_build_sql_delete('foo','1 2 3 4',4,'{"0", "a", "{a0,b0,c0}"}');
! ERROR: invalid attribute number 4
! -- retest using a quoted and schema qualified table
! CREATE SCHEMA "MySchema";
! CREATE TABLE "MySchema"."Foo"(f1 int, f2 text, f3 text[], primary key (f1,f2));
! INSERT INTO "MySchema"."Foo" VALUES (0,'a','{"a0","b0","c0"}');
! -- list the primary key fields
! SELECT *
! FROM dblink_get_pkey('"MySchema"."Foo"');
! position | colname
! ----------+---------
! 1 | f1
! 2 | f2
! (2 rows)
!
! -- build an insert statement based on a local tuple,
! -- replacing the primary key values with new ones
! SELECT dblink_build_sql_insert('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
! dblink_build_sql_insert
! ------------------------------------------------------------------------
! INSERT INTO "MySchema"."Foo"(f1,f2,f3) VALUES('99','xyz','{a0,b0,c0}')
! (1 row)
!
! -- build an update statement based on a local tuple,
! -- replacing the primary key values with new ones
! SELECT dblink_build_sql_update('"MySchema"."Foo"','1 2',2,'{"0", "a"}','{"99", "xyz"}');
! dblink_build_sql_update
! -----------------------------------------------------------------------------------------------------
! UPDATE "MySchema"."Foo" SET f1 = '99', f2 = 'xyz', f3 = '{a0,b0,c0}' WHERE f1 = '99' AND f2 = 'xyz'
! (1 row)
!
! -- build a delete statement based on a local tuple,
! SELECT dblink_build_sql_delete('"MySchema"."Foo"','1 2',2,'{"0", "a"}');
! dblink_build_sql_delete
! ----------------------------------------------------------
! DELETE FROM "MySchema"."Foo" WHERE f1 = '0' AND f2 = 'a'
! (1 row)
!
! CREATE FUNCTION connection_parameters() RETURNS text LANGUAGE SQL AS $f$
! SELECT $$dbname='$$||current_database()||$$' port=$$||current_setting('port');
! $f$;
! -- regular old dblink
! SELECT *
! FROM dblink(connection_parameters(),'SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! a | b | c
! ---+---+------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! (2 rows)
!
! -- should generate "connection not available" error
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! ERROR: connection not available
! -- The first-level connection's backend will crash on exit given OpenLDAP
! -- [2.4.24, 2.4.31]. We won't see evidence of any crash until the victim
! -- process terminates and the postmaster responds. If process termination
! -- entails writing a core dump, that can take awhile. Wait for the process to
! -- vanish. At that point, the postmaster has called waitpid() on the crashed
! -- process, and it will accept no new connections until it has reinitialized
! -- the cluster. (We can't exploit pg_stat_activity, because the crash happens
! -- after the backend updates shared memory to reflect its impending exit.)
! DO $pl$
! DECLARE
! detail text;
! BEGIN
! PERFORM wait_pid(crash_pid)
! FROM dblink(connection_parameters(), $$
! SELECT pg_backend_pid() FROM dblink(
! 'service=test_ldap '||connection_parameters(),
! -- This string concatenation is a hack to shoehorn a
! -- set_pgservicefile call into the SQL statement.
! 'SELECT 1' || set_pgservicefile('pg_service.conf')
! ) t(c int)
! $$) AS t(crash_pid int);
! EXCEPTION WHEN OTHERS THEN
! GET STACKED DIAGNOSTICS detail = PG_EXCEPTION_DETAIL;
! -- Expected error in a non-LDAP build.
! IF NOT detail LIKE 'syntax error in service file%' THEN RAISE; END IF;
! END
! $pl$;
! -- create a persistent connection
! SELECT dblink_connect(connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! -- use the persistent connection
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! a | b | c
! ---+---+------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! (2 rows)
!
! -- open a cursor with bad SQL and fail_on_error set to false
! SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foobar',false);
! NOTICE: relation "foobar" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not open cursor.
! dblink_open
! -------------
! ERROR
! (1 row)
!
! -- reset remote transaction state
! SELECT dblink_exec('ABORT');
! dblink_exec
! -------------
! ROLLBACK
! (1 row)
!
! -- open a cursor
! SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- close the cursor
! SELECT dblink_close('rmt_foo_cursor',false);
! dblink_close
! --------------
! OK
! (1 row)
!
! -- open the cursor again
! SELECT dblink_open('rmt_foo_cursor','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- fetch some data
! SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! (4 rows)
!
! SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! (4 rows)
!
! -- this one only finds two rows left
! SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! (2 rows)
!
! -- intentionally botch a fetch
! SELECT *
! FROM dblink_fetch('rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
! NOTICE: cursor "rmt_foobar_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
! a | b | c
! ---+---+---
! (0 rows)
!
! -- reset remote transaction state
! SELECT dblink_exec('ABORT');
! dblink_exec
! -------------
! ROLLBACK
! (1 row)
!
! -- close the wrong cursor
! SELECT dblink_close('rmt_foobar_cursor',false);
! NOTICE: cursor "rmt_foobar_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not close cursor.
! dblink_close
! --------------
! ERROR
! (1 row)
!
! -- should generate 'cursor "rmt_foo_cursor" not found' error
! SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! ERROR: cursor "rmt_foo_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
! -- this time, 'cursor "rmt_foo_cursor" not found' as a notice
! SELECT *
! FROM dblink_fetch('rmt_foo_cursor',4,false) AS t(a int, b text, c text[]);
! NOTICE: cursor "rmt_foo_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not fetch from cursor.
! a | b | c
! ---+---+---
! (0 rows)
!
! -- close the persistent connection
! SELECT dblink_disconnect();
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- should generate "connection not available" error
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! ERROR: connection not available
! -- put more data into our slave table, first using arbitrary connection syntax
! -- but truncate the actual return value so we can use diff to check for success
! SELECT substr(dblink_exec(connection_parameters(),'INSERT INTO foo VALUES(10,''k'',''{"a10","b10","c10"}'')'),1,6);
! substr
! --------
! INSERT
! (1 row)
!
! -- create a persistent connection
! SELECT dblink_connect(connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! -- put more data into our slave table, using persistent connection syntax
! -- but truncate the actual return value so we can use diff to check for success
! SELECT substr(dblink_exec('INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
! substr
! --------
! INSERT
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[]);
! a | b | c
! ----+---+---------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! 11 | l | {a11,b11,c11}
! (12 rows)
!
! -- bad remote select
! SELECT *
! FROM dblink('SELECT * FROM foobar',false) AS t(a int, b text, c text[]);
! NOTICE: relation "foobar" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not execute query.
! a | b | c
! ---+---+---
! (0 rows)
!
! -- change some data
! SELECT dblink_exec('UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
! dblink_exec
! -------------
! UPDATE 1
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE a = 11;
! a | b | c
! ----+---+---------------
! 11 | l | {a11,b99,c11}
! (1 row)
!
! -- botch a change to some other data
! SELECT dblink_exec('UPDATE foobar SET f3[2] = ''b99'' WHERE f1 = 11',false);
! NOTICE: relation "foobar" does not exist
! CONTEXT: Error occurred on dblink connection named "unnamed": could not execute command.
! dblink_exec
! -------------
! ERROR
! (1 row)
!
! -- delete some data
! SELECT dblink_exec('DELETE FROM foo WHERE f1 = 11');
! dblink_exec
! -------------
! DELETE 1
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE a = 11;
! a | b | c
! ---+---+---
! (0 rows)
!
! -- close the persistent connection
! SELECT dblink_disconnect();
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! --
! -- tests for the new named persistent connection syntax
! --
! -- should generate "missing "=" after "myconn" in connection info string" error
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! ERROR: could not establish connection
! DETAIL: missing "=" after "myconn" in connection info string
!
! -- create a named persistent connection
! SELECT dblink_connect('myconn',connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! -- use the named persistent connection
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! a | b | c
! ----+---+---------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! (3 rows)
!
! -- use the named persistent connection, but get it wrong
! SELECT *
! FROM dblink('myconn','SELECT * FROM foobar',false) AS t(a int, b text, c text[])
! WHERE t.a > 7;
! NOTICE: relation "foobar" does not exist
! CONTEXT: Error occurred on dblink connection named "myconn": could not execute query.
! a | b | c
! ---+---+---
! (0 rows)
!
! -- create a second named persistent connection
! -- should error with "duplicate connection name"
! SELECT dblink_connect('myconn',connection_parameters());
! ERROR: duplicate connection name
! -- create a second named persistent connection with a new name
! SELECT dblink_connect('myconn2',connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! -- use the second named persistent connection
! SELECT *
! FROM dblink('myconn2','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! a | b | c
! ----+---+---------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! (3 rows)
!
! -- close the second named persistent connection
! SELECT dblink_disconnect('myconn2');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- open a cursor incorrectly
! SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foobar',false);
! NOTICE: relation "foobar" does not exist
! CONTEXT: Error occurred on dblink connection named "myconn": could not open cursor.
! dblink_open
! -------------
! ERROR
! (1 row)
!
! -- reset remote transaction state
! SELECT dblink_exec('myconn','ABORT');
! dblink_exec
! -------------
! ROLLBACK
! (1 row)
!
! -- test opening cursor in a transaction
! SELECT dblink_exec('myconn','BEGIN');
! dblink_exec
! -------------
! BEGIN
! (1 row)
!
! -- an open transaction will prevent dblink_open() from opening its own
! SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- this should not commit the transaction because the client opened it
! SELECT dblink_close('myconn','rmt_foo_cursor');
! dblink_close
! --------------
! OK
! (1 row)
!
! -- this should succeed because we have an open transaction
! SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
! dblink_exec
! ----------------
! DECLARE CURSOR
! (1 row)
!
! -- commit remote transaction
! SELECT dblink_exec('myconn','COMMIT');
! dblink_exec
! -------------
! COMMIT
! (1 row)
!
! -- test automatic transactions for multiple cursor opens
! SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- the second cursor
! SELECT dblink_open('myconn','rmt_foo_cursor2','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- this should not commit the transaction
! SELECT dblink_close('myconn','rmt_foo_cursor2');
! dblink_close
! --------------
! OK
! (1 row)
!
! -- this should succeed because we have an open transaction
! SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
! dblink_exec
! ----------------
! DECLARE CURSOR
! (1 row)
!
! -- this should commit the transaction
! SELECT dblink_close('myconn','rmt_foo_cursor');
! dblink_close
! --------------
! OK
! (1 row)
!
! -- this should fail because there is no open transaction
! SELECT dblink_exec('myconn','DECLARE xact_test CURSOR FOR SELECT * FROM foo');
! ERROR: DECLARE CURSOR can only be used in transaction blocks
! CONTEXT: Error occurred on dblink connection named "myconn": could not execute command.
! -- reset remote transaction state
! SELECT dblink_exec('myconn','ABORT');
! dblink_exec
! -------------
! ROLLBACK
! (1 row)
!
! -- open a cursor
! SELECT dblink_open('myconn','rmt_foo_cursor','SELECT * FROM foo');
! dblink_open
! -------------
! OK
! (1 row)
!
! -- fetch some data
! SELECT *
! FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! (4 rows)
!
! SELECT *
! FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ---+---+------------
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! (4 rows)
!
! -- this one only finds three rows left
! SELECT *
! FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! a | b | c
! ----+---+---------------
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! (3 rows)
!
! -- fetch some data incorrectly
! SELECT *
! FROM dblink_fetch('myconn','rmt_foobar_cursor',4,false) AS t(a int, b text, c text[]);
! NOTICE: cursor "rmt_foobar_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "myconn": could not fetch from cursor.
! a | b | c
! ---+---+---
! (0 rows)
!
! -- reset remote transaction state
! SELECT dblink_exec('myconn','ABORT');
! dblink_exec
! -------------
! ROLLBACK
! (1 row)
!
! -- should generate 'cursor "rmt_foo_cursor" not found' error
! SELECT *
! FROM dblink_fetch('myconn','rmt_foo_cursor',4) AS t(a int, b text, c text[]);
! ERROR: cursor "rmt_foo_cursor" does not exist
! CONTEXT: Error occurred on dblink connection named "myconn": could not fetch from cursor.
! -- close the named persistent connection
! SELECT dblink_disconnect('myconn');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- should generate "missing "=" after "myconn" in connection info string" error
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE t.a > 7;
! ERROR: could not establish connection
! DETAIL: missing "=" after "myconn" in connection info string
!
! -- create a named persistent connection
! SELECT dblink_connect('myconn',connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! -- put more data into our slave table, using named persistent connection syntax
! -- but truncate the actual return value so we can use diff to check for success
! SELECT substr(dblink_exec('myconn','INSERT INTO foo VALUES(11,''l'',''{"a11","b11","c11"}'')'),1,6);
! substr
! --------
! INSERT
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
! a | b | c
! ----+---+---------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! 11 | l | {a11,b11,c11}
! (12 rows)
!
! -- change some data
! SELECT dblink_exec('myconn','UPDATE foo SET f3[2] = ''b99'' WHERE f1 = 11');
! dblink_exec
! -------------
! UPDATE 1
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE a = 11;
! a | b | c
! ----+---+---------------
! 11 | l | {a11,b99,c11}
! (1 row)
!
! -- delete some data
! SELECT dblink_exec('myconn','DELETE FROM foo WHERE f1 = 11');
! dblink_exec
! -------------
! DELETE 1
! (1 row)
!
! -- let's see it
! SELECT *
! FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[])
! WHERE a = 11;
! a | b | c
! ---+---+---
! (0 rows)
!
! -- close the named persistent connection
! SELECT dblink_disconnect('myconn');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- close the named persistent connection again
! -- should get 'connection "myconn" not available' error
! SELECT dblink_disconnect('myconn');
! ERROR: connection "myconn" not available
! -- test asynchronous queries
! SELECT dblink_connect('dtest1', connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! SELECT * from
! dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
! t1
! ----
! 1
! (1 row)
!
! SELECT dblink_connect('dtest2', connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! SELECT * from
! dblink_send_query('dtest2', 'select * from foo where f1 > 2 and f1 < 7') as t1;
! t1
! ----
! 1
! (1 row)
!
! SELECT dblink_connect('dtest3', connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! SELECT * from
! dblink_send_query('dtest3', 'select * from foo where f1 > 6') as t1;
! t1
! ----
! 1
! (1 row)
!
! CREATE TEMPORARY TABLE result AS
! (SELECT * from dblink_get_result('dtest1') as t1(f1 int, f2 text, f3 text[]))
! UNION
! (SELECT * from dblink_get_result('dtest2') as t2(f1 int, f2 text, f3 text[]))
! UNION
! (SELECT * from dblink_get_result('dtest3') as t3(f1 int, f2 text, f3 text[]))
! ORDER by f1;
! -- dblink_get_connections returns an array with elements in a machine-dependent
! -- ordering, so we must resort to unnesting and sorting for a stable result
! create function unnest(anyarray) returns setof anyelement
! language sql strict immutable as $$
! select $1[i] from generate_series(array_lower($1,1), array_upper($1,1)) as i
! $$;
! SELECT * FROM unnest(dblink_get_connections()) ORDER BY 1;
! unnest
! --------
! dtest1
! dtest2
! dtest3
! (3 rows)
!
! SELECT dblink_is_busy('dtest1');
! dblink_is_busy
! ----------------
! 0
! (1 row)
!
! SELECT dblink_disconnect('dtest1');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! SELECT dblink_disconnect('dtest2');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! SELECT dblink_disconnect('dtest3');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! SELECT * from result;
! f1 | f2 | f3
! ----+----+---------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! (11 rows)
!
! SELECT dblink_connect('dtest1', connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! SELECT * from
! dblink_send_query('dtest1', 'select * from foo where f1 < 3') as t1;
! t1
! ----
! 1
! (1 row)
!
! SELECT dblink_cancel_query('dtest1');
! dblink_cancel_query
! ---------------------
! OK
! (1 row)
!
! SELECT dblink_error_message('dtest1');
! dblink_error_message
! ----------------------
! OK
! (1 row)
!
! SELECT dblink_disconnect('dtest1');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- test foreign data wrapper functionality
! CREATE ROLE dblink_regression_test;
! DO $d$
! BEGIN
! EXECUTE $$CREATE SERVER fdtest FOREIGN DATA WRAPPER dblink_fdw
! OPTIONS (dbname '$$||current_database()||$$',
! port '$$||current_setting('port')||$$'
! )$$;
! END;
! $d$;
! CREATE USER MAPPING FOR public SERVER fdtest
! OPTIONS (server 'localhost'); -- fail, can't specify server here
! ERROR: invalid option "server"
! HINT: Valid options in this context are: user, password
! CREATE USER MAPPING FOR public SERVER fdtest OPTIONS (user :'USER');
! GRANT USAGE ON FOREIGN SERVER fdtest TO dblink_regression_test;
! GRANT EXECUTE ON FUNCTION dblink_connect_u(text, text) TO dblink_regression_test;
! SET SESSION AUTHORIZATION dblink_regression_test;
! -- should fail
! SELECT dblink_connect('myconn', 'fdtest');
! ERROR: password is required
! DETAIL: Non-superusers must provide a password in the connection string.
! -- should succeed
! SELECT dblink_connect_u('myconn', 'fdtest');
! dblink_connect_u
! ------------------
! OK
! (1 row)
!
! SELECT * FROM dblink('myconn','SELECT * FROM foo') AS t(a int, b text, c text[]);
! a | b | c
! ----+---+---------------
! 0 | a | {a0,b0,c0}
! 1 | b | {a1,b1,c1}
! 2 | c | {a2,b2,c2}
! 3 | d | {a3,b3,c3}
! 4 | e | {a4,b4,c4}
! 5 | f | {a5,b5,c5}
! 6 | g | {a6,b6,c6}
! 7 | h | {a7,b7,c7}
! 8 | i | {a8,b8,c8}
! 9 | j | {a9,b9,c9}
! 10 | k | {a10,b10,c10}
! (11 rows)
!
! \c - -
! REVOKE USAGE ON FOREIGN SERVER fdtest FROM dblink_regression_test;
! REVOKE EXECUTE ON FUNCTION dblink_connect_u(text, text) FROM dblink_regression_test;
! DROP USER dblink_regression_test;
! DROP USER MAPPING FOR public SERVER fdtest;
! DROP SERVER fdtest;
! -- test asynchronous notifications
! SELECT dblink_connect(connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! --should return listen
! SELECT dblink_exec('LISTEN regression');
! dblink_exec
! -------------
! LISTEN
! (1 row)
!
! --should return listen
! SELECT dblink_exec('LISTEN foobar');
! dblink_exec
! -------------
! LISTEN
! (1 row)
!
! SELECT dblink_exec('NOTIFY regression');
! dblink_exec
! -------------
! NOTIFY
! (1 row)
!
! SELECT dblink_exec('NOTIFY foobar');
! dblink_exec
! -------------
! NOTIFY
! (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();
! notify_name | is_self_notify | extra
! -------------+----------------+-------
! regression | t |
! foobar | t |
! (2 rows)
!
! SELECT * from dblink_get_notify();
! notify_name | be_pid | extra
! -------------+--------+-------
! (0 rows)
!
! SELECT dblink_disconnect();
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! -- test dropped columns in dblink_build_sql_insert, dblink_build_sql_update
! CREATE TEMP TABLE test_dropped
! (
! col1 INT NOT NULL DEFAULT 111,
! id SERIAL PRIMARY KEY,
! col2 INT NOT NULL DEFAULT 112,
! col2b INT NOT NULL DEFAULT 113
! );
! INSERT INTO test_dropped VALUES(default);
! ALTER TABLE test_dropped
! DROP COLUMN col1,
! DROP COLUMN col2,
! ADD COLUMN col3 VARCHAR(10) NOT NULL DEFAULT 'foo',
! ADD COLUMN col4 INT NOT NULL DEFAULT 42;
! SELECT dblink_build_sql_insert('test_dropped', '1', 1,
! ARRAY['1'::TEXT], ARRAY['2'::TEXT]);
! dblink_build_sql_insert
! ---------------------------------------------------------------------------
! INSERT INTO test_dropped(id,col2b,col3,col4) VALUES('2','113','foo','42')
! (1 row)
!
! SELECT dblink_build_sql_update('test_dropped', '1', 1,
! ARRAY['1'::TEXT], ARRAY['2'::TEXT]);
! dblink_build_sql_update
! -------------------------------------------------------------------------------------------
! UPDATE test_dropped SET id = '2', col2b = '113', col3 = 'foo', col4 = '42' WHERE id = '2'
! (1 row)
!
! SELECT dblink_build_sql_delete('test_dropped', '1', 1,
! ARRAY['2'::TEXT]);
! dblink_build_sql_delete
! -----------------------------------------
! DELETE FROM test_dropped WHERE id = '2'
! (1 row)
!
! -- test local mimicry of remote GUC values that affect datatype I/O
! SET datestyle = ISO, MDY;
! SET intervalstyle = postgres;
! SET timezone = UTC;
! SELECT dblink_connect('myconn',connection_parameters());
! dblink_connect
! ----------------
! OK
! (1 row)
!
! SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
! dblink_exec
! -------------
! SET
! (1 row)
!
! -- single row synchronous case
! SELECT *
! FROM dblink('myconn',
! 'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
! AS t(a timestamptz);
! a
! ------------------------
! 2013-03-12 00:00:00+00
! (1 row)
!
! -- multi-row synchronous case
! SELECT *
! FROM dblink('myconn',
! 'SELECT * FROM
! (VALUES (''12.03.2013 00:00:00+00''),
! (''12.03.2013 00:00:00+00'')) t')
! AS t(a timestamptz);
! a
! ------------------------
! 2013-03-12 00:00:00+00
! 2013-03-12 00:00:00+00
! (2 rows)
!
! -- single-row asynchronous case
! SELECT *
! FROM dblink_send_query('myconn',
! 'SELECT * FROM
! (VALUES (''12.03.2013 00:00:00+00'')) t');
! dblink_send_query
! -------------------
! 1
! (1 row)
!
! CREATE TEMPORARY TABLE result AS
! (SELECT * from dblink_get_result('myconn') as t(t timestamptz))
! UNION ALL
! (SELECT * from dblink_get_result('myconn') as t(t timestamptz));
! SELECT * FROM result;
! t
! ------------------------
! 2013-03-12 00:00:00+00
! (1 row)
!
! DROP TABLE result;
! -- multi-row asynchronous case
! SELECT *
! FROM dblink_send_query('myconn',
! 'SELECT * FROM
! (VALUES (''12.03.2013 00:00:00+00''),
! (''12.03.2013 00:00:00+00'')) t');
! dblink_send_query
! -------------------
! 1
! (1 row)
!
! CREATE TEMPORARY TABLE result AS
! (SELECT * from dblink_get_result('myconn') as t(t timestamptz))
! UNION ALL
! (SELECT * from dblink_get_result('myconn') as t(t timestamptz))
! UNION ALL
! (SELECT * from dblink_get_result('myconn') as t(t timestamptz));
! SELECT * FROM result;
! t
! ------------------------
! 2013-03-12 00:00:00+00
! 2013-03-12 00:00:00+00
! (2 rows)
!
! DROP TABLE result;
! -- Try an ambiguous interval
! SELECT dblink_exec('myconn', 'SET intervalstyle = sql_standard;');
! dblink_exec
! -------------
! SET
! (1 row)
!
! SELECT *
! FROM dblink('myconn',
! 'SELECT * FROM (VALUES (''-1 2:03:04'')) i')
! AS i(i interval);
! i
! -------------------
! -1 days -02:03:04
! (1 row)
!
! -- Try swapping to another format to ensure the GUCs are tracked
! -- properly through a change.
! CREATE TEMPORARY TABLE result (t timestamptz);
! SELECT dblink_exec('myconn', 'SET datestyle = ISO, MDY;');
! dblink_exec
! -------------
! SET
! (1 row)
!
! INSERT INTO result
! SELECT *
! FROM dblink('myconn',
! 'SELECT * FROM (VALUES (''03.12.2013 00:00:00+00'')) t')
! AS t(a timestamptz);
! SELECT dblink_exec('myconn', 'SET datestyle = GERMAN, DMY;');
! dblink_exec
! -------------
! SET
! (1 row)
!
! INSERT INTO result
! SELECT *
! FROM dblink('myconn',
! 'SELECT * FROM (VALUES (''12.03.2013 00:00:00+00'')) t')
! AS t(a timestamptz);
! SELECT * FROM result;
! t
! ------------------------
! 2013-03-12 00:00:00+00
! 2013-03-12 00:00:00+00
! (2 rows)
!
! DROP TABLE result;
! -- Check error throwing in dblink_fetch
! SELECT dblink_open('myconn','error_cursor',
! 'SELECT * FROM (VALUES (''1''), (''not an int'')) AS t(text);');
! dblink_open
! -------------
! OK
! (1 row)
!
! SELECT *
! FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int);
! i
! ---
! 1
! (1 row)
!
! SELECT *
! FROM dblink_fetch('myconn','error_cursor', 1) AS t(i int);
! ERROR: invalid input syntax for integer: "not an int"
! -- Make sure that the local settings have retained their values in spite
! -- of shenanigans on the connection.
! SHOW datestyle;
! DateStyle
! -----------
! ISO, MDY
! (1 row)
!
! SHOW intervalstyle;
! IntervalStyle
! ---------------
! postgres
! (1 row)
!
! -- Clean up GUC-setting tests
! SELECT dblink_disconnect('myconn');
! dblink_disconnect
! -------------------
! OK
! (1 row)
!
! RESET datestyle;
! RESET intervalstyle;
! RESET timezone;
--- 16,22 ----
-- list the primary key fields
SELECT *
FROM dblink_get_pkey('foo');
! server closed the connection unexpectedly
! This probably means the server terminated abnormally
! before or while processing the request.
! connection to server was lost
======================================================================
dblink.out (text/plain, 116B) download
test paths ... ok
test dblink ... FAILED (test process exited with exit code 2)
file_fdw.diffs (text/plain, 7.7K) download
*** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/expected/file_fdw.out 2016-03-15 16:11:08.209906170 +0300
--- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/results/file_fdw.out 2016-03-15 16:11:09.497917931 +0300
***************
*** 104,122 ****
) SERVER file_server
OPTIONS (format 'text', filename '/home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/data/text.csv', null 'NULL');
SELECT * FROM text_csv; -- ERROR
! ERROR: COPY force not null available only in CSV mode
ALTER FOREIGN TABLE text_csv OPTIONS (SET format 'csv');
\pset null _null_
SELECT * FROM text_csv;
! word1 | word2 | word3 | word4
! -------+--------+--------+--------
! AAA | aaa | 123 |
! XYZ | xyz | | 321
! NULL | _null_ | _null_ | _null_
! NULL | _null_ | _null_ | _null_
! ABC | abc | |
! (5 rows)
!
-- force_not_null and force_null can be used together on the same column
ALTER FOREIGN TABLE text_csv ALTER COLUMN word1 OPTIONS (force_null 'true');
ALTER FOREIGN TABLE text_csv ALTER COLUMN word3 OPTIONS (force_not_null 'true');
--- 104,114 ----
) SERVER file_server
OPTIONS (format 'text', filename '/home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/data/text.csv', null 'NULL');
SELECT * FROM text_csv; -- ERROR
! ERROR: unrecognized node type: 539
ALTER FOREIGN TABLE text_csv OPTIONS (SET format 'csv');
\pset null _null_
SELECT * FROM text_csv;
! ERROR: unrecognized node type: 539
-- force_not_null and force_null can be used together on the same column
ALTER FOREIGN TABLE text_csv ALTER COLUMN word1 OPTIONS (force_null 'true');
ALTER FOREIGN TABLE text_csv ALTER COLUMN word3 OPTIONS (force_not_null 'true');
***************
*** 148,345 ****
HINT: Valid options in this context are: filename, format, header, delimiter, quote, escape, null, encoding
-- basic query tests
SELECT * FROM agg_text WHERE b > 10.0 ORDER BY a;
! a | b
! -----+--------
! 42 | 324.78
! 100 | 99.097
! (2 rows)
!
SELECT * FROM agg_csv ORDER BY a;
! a | b
! -----+---------
! 0 | 0.09561
! 42 | 324.78
! 100 | 99.097
! (3 rows)
!
SELECT * FROM agg_csv c JOIN agg_text t ON (t.a = c.a) ORDER BY c.a;
! a | b | a | b
! -----+---------+-----+---------
! 0 | 0.09561 | 0 | 0.09561
! 42 | 324.78 | 42 | 324.78
! 100 | 99.097 | 100 | 99.097
! (3 rows)
!
! -- error context report tests
! SELECT * FROM agg_bad; -- ERROR
! ERROR: invalid input syntax for type real: "aaa"
! CONTEXT: COPY agg_bad, line 3, column b: "aaa"
! -- misc query tests
! \t on
! EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv;
! Foreign Scan on public.agg_csv
! Output: a, b
! Foreign File: /home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/data/agg.csv
!
! \t off
! PREPARE st(int) AS SELECT * FROM agg_csv WHERE a = $1;
! EXECUTE st(100);
! a | b
! -----+--------
! 100 | 99.097
! (1 row)
!
! EXECUTE st(100);
! a | b
! -----+--------
! 100 | 99.097
! (1 row)
!
! DEALLOCATE st;
! -- tableoid
! SELECT tableoid::regclass, b FROM agg_csv;
! tableoid | b
! ----------+---------
! agg_csv | 99.097
! agg_csv | 0.09561
! agg_csv | 324.78
! (3 rows)
!
! -- updates aren't supported
! INSERT INTO agg_csv VALUES(1,2.0);
! ERROR: cannot insert into foreign table "agg_csv"
! UPDATE agg_csv SET a = 1;
! ERROR: cannot update foreign table "agg_csv"
! DELETE FROM agg_csv WHERE a = 100;
! ERROR: cannot delete from foreign table "agg_csv"
! -- but this should be allowed
! SELECT * FROM agg_csv FOR UPDATE;
! a | b
! -----+---------
! 100 | 99.097
! 0 | 0.09561
! 42 | 324.78
! (3 rows)
!
! -- constraint exclusion tests
! \t on
! EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
! Foreign Scan on public.agg_csv
! Output: a, b
! Filter: (agg_csv.a < 0)
! Foreign File: /home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/data/agg.csv
!
! \t off
! SELECT * FROM agg_csv WHERE a < 0;
! a | b
! ---+---
! (0 rows)
!
! SET constraint_exclusion = 'on';
! \t on
! EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_csv WHERE a < 0;
! Result
! Output: a, b
! One-Time Filter: false
!
! \t off
! SELECT * FROM agg_csv WHERE a < 0;
! a | b
! ---+---
! (0 rows)
!
! RESET constraint_exclusion;
! -- table inheritance tests
! CREATE TABLE agg (a int2, b float4);
! ALTER FOREIGN TABLE agg_csv INHERIT agg;
! SELECT tableoid::regclass, * FROM agg;
! tableoid | a | b
! ----------+-----+---------
! agg_csv | 100 | 99.097
! agg_csv | 0 | 0.09561
! agg_csv | 42 | 324.78
! (3 rows)
!
! SELECT tableoid::regclass, * FROM agg_csv;
! tableoid | a | b
! ----------+-----+---------
! agg_csv | 100 | 99.097
! agg_csv | 0 | 0.09561
! agg_csv | 42 | 324.78
! (3 rows)
!
! SELECT tableoid::regclass, * FROM ONLY agg;
! tableoid | a | b
! ----------+---+---
! (0 rows)
!
! -- updates aren't supported
! UPDATE agg SET a = 1;
! ERROR: cannot update foreign table "agg_csv"
! DELETE FROM agg WHERE a = 100;
! ERROR: cannot delete from foreign table "agg_csv"
! -- but this should be allowed
! SELECT tableoid::regclass, * FROM agg FOR UPDATE;
! tableoid | a | b
! ----------+-----+---------
! agg_csv | 100 | 99.097
! agg_csv | 0 | 0.09561
! agg_csv | 42 | 324.78
! (3 rows)
!
! ALTER FOREIGN TABLE agg_csv NO INHERIT agg;
! DROP TABLE agg;
! -- privilege tests
! SET ROLE file_fdw_superuser;
! SELECT * FROM agg_text ORDER BY a;
! a | b
! -----+---------
! 0 | 0.09561
! 42 | 324.78
! 56 | 7.8
! 100 | 99.097
! (4 rows)
!
! SET ROLE file_fdw_user;
! SELECT * FROM agg_text ORDER BY a;
! a | b
! -----+---------
! 0 | 0.09561
! 42 | 324.78
! 56 | 7.8
! 100 | 99.097
! (4 rows)
!
! SET ROLE no_priv_user;
! SELECT * FROM agg_text ORDER BY a; -- ERROR
! ERROR: permission denied for relation agg_text
! SET ROLE file_fdw_user;
! \t on
! EXPLAIN (VERBOSE, COSTS FALSE) SELECT * FROM agg_text WHERE a > 0;
! Foreign Scan on public.agg_text
! Output: a, b
! Filter: (agg_text.a > 0)
! Foreign File: /home/vpopov/Projects/pwdtest.new/postgresql/contrib/file_fdw/data/agg.data
!
! \t off
! -- privilege tests for object
! SET ROLE file_fdw_superuser;
! ALTER FOREIGN TABLE agg_text OWNER TO file_fdw_user;
! ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text');
! SET ROLE file_fdw_user;
! ALTER FOREIGN TABLE agg_text OPTIONS (SET format 'text');
! ERROR: only superuser can change options of a file_fdw foreign table
! SET ROLE file_fdw_superuser;
! -- cleanup
! RESET ROLE;
! DROP EXTENSION file_fdw CASCADE;
! NOTICE: drop cascades to 8 other objects
! DETAIL: drop cascades to server file_server
! drop cascades to user mapping for file_fdw_user on server file_server
! drop cascades to user mapping for file_fdw_superuser on server file_server
! drop cascades to user mapping for no_priv_user on server file_server
! drop cascades to foreign table agg_text
! drop cascades to foreign table agg_csv
! drop cascades to foreign table agg_bad
! drop cascades to foreign table text_csv
! DROP ROLE file_fdw_superuser, file_fdw_user, no_priv_user;
--- 140,150 ----
HINT: Valid options in this context are: filename, format, header, delimiter, quote, escape, null, encoding
-- basic query tests
SELECT * FROM agg_text WHERE b > 10.0 ORDER BY a;
! ERROR: unrecognized node type: 539
SELECT * FROM agg_csv ORDER BY a;
! ERROR: unrecognized node type: 539
SELECT * FROM agg_csv c JOIN agg_text t ON (t.a = c.a) ORDER BY c.a;
! server closed the connection unexpectedly
! This probably means the server terminated abnormally
! before or while processing the request.
! connection to server was lost
======================================================================
file_fdw.out (text/plain, 79B) download
test file_fdw ... FAILED (test process exited with exit code 2)
hstore.diffs (text/plain, 9.9K) download
*** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/hstore/expected/hstore.out 2016-03-15 14:32:12.921977887 +0300
--- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/hstore/results/hstore.out 2016-03-15 16:19:53.174671801 +0300
***************
*** 1161,1509 ****
(1 row)
select * from skeys('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>f');
! skeys
! -------
! b
! aa
! cq
! fg
! (4 rows)
!
! select * from skeys('""=>1');
! skeys
! -------
!
! (1 row)
!
! select * from skeys('');
! skeys
! -------
! (0 rows)
!
! select * from svals('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>f');
! svals
! -------
! g
! 1
! l
! f
! (4 rows)
!
! select *, svals is null from svals('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>NULL');
! svals | ?column?
! -------+----------
! g | f
! 1 | f
! l | f
! | t
! (4 rows)
!
! select * from svals('""=>1');
! svals
! -------
! 1
! (1 row)
!
! select * from svals('');
! svals
! -------
! (0 rows)
!
! select * from each('aaa=>bq, b=>NULL, ""=>1 ');
! key | value
! -----+-------
! | 1
! b |
! aaa | bq
! (3 rows)
!
! -- @>
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
! ?column?
! ----------
! t
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>NULL';
! ?column?
! ----------
! t
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, g=>NULL';
! ?column?
! ----------
! f
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'g=>NULL';
! ?column?
! ----------
! f
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>c';
! ?column?
! ----------
! f
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b';
! ?column?
! ----------
! t
! (1 row)
!
! select 'a=>b, b=>1, c=>NULL'::hstore @> 'a=>b, c=>q';
! ?column?
! ----------
! f
! (1 row)
!
! CREATE TABLE testhstore (h hstore);
! \copy testhstore from 'data/hstore.data'
! select count(*) from testhstore where h @> 'wait=>NULL';
! count
! -------
! 1
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC';
! count
! -------
! 15
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC, public=>t';
! count
! -------
! 2
! (1 row)
!
! select count(*) from testhstore where h ? 'public';
! count
! -------
! 194
! (1 row)
!
! select count(*) from testhstore where h ?| ARRAY['public','disabled'];
! count
! -------
! 337
! (1 row)
!
! select count(*) from testhstore where h ?& ARRAY['public','disabled'];
! count
! -------
! 42
! (1 row)
!
! create index hidx on testhstore using gist(h);
! set enable_seqscan=off;
! select count(*) from testhstore where h @> 'wait=>NULL';
! count
! -------
! 1
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC';
! count
! -------
! 15
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC, public=>t';
! count
! -------
! 2
! (1 row)
!
! select count(*) from testhstore where h ? 'public';
! count
! -------
! 194
! (1 row)
!
! select count(*) from testhstore where h ?| ARRAY['public','disabled'];
! count
! -------
! 337
! (1 row)
!
! select count(*) from testhstore where h ?& ARRAY['public','disabled'];
! count
! -------
! 42
! (1 row)
!
! drop index hidx;
! create index hidx on testhstore using gin (h);
! set enable_seqscan=off;
! select count(*) from testhstore where h @> 'wait=>NULL';
! count
! -------
! 1
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC';
! count
! -------
! 15
! (1 row)
!
! select count(*) from testhstore where h @> 'wait=>CC, public=>t';
! count
! -------
! 2
! (1 row)
!
! select count(*) from testhstore where h ? 'public';
! count
! -------
! 194
! (1 row)
!
! select count(*) from testhstore where h ?| ARRAY['public','disabled'];
! count
! -------
! 337
! (1 row)
!
! select count(*) from testhstore where h ?& ARRAY['public','disabled'];
! count
! -------
! 42
! (1 row)
!
! select count(*) from (select (each(h)).key from testhstore) as wow ;
! count
! -------
! 4781
! (1 row)
!
! select key, count(*) from (select (each(h)).key from testhstore) as wow group by key order by count desc, key;
! key | count
! -----------+-------
! line | 884
! query | 207
! pos | 203
! node | 202
! space | 197
! status | 195
! public | 194
! title | 190
! wait | 190
! org | 189
! user | 189
! coauthors | 188
! disabled | 185
! indexed | 184
! cleaned | 180
! bad | 179
! date | 179
! world | 176
! state | 172
! subtitle | 169
! auth | 168
! abstract | 161
! (22 rows)
!
! -- sort/hash
! select count(distinct h) from testhstore;
! count
! -------
! 885
! (1 row)
!
! set enable_hashagg = false;
! select count(*) from (select h from (select * from testhstore union all select * from testhstore) hs group by h) hs2;
! count
! -------
! 885
! (1 row)
!
! set enable_hashagg = true;
! set enable_sort = false;
! select count(*) from (select h from (select * from testhstore union all select * from testhstore) hs group by h) hs2;
! count
! -------
! 885
! (1 row)
!
! select distinct * from (values (hstore '' || ''),('')) v(h);
! h
! ---
!
! (1 row)
!
! set enable_sort = true;
! -- btree
! drop index hidx;
! create index hidx on testhstore using btree (h);
! set enable_seqscan=off;
! select count(*) from testhstore where h #># 'p=>1';
! count
! -------
! 125
! (1 row)
!
! select count(*) from testhstore where h = 'pos=>98, line=>371, node=>CBA, indexed=>t';
! count
! -------
! 1
! (1 row)
!
! -- json and jsonb
! select hstore_to_json('"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4');
! hstore_to_json
! -------------------------------------------------------------------------------------------------
! {"b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4", "a key": "1"}
! (1 row)
!
! select cast( hstore '"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4' as json);
! json
! -------------------------------------------------------------------------------------------------
! {"b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4", "a key": "1"}
! (1 row)
!
! select hstore_to_json_loose('"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4, h=> "2016-01-01"');
! hstore_to_json_loose
! -------------------------------------------------------------------------------------------------------------
! {"b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4, "h": "2016-01-01", "a key": 1}
! (1 row)
!
! select hstore_to_jsonb('"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4');
! hstore_to_jsonb
! -------------------------------------------------------------------------------------------------
! {"b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4", "a key": "1"}
! (1 row)
!
! select cast( hstore '"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4' as jsonb);
! jsonb
! -------------------------------------------------------------------------------------------------
! {"b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4", "a key": "1"}
! (1 row)
!
! select hstore_to_jsonb_loose('"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4, h=> "2016-01-01"');
! hstore_to_jsonb_loose
! ----------------------------------------------------------------------------------------------------------
! {"b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 23450, "h": "2016-01-01", "a key": 1}
! (1 row)
!
! create table test_json_agg (f1 text, f2 hstore);
! insert into test_json_agg values ('rec1','"a key" =>1, b => t, c => null, d=> 12345, e => 012345, f=> 1.234, g=> 2.345e+4'),
! ('rec2','"a key" =>2, b => f, c => "null", d=> -12345, e => 012345.6, f=> -1.234, g=> 0.345e-4');
! select json_agg(q) from test_json_agg q;
! json_agg
! ----------------------------------------------------------------------------------------------------------------------------
! [{"f1":"rec1","f2":{"b": "t", "c": null, "d": "12345", "e": "012345", "f": "1.234", "g": "2.345e+4", "a key": "1"}}, +
! {"f1":"rec2","f2":{"b": "f", "c": "null", "d": "-12345", "e": "012345.6", "f": "-1.234", "g": "0.345e-4", "a key": "2"}}]
! (1 row)
!
! select json_agg(q) from (select f1, hstore_to_json_loose(f2) as f2 from test_json_agg) q;
! json_agg
! ----------------------------------------------------------------------------------------------------------------------
! [{"f1":"rec1","f2":{"b": true, "c": null, "d": 12345, "e": "012345", "f": 1.234, "g": 2.345e+4, "a key": 1}}, +
! {"f1":"rec2","f2":{"b": false, "c": "null", "d": -12345, "e": "012345.6", "f": -1.234, "g": 0.345e-4, "a key": 2}}]
! (1 row)
!
--- 1161,1167 ----
(1 row)
select * from skeys('aa=>1 , b=>2, cq=>3'::hstore || 'cq=>l, b=>g, fg=>f');
! server closed the connection unexpectedly
! This probably means the server terminated abnormally
! before or while processing the request.
! connection to server was lost
======================================================================
hstore.out (text/plain, 79B) download
test hstore ... FAILED (test process exited with exit code 2)
pgcrypto.diffs (text/plain, 67.0K) downloadpgcrypto.out (text/plain, 966B) download
test init ... ok
test md5 ... ok
test hmac-md5 ... ok
test hmac-sha1 ... ok
test blowfish ... ok
test rijndael ... ok
test sha2 ... ok
test crypt-des ... ok
test crypt-md5 ... ok
test crypt-blowfish ... ok
test crypt-xdes ... ok
test pgp-armor ... FAILED (test process exited with exit code 2)
test pgp-decrypt ... FAILED (test process exited with exit code 2)
test pgp-encrypt ... FAILED (test process exited with exit code 2)
test pgp-compression ... FAILED (test process exited with exit code 2)
test pgp-pubkey-decrypt ... FAILED (test process exited with exit code 2)
test pgp-pubkey-encrypt ... FAILED (test process exited with exit code 2)
test pgp-info ... FAILED (test process exited with exit code 2)
pgstattuple.diffs (text/plain, 12.7K) download
*** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgstattuple/expected/pgstattuple.out 2016-03-15 14:32:12.937978027 +0300
--- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgstattuple/results/pgstattuple.out 2016-03-15 16:39:52.009673824 +0300
***************
*** 1,4 ****
--- 1,5 ----
CREATE EXTENSION pgstattuple;
+ ERROR: could not load library "/usr/local/pgsql/lib/pgstattuple.so": /usr/local/pgsql/lib/pgstattuple.so: undefined symbol: visibilitymap_test
--
-- It's difficult to come up with platform-independent test cases for
-- the pgstattuple functions, but the results for empty tables and
***************
*** 6,132 ****
--
create table test (a int primary key, b int[]);
select * from pgstattuple('test');
! table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
! -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
! 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
! (1 row)
!
select * from pgstattuple('test'::text);
! table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
! -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
! 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
! (1 row)
!
select * from pgstattuple('test'::name);
! table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
! -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
! 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
! (1 row)
!
select * from pgstattuple('test'::regclass);
! table_len | tuple_count | tuple_len | tuple_percent | dead_tuple_count | dead_tuple_len | dead_tuple_percent | free_space | free_percent
! -----------+-------------+-----------+---------------+------------------+----------------+--------------------+------------+--------------
! 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
! (1 row)
!
select pgstattuple(oid) from pg_class where relname = 'test';
! pgstattuple
! ---------------------
! (0,0,0,0,0,0,0,0,0)
! (1 row)
!
select pgstattuple(relname) from pg_class where relname = 'test';
! pgstattuple
! ---------------------
! (0,0,0,0,0,0,0,0,0)
! (1 row)
!
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey');
! version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
! ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
! 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN
! (1 row)
!
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::text);
! version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
! ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
! 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN
! (1 row)
!
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::name);
! version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
! ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
! 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN
! (1 row)
!
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::regclass);
! version | tree_level | index_size | root_block_no | internal_pages | leaf_pages | empty_pages | deleted_pages | avg_leaf_density | leaf_fragmentation
! ---------+------------+------------+---------------+----------------+------------+-------------+---------------+------------------+--------------------
! 2 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | NaN | NaN
! (1 row)
!
select pg_relpages('test');
! pg_relpages
! -------------
! 0
! (1 row)
!
select pg_relpages('test_pkey');
! pg_relpages
! -------------
! 1
! (1 row)
!
select pg_relpages('test_pkey'::text);
! pg_relpages
! -------------
! 1
! (1 row)
!
select pg_relpages('test_pkey'::name);
! pg_relpages
! -------------
! 1
! (1 row)
!
select pg_relpages('test_pkey'::regclass);
! pg_relpages
! -------------
! 1
! (1 row)
!
select pg_relpages(oid) from pg_class where relname = 'test_pkey';
! pg_relpages
! -------------
! 1
! (1 row)
!
select pg_relpages(relname) from pg_class where relname = 'test_pkey';
! pg_relpages
! -------------
! 1
! (1 row)
!
create index test_ginidx on test using gin (b);
select * from pgstatginindex('test_ginidx');
! version | pending_pages | pending_tuples
! ---------+---------------+----------------
! 2 | 0 | 0
! (1 row)
!
--- 7,115 ----
--
create table test (a int primary key, b int[]);
select * from pgstattuple('test');
! ERROR: function pgstattuple(unknown) does not exist
! LINE 1: select * from pgstattuple('test');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select * from pgstattuple('test'::text);
! ERROR: function pgstattuple(text) does not exist
! LINE 1: select * from pgstattuple('test'::text);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select * from pgstattuple('test'::name);
! ERROR: function pgstattuple(name) does not exist
! LINE 1: select * from pgstattuple('test'::name);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select * from pgstattuple('test'::regclass);
! ERROR: function pgstattuple(regclass) does not exist
! LINE 1: select * from pgstattuple('test'::regclass);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pgstattuple(oid) from pg_class where relname = 'test';
! ERROR: function pgstattuple(oid) does not exist
! LINE 1: select pgstattuple(oid) from pg_class where relname = 'test'...
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pgstattuple(relname) from pg_class where relname = 'test';
! ERROR: function pgstattuple(name) does not exist
! LINE 1: select pgstattuple(relname) from pg_class where relname = 't...
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey');
! ERROR: function pgstatindex(unknown) does not exist
! LINE 5: from pgstatindex('test_pkey');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::text);
! ERROR: function pgstatindex(text) does not exist
! LINE 5: from pgstatindex('test_pkey'::text);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::name);
! ERROR: function pgstatindex(name) does not exist
! LINE 5: from pgstatindex('test_pkey'::name);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select version, tree_level,
index_size / current_setting('block_size')::int as index_size,
root_block_no, internal_pages, leaf_pages, empty_pages, deleted_pages,
avg_leaf_density, leaf_fragmentation
from pgstatindex('test_pkey'::regclass);
! ERROR: function pgstatindex(regclass) does not exist
! LINE 5: from pgstatindex('test_pkey'::regclass);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages('test');
! ERROR: function pg_relpages(unknown) does not exist
! LINE 1: select pg_relpages('test');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages('test_pkey');
! ERROR: function pg_relpages(unknown) does not exist
! LINE 1: select pg_relpages('test_pkey');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages('test_pkey'::text);
! ERROR: function pg_relpages(text) does not exist
! LINE 1: select pg_relpages('test_pkey'::text);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages('test_pkey'::name);
! ERROR: function pg_relpages(name) does not exist
! LINE 1: select pg_relpages('test_pkey'::name);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages('test_pkey'::regclass);
! ERROR: function pg_relpages(regclass) does not exist
! LINE 1: select pg_relpages('test_pkey'::regclass);
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages(oid) from pg_class where relname = 'test_pkey';
! ERROR: function pg_relpages(oid) does not exist
! LINE 1: select pg_relpages(oid) from pg_class where relname = 'test_...
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
select pg_relpages(relname) from pg_class where relname = 'test_pkey';
! ERROR: function pg_relpages(name) does not exist
! LINE 1: select pg_relpages(relname) from pg_class where relname = 't...
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
create index test_ginidx on test using gin (b);
select * from pgstatginindex('test_ginidx');
! ERROR: function pgstatginindex(unknown) does not exist
! LINE 1: select * from pgstatginindex('test_ginidx');
! ^
! HINT: No function matches the given name and argument types. You might need to add explicit type casts.
======================================================================
pgstattuple.out (text/plain, 40B) download
test pgstattuple ... FAILED
postgres_fdw.diffs (text/plain, 262.7K) downloadpostgres_fdw.out (text/plain, 79B) download
test postgres_fdw ... FAILED (test process exited with exit code 2)
tablefunc.diffs (text/plain, 21.4K) download
*** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/tablefunc/expected/tablefunc.out 2016-03-15 14:32:12.945978099 +0300
--- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/tablefunc/results/tablefunc.out 2016-03-15 16:58:19.297568781 +0300
***************
*** 4,427 ****
-- no easy way to do this for regression testing
--
SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2);
! avg
! -----
! 250
! (1 row)
!
! --
! -- crosstab()
! --
! CREATE TABLE ct(id int, rowclass text, rowid text, attribute text, val text);
! \copy ct from 'data/ct.data'
! SELECT * FROM crosstab2('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' and (attribute = ''att2'' or attribute = ''att3'') ORDER BY 1,2;');
! row_name | category_1 | category_2
! ----------+------------+------------
! test1 | val2 | val3
! test2 | val6 | val7
! | val10 | val11
! (3 rows)
!
! SELECT * FROM crosstab3('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' and (attribute = ''att2'' or attribute = ''att3'') ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3
! ----------+------------+------------+------------
! test1 | val2 | val3 |
! test2 | val6 | val7 |
! | val10 | val11 |
! (3 rows)
!
! SELECT * FROM crosstab4('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' and (attribute = ''att2'' or attribute = ''att3'') ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3 | category_4
! ----------+------------+------------+------------+------------
! test1 | val2 | val3 | |
! test2 | val6 | val7 | |
! | val10 | val11 | |
! (3 rows)
!
! SELECT * FROM crosstab2('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;');
! row_name | category_1 | category_2
! ----------+------------+------------
! test1 | val1 | val2
! test2 | val5 | val6
! | val9 | val10
! (3 rows)
!
! SELECT * FROM crosstab3('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3
! ----------+------------+------------+------------
! test1 | val1 | val2 | val3
! test2 | val5 | val6 | val7
! | val9 | val10 | val11
! (3 rows)
!
! SELECT * FROM crosstab4('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3 | category_4
! ----------+------------+------------+------------+------------
! test1 | val1 | val2 | val3 | val4
! test2 | val5 | val6 | val7 | val8
! | val9 | val10 | val11 | val12
! (3 rows)
!
! SELECT * FROM crosstab2('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' and (attribute = ''att1'' or attribute = ''att2'') ORDER BY 1,2;');
! row_name | category_1 | category_2
! ----------+------------+------------
! test3 | val1 | val2
! test4 | val4 | val5
! (2 rows)
!
! SELECT * FROM crosstab3('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' and (attribute = ''att1'' or attribute = ''att2'') ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3
! ----------+------------+------------+------------
! test3 | val1 | val2 |
! test4 | val4 | val5 |
! (2 rows)
!
! SELECT * FROM crosstab4('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' and (attribute = ''att1'' or attribute = ''att2'') ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3 | category_4
! ----------+------------+------------+------------+------------
! test3 | val1 | val2 | |
! test4 | val4 | val5 | |
! (2 rows)
!
! SELECT * FROM crosstab2('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' ORDER BY 1,2;');
! row_name | category_1 | category_2
! ----------+------------+------------
! test3 | val1 | val2
! test4 | val4 | val5
! (2 rows)
!
! SELECT * FROM crosstab3('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3
! ----------+------------+------------+------------
! test3 | val1 | val2 | val3
! test4 | val4 | val5 | val6
! (2 rows)
!
! SELECT * FROM crosstab4('SELECT rowid, attribute, val FROM ct where rowclass = ''group2'' ORDER BY 1,2;');
! row_name | category_1 | category_2 | category_3 | category_4
! ----------+------------+------------+------------+------------
! test3 | val1 | val2 | val3 |
! test4 | val4 | val5 | val6 |
! (2 rows)
!
! SELECT * FROM crosstab('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;') AS c(rowid text, att1 text, att2 text);
! rowid | att1 | att2
! -------+------+-------
! test1 | val1 | val2
! test2 | val5 | val6
! | val9 | val10
! (3 rows)
!
! SELECT * FROM crosstab('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;') AS c(rowid text, att1 text, att2 text, att3 text);
! rowid | att1 | att2 | att3
! -------+------+-------+-------
! test1 | val1 | val2 | val3
! test2 | val5 | val6 | val7
! | val9 | val10 | val11
! (3 rows)
!
! SELECT * FROM crosstab('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;') AS c(rowid text, att1 text, att2 text, att3 text, att4 text);
! rowid | att1 | att2 | att3 | att4
! -------+------+-------+-------+-------
! test1 | val1 | val2 | val3 | val4
! test2 | val5 | val6 | val7 | val8
! | val9 | val10 | val11 | val12
! (3 rows)
!
! -- check it works with OUT parameters, too
! CREATE FUNCTION crosstab_out(text,
! OUT rowid text, OUT att1 text, OUT att2 text, OUT att3 text)
! RETURNS setof record
! AS '$libdir/tablefunc','crosstab'
! LANGUAGE C STABLE STRICT;
! SELECT * FROM crosstab_out('SELECT rowid, attribute, val FROM ct where rowclass = ''group1'' ORDER BY 1,2;');
! rowid | att1 | att2 | att3
! -------+------+-------+-------
! test1 | val1 | val2 | val3
! test2 | val5 | val6 | val7
! | val9 | val10 | val11
! (3 rows)
!
! --
! -- hash based crosstab
! --
! create table cth(id serial, rowid text, rowdt timestamp, attribute text, val text);
! insert into cth values(DEFAULT,'test1','01 March 2003','temperature','42');
! insert into cth values(DEFAULT,'test1','01 March 2003','test_result','PASS');
! -- the next line is intentionally left commented and is therefore a "missing" attribute
! -- insert into cth values(DEFAULT,'test1','01 March 2003','test_startdate','28 February 2003');
! insert into cth values(DEFAULT,'test1','01 March 2003','volts','2.6987');
! insert into cth values(DEFAULT,'test2','02 March 2003','temperature','53');
! insert into cth values(DEFAULT,'test2','02 March 2003','test_result','FAIL');
! insert into cth values(DEFAULT,'test2','02 March 2003','test_startdate','01 March 2003');
! insert into cth values(DEFAULT,'test2','02 March 2003','volts','3.1234');
! -- next group tests for NULL rowids
! insert into cth values(DEFAULT,NULL,'25 October 2007','temperature','57');
! insert into cth values(DEFAULT,NULL,'25 October 2007','test_result','PASS');
! insert into cth values(DEFAULT,NULL,'25 October 2007','test_startdate','24 October 2007');
! insert into cth values(DEFAULT,NULL,'25 October 2007','volts','1.41234');
! -- return attributes as plain text
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature text, test_result text, test_startdate text, volts text);
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+--------------------------+-------------+-------------+-----------------+---------
! test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
! test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | 01 March 2003 | 3.1234
! | Thu Oct 25 00:00:00 2007 | 57 | PASS | 24 October 2007 | 1.41234
! (3 rows)
!
! -- this time without rowdt
! SELECT * FROM crosstab(
! 'SELECT rowid, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1')
! AS c(rowid text, temperature text, test_result text, test_startdate text, volts text);
! rowid | temperature | test_result | test_startdate | volts
! -------+-------------+-------------+-----------------+---------
! test1 | 42 | PASS | | 2.6987
! test2 | 53 | FAIL | 01 March 2003 | 3.1234
! | 57 | PASS | 24 October 2007 | 1.41234
! (3 rows)
!
! -- convert attributes to specific datatypes
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature int4, test_result text, test_startdate timestamp, volts float8);
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+--------------------------+-------------+-------------+--------------------------+---------
! test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
! test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
! | Thu Oct 25 00:00:00 2007 | 57 | PASS | Wed Oct 24 00:00:00 2007 | 1.41234
! (3 rows)
!
! -- source query and category query out of sync
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth WHERE attribute IN (''temperature'',''test_result'',''test_startdate'') ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature int4, test_result text, test_startdate timestamp);
! rowid | rowdt | temperature | test_result | test_startdate
! -------+--------------------------+-------------+-------------+--------------------------
! test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS |
! test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003
! | Thu Oct 25 00:00:00 2007 | 57 | PASS | Wed Oct 24 00:00:00 2007
! (3 rows)
!
! -- if category query generates no rows, get expected error
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth WHERE attribute = ''a'' ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature int4, test_result text, test_startdate timestamp, volts float8);
! ERROR: provided "categories" SQL must return 1 column of at least one row
! -- if category query generates more than one column, get expected error
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT rowdt, attribute FROM cth ORDER BY 2')
! AS c(rowid text, rowdt timestamp, temperature int4, test_result text, test_startdate timestamp, volts float8);
! ERROR: provided "categories" SQL must return 1 column of at least one row
! -- if source query returns zero rows, get zero rows returned
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth WHERE false ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature text, test_result text, test_startdate text, volts text);
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+-------+-------------+-------------+----------------+-------
! (0 rows)
!
! -- if source query returns zero rows, get zero rows returned even if category query generates no rows
! SELECT * FROM crosstab(
! 'SELECT rowid, rowdt, attribute, val FROM cth WHERE false ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth WHERE false ORDER BY 1')
! AS c(rowid text, rowdt timestamp, temperature text, test_result text, test_startdate text, volts text);
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+-------+-------------+-------------+----------------+-------
! (0 rows)
!
! -- check it works with a named result rowtype
! create type my_crosstab_result as (
! rowid text, rowdt timestamp,
! temperature int4, test_result text, test_startdate timestamp, volts float8);
! CREATE FUNCTION crosstab_named(text, text)
! RETURNS setof my_crosstab_result
! AS '$libdir/tablefunc','crosstab_hash'
! LANGUAGE C STABLE STRICT;
! SELECT * FROM crosstab_named(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1');
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+--------------------------+-------------+-------------+--------------------------+---------
! test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
! test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
! | Thu Oct 25 00:00:00 2007 | 57 | PASS | Wed Oct 24 00:00:00 2007 | 1.41234
! (3 rows)
!
! -- check it works with OUT parameters
! CREATE FUNCTION crosstab_out(text, text,
! OUT rowid text, OUT rowdt timestamp,
! OUT temperature int4, OUT test_result text,
! OUT test_startdate timestamp, OUT volts float8)
! RETURNS setof record
! AS '$libdir/tablefunc','crosstab_hash'
! LANGUAGE C STABLE STRICT;
! SELECT * FROM crosstab_out(
! 'SELECT rowid, rowdt, attribute, val FROM cth ORDER BY 1',
! 'SELECT DISTINCT attribute FROM cth ORDER BY 1');
! rowid | rowdt | temperature | test_result | test_startdate | volts
! -------+--------------------------+-------------+-------------+--------------------------+---------
! test1 | Sat Mar 01 00:00:00 2003 | 42 | PASS | | 2.6987
! test2 | Sun Mar 02 00:00:00 2003 | 53 | FAIL | Sat Mar 01 00:00:00 2003 | 3.1234
! | Thu Oct 25 00:00:00 2007 | 57 | PASS | Wed Oct 24 00:00:00 2007 | 1.41234
! (3 rows)
!
! --
! -- connectby
! --
! -- test connectby with text based hierarchy
! CREATE TABLE connectby_text(keyid text, parent_keyid text, pos int);
! \copy connectby_text from 'data/connectby_text.data'
! -- with branch, without orderby
! SELECT * FROM connectby('connectby_text', 'keyid', 'parent_keyid', 'row2', 0, '~') AS t(keyid text, parent_keyid text, level int, branch text);
! keyid | parent_keyid | level | branch
! -------+--------------+-------+---------------------
! row2 | | 0 | row2
! row4 | row2 | 1 | row2~row4
! row6 | row4 | 2 | row2~row4~row6
! row8 | row6 | 3 | row2~row4~row6~row8
! row5 | row2 | 1 | row2~row5
! row9 | row5 | 2 | row2~row5~row9
! (6 rows)
!
! -- without branch, without orderby
! SELECT * FROM connectby('connectby_text', 'keyid', 'parent_keyid', 'row2', 0) AS t(keyid text, parent_keyid text, level int);
! keyid | parent_keyid | level
! -------+--------------+-------
! row2 | | 0
! row4 | row2 | 1
! row6 | row4 | 2
! row8 | row6 | 3
! row5 | row2 | 1
! row9 | row5 | 2
! (6 rows)
!
! -- with branch, with orderby
! SELECT * FROM connectby('connectby_text', 'keyid', 'parent_keyid', 'pos', 'row2', 0, '~') AS t(keyid text, parent_keyid text, level int, branch text, pos int) ORDER BY t.pos;
! keyid | parent_keyid | level | branch | pos
! -------+--------------+-------+---------------------+-----
! row2 | | 0 | row2 | 1
! row5 | row2 | 1 | row2~row5 | 2
! row9 | row5 | 2 | row2~row5~row9 | 3
! row4 | row2 | 1 | row2~row4 | 4
! row6 | row4 | 2 | row2~row4~row6 | 5
! row8 | row6 | 3 | row2~row4~row6~row8 | 6
! (6 rows)
!
! -- without branch, with orderby
! SELECT * FROM connectby('connectby_text', 'keyid', 'parent_keyid', 'pos', 'row2', 0) AS t(keyid text, parent_keyid text, level int, pos int) ORDER BY t.pos;
! keyid | parent_keyid | level | pos
! -------+--------------+-------+-----
! row2 | | 0 | 1
! row5 | row2 | 1 | 2
! row9 | row5 | 2 | 3
! row4 | row2 | 1 | 4
! row6 | row4 | 2 | 5
! row8 | row6 | 3 | 6
! (6 rows)
!
! -- test connectby with int based hierarchy
! CREATE TABLE connectby_int(keyid int, parent_keyid int);
! \copy connectby_int from 'data/connectby_int.data'
! -- with branch
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 0, '~') AS t(keyid int, parent_keyid int, level int, branch text);
! keyid | parent_keyid | level | branch
! -------+--------------+-------+---------
! 2 | | 0 | 2
! 4 | 2 | 1 | 2~4
! 6 | 4 | 2 | 2~4~6
! 8 | 6 | 3 | 2~4~6~8
! 5 | 2 | 1 | 2~5
! 9 | 5 | 2 | 2~5~9
! (6 rows)
!
! -- without branch
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 0) AS t(keyid int, parent_keyid int, level int);
! keyid | parent_keyid | level
! -------+--------------+-------
! 2 | | 0
! 4 | 2 | 1
! 6 | 4 | 2
! 8 | 6 | 3
! 5 | 2 | 1
! 9 | 5 | 2
! (6 rows)
!
! -- recursion detection
! INSERT INTO connectby_int VALUES(10,9);
! INSERT INTO connectby_int VALUES(11,10);
! INSERT INTO connectby_int VALUES(9,11);
! -- should fail due to infinite recursion
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 0, '~') AS t(keyid int, parent_keyid int, level int, branch text);
! ERROR: infinite recursion detected
! -- infinite recursion failure avoided by depth limit
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 4, '~') AS t(keyid int, parent_keyid int, level int, branch text);
! keyid | parent_keyid | level | branch
! -------+--------------+-------+-------------
! 2 | | 0 | 2
! 4 | 2 | 1 | 2~4
! 6 | 4 | 2 | 2~4~6
! 8 | 6 | 3 | 2~4~6~8
! 5 | 2 | 1 | 2~5
! 9 | 5 | 2 | 2~5~9
! 10 | 9 | 3 | 2~5~9~10
! 11 | 10 | 4 | 2~5~9~10~11
! (8 rows)
!
! -- should fail as first two columns must have the same type
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 0, '~') AS t(keyid text, parent_keyid int, level int, branch text);
! ERROR: invalid return type
! DETAIL: First two columns must be the same type.
! -- should fail as key field datatype should match return datatype
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '2', 0, '~') AS t(keyid float8, parent_keyid float8, level int, branch text);
! ERROR: invalid return type
! DETAIL: SQL key field type double precision does not match return key field type integer.
! -- tests for values using custom queries
! -- query with one column - failed
! SELECT * FROM connectby('connectby_int', '1; --', 'parent_keyid', '2', 0) AS t(keyid int, parent_keyid int, level int);
! ERROR: invalid return type
! DETAIL: Query must return at least two columns.
! -- query with two columns first value as NULL
! SELECT * FROM connectby('connectby_int', 'NULL::int, 1::int; --', 'parent_keyid', '2', 0) AS t(keyid int, parent_keyid int, level int);
! keyid | parent_keyid | level
! -------+--------------+-------
! 2 | | 0
! | 1 | 1
! (2 rows)
!
! -- query with two columns second value as NULL
! SELECT * FROM connectby('connectby_int', '1::int, NULL::int; --', 'parent_keyid', '2', 0) AS t(keyid int, parent_keyid int, level int);
! ERROR: infinite recursion detected
! -- query with two columns, both values as NULL
! SELECT * FROM connectby('connectby_int', 'NULL::int, NULL::int; --', 'parent_keyid', '2', 0) AS t(keyid int, parent_keyid int, level int);
! keyid | parent_keyid | level
! -------+--------------+-------
! 2 | | 0
! | | 1
! (2 rows)
!
! -- test for falsely detected recursion
! DROP TABLE connectby_int;
! CREATE TABLE connectby_int(keyid int, parent_keyid int);
! INSERT INTO connectby_int VALUES(11,NULL);
! INSERT INTO connectby_int VALUES(10,11);
! INSERT INTO connectby_int VALUES(111,11);
! INSERT INTO connectby_int VALUES(1,111);
! -- this should not fail due to recursion detection
! SELECT * FROM connectby('connectby_int', 'keyid', 'parent_keyid', '11', 0, '-') AS t(keyid int, parent_keyid int, level int, branch text);
! keyid | parent_keyid | level | branch
! -------+--------------+-------+----------
! 11 | | 0 | 11
! 10 | 11 | 1 | 11-10
! 111 | 11 | 1 | 11-111
! 1 | 111 | 2 | 11-111-1
! (4 rows)
!
--- 4,10 ----
-- no easy way to do this for regression testing
--
SELECT avg(normal_rand)::int FROM normal_rand(100, 250, 0.2);
! server closed the connection unexpectedly
! This probably means the server terminated abnormally
! before or while processing the request.
! connection to server was lost
======================================================================
tablefunc.out (text/plain, 79B) download
test tablefunc ... FAILED (test process exited with exit code 2)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: v.popov@postgrespro.ru, michael.paquier@gmail.com, david@pgmasters.net
Subject: Re: Password identifiers, protocol aging and SCRAM protocol
In-Reply-To: <56E82049.8040204@postgrespro.ru>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox