pg.ddx.io  pgsql-hackers@postgresql.org mailing list archive  
help / color / mirror / Atom feed
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-hackers

Attachments:

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) download
pgcrypto.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) download
postgres_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)

view thread (149+ messages)  latest in thread

Message-ID: <56E82049.8040204@postgrespro.ru>
Permalink:  ../56E82049.8040204@postgrespro.ru/
Also on:    postgresql.org/message-id/56E82049.8040204@postgrespro.ru

 · 

reply

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