Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1afqFd-0004Oj-HQ for pgsql-hackers@arkaria.postgresql.org; Tue, 15 Mar 2016 14:47:14 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1afqFc-0007mZ-TI for pgsql-hackers@arkaria.postgresql.org; Tue, 15 Mar 2016 14:47:12 +0000 Received: from makus.postgresql.org ([2001:4800:1501:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1afqFZ-0007mS-L1 for pgsql-hackers@postgresql.org; Tue, 15 Mar 2016 14:47:10 +0000 Received: from newmail.postgrespro.ru ([93.174.131.138] helo=mail.postgrespro.ru) by makus.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1afqFD-0004Rx-IO for pgsql-hackers@postgresql.org; Tue, 15 Mar 2016 14:47:08 +0000 Received: from localhost (localhost [127.0.0.1]) by mail.postgrespro.ru (Postfix) with ESMTP id 19A9021C6E2C; Tue, 15 Mar 2016 17:46:45 +0300 (MSK) Received: from mail.postgrespro.ru ([127.0.0.1]) by localhost (mail.postgrespro.ru [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id L2OdBG3aHalo; Tue, 15 Mar 2016 17:46:33 +0300 (MSK) Received: from [192.168.27.123] (unknown [192.168.27.1]) by mail.postgrespro.ru (Postfix) with ESMTPSA id 4186721C6BB6; Tue, 15 Mar 2016 17:46:33 +0300 (MSK) Subject: Re: Password identifiers, protocol aging and SCRAM protocol To: pgsql-hackers@postgresql.org, "michael.paquier@gmail.com >> Michael Paquier" References: <56E6D98F.1070701@pgmasters.net> Cc: david@pgmasters.net From: Valery Popov Message-ID: <56E82049.8040204@postgrespro.ru> Date: Tue, 15 Mar 2016 17:46:33 +0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: multipart/mixed; boundary="------------020302030909030204070803" X-Pg-Spam-Score: -1.9 (-) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-hackers Precedence: bulk Sender: pgsql-hackers-owner@postgresql.org This is a multi-part message in MIME format. --------------020302030909030204070803 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit 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 --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="dblink.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dblink.diffs" *** /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 ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="dblink.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="dblink.out" test paths ... ok test dblink ... FAILED (test process exited with exit code 2) --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="file_fdw.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file_fdw.diffs" *** /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 ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="file_fdw.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="file_fdw.out" test file_fdw ... FAILED (test process exited with exit code 2) --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="hstore.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="hstore.diffs" *** /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 ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="hstore.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="hstore.out" test hstore ... FAILED (test process exited with exit code 2) --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="pgcrypto.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pgcrypto.diffs" *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-armor.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-armor.out 2016-03-15 16:28:48.539641414 +0300 *************** *** 111,372 **** =ZZZZ -----END PGP MESSAGE----- '); ! ERROR: Corrupt ascii-armor ! -- corrupt (no empty line) ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! ERROR: Corrupt ascii-armor ! -- no headers ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! -----+------- ! (0 rows) ! ! -- header with empty value ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! foo: ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! -----+------- ! foo | ! (1 row) ! ! -- simple ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! fookey: foovalue ! barkey: barvalue ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! --------+---------- ! fookey | foovalue ! barkey | barvalue ! (2 rows) ! ! -- insane keys, part 1 ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! insane:key : ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! -------------+------- ! insane:key | ! (1 row) ! ! -- insane keys, part 2 ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! insane:key : text value here ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! -------------+----------------- ! insane:key | text value here ! (1 row) ! ! -- long value ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! long: this value is more than 76 characters long, but it should still parse correctly as that''s permitted by RFC 4880 ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! ------+----------------------------------------------------------------------------------------------------------------- ! long | this value is more than 76 characters long, but it should still parse correctly as that's permitted by RFC 4880 ! (1 row) ! ! -- long value, split up ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! long: this value is more than 76 characters long, but it should still ! long: parse correctly as that''s permitted by RFC 4880 ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! ------+------------------------------------------------------------------ ! long | this value is more than 76 characters long, but it should still ! long | parse correctly as that's permitted by RFC 4880 ! (2 rows) ! ! -- long value, split up, part 2 ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! long: this value is more than ! long: 76 characters long, but it should still ! long: parse correctly as that''s permitted by RFC 4880 ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! ------+------------------------------------------------- ! long | this value is more than ! long | 76 characters long, but it should still ! long | parse correctly as that's permitted by RFC 4880 ! (3 rows) ! ! -- long value, split up, part 3 ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! emptykey: ! long: this value is more than ! emptykey: ! long: 76 characters long, but it should still ! emptykey: ! long: parse correctly as that''s permitted by RFC 4880 ! emptykey: ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! '); ! key | value ! ----------+------------------------------------------------- ! emptykey | ! long | this value is more than ! emptykey | ! long | 76 characters long, but it should still ! emptykey | ! long | parse correctly as that's permitted by RFC 4880 ! emptykey | ! (7 rows) ! ! select * from pgp_armor_headers(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.blowfish.sha1.mdc.s2k3.z0 ! ! jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS ! yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE= ! =JcP+ ! -----END PGP MESSAGE----- ! '); ! key | value ! ---------+-------------------------------- ! Comment | dat1.blowfish.sha1.mdc.s2k3.z0 ! (1 row) ! ! -- test CR+LF line endings ! select * from pgp_armor_headers(replace(' ! -----BEGIN PGP MESSAGE----- ! fookey: foovalue ! barkey: barvalue ! ! em9va2E= ! =ZZZZ ! -----END PGP MESSAGE----- ! ', E'\n', E'\r\n')); ! key | value ! --------+---------- ! fookey | foovalue ! barkey | barvalue ! (2 rows) ! ! -- test header generation ! select armor('zooka', array['foo'], array['bar']); ! armor ! ----------------------------- ! -----BEGIN PGP MESSAGE-----+ ! foo: bar + ! + ! em9va2E= + ! =D5cR + ! -----END PGP MESSAGE----- + ! ! (1 row) ! ! select armor('zooka', array['Version', 'Comment'], array['Created by pgcrypto', 'PostgreSQL, the world''s most advanced open source database']); ! armor ! --------------------------------------------------------------------- ! -----BEGIN PGP MESSAGE----- + ! Version: Created by pgcrypto + ! Comment: PostgreSQL, the world's most advanced open source database+ ! + ! em9va2E= + ! =D5cR + ! -----END PGP MESSAGE----- + ! ! (1 row) ! ! select * from pgp_armor_headers( ! armor('zooka', array['Version', 'Comment'], ! array['Created by pgcrypto', 'PostgreSQL, the world''s most advanced open source database'])); ! key | value ! ---------+------------------------------------------------------------ ! Version | Created by pgcrypto ! Comment | PostgreSQL, the world's most advanced open source database ! (2 rows) ! ! -- error/corner cases ! select armor('', array['foo'], array['too', 'many']); ! ERROR: mismatched array dimensions ! select armor('', array['too', 'many'], array['foo']); ! ERROR: mismatched array dimensions ! select armor('', array[['']], array['foo']); ! ERROR: wrong number of array subscripts ! select armor('', array['foo'], array[['']]); ! ERROR: wrong number of array subscripts ! select armor('', array[null], array['foo']); ! ERROR: null value not allowed for header key ! select armor('', array['foo'], array[null]); ! ERROR: null value not allowed for header value ! select armor('', '[0:0]={"foo"}', array['foo']); ! armor ! ----------------------------- ! -----BEGIN PGP MESSAGE-----+ ! foo: foo + ! + ! =twTO + ! -----END PGP MESSAGE----- + ! ! (1 row) ! ! select armor('', array['foo'], '[0:0]={"foo"}'); ! armor ! ----------------------------- ! -----BEGIN PGP MESSAGE-----+ ! foo: foo + ! + ! =twTO + ! -----END PGP MESSAGE----- + ! ! (1 row) ! ! select armor('', array[E'embedded\nnewline'], array['foo']); ! ERROR: header key must not contain newlines ! select armor('', array['foo'], array[E'embedded\nnewline']); ! ERROR: header value must not contain newlines ! select armor('', array['embedded: colon+space'], array['foo']); ! ERROR: header key must not contain ": " --- 111,117 ---- =ZZZZ -----END PGP MESSAGE----- '); ! server closed the connection unexpectedly ! This probably means the server terminated abnormally ! before or while processing the request. ! connection to server was lost ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-decrypt.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-decrypt.out 2016-03-15 16:28:48.603642001 +0300 *************** *** 1,425 **** ! -- ! -- pgp_descrypt tests ! -- ! -- Checking ciphers ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.blowfish.sha1.mdc.s2k3.z0 ! ! jA0EBAMCfFNwxnvodX9g0jwB4n4s26/g5VmKzVab1bX1SmwY7gvgvlWdF3jKisvS ! yA6Ce1QTMK3KdL2MPfamsTUSAML8huCJMwYQFfE= ! =JcP+ ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCci97v0Q6Z0Zg0kQBsVf5Oe3iC+FBzUmuMV9KxmAyOMyjCc/5i8f1Eest ! UTAsG35A1vYs02VARKzGz6xI2UHwFUirP+brPBg3Ee7muOx8pA== ! =XtrP ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes192.sha1.mdc.s2k3.z0 ! ! jA0ECAMCI7YQpWqp3D1g0kQBCjB7GlX7+SQeXNleXeXQ78ZAPNliquGDq9u378zI ! 5FPTqAhIB2/2fjY8QEIs1ai00qphjX2NitxV/3Wn+6dufB4Q4g== ! =rCZt ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes256.sha1.mdc.s2k3.z0 ! ! jA0ECQMC4f/5djqCC1Rg0kQBTHEPsD+Sw7biBsM2er3vKyGPAQkuTBGKC5ie7hT/ ! lceMfQdbAg6oTFyJpk/wH18GzRDphCofg0X8uLgkAKMrpcmgog== ! =fB6S ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- Checking MDC modes ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.nomdc.s2k3.z0 ! ! jA0EBwMCnv07rlXqWctgyS2Dm2JfOKCRL4sLSLJUC8RS2cH7cIhKSuLitOtyquB+ ! u9YkgfJfsuRJmgQ9tmo= ! =60ui ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCEeP3idNjQ1Bg0kQBf4G0wX+2QNzLh2YNwYkQgQkfYhn/hLXjV4nK9nsE ! 8Ex1Dsdt5UPvOz8W8VKQRS6loOfOe+yyXil8W3IYFwUpdDUi+Q== ! =moGf ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- Checking hashes ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.md5.mdc.s2k3.z0 ! ! jA0EBwMClrXXtOXetohg0kQBn0Kl1ymevQZRHkdoYRHgzCwSQEiss7zYff2UNzgO ! KyRrHf7zEBuZiZ2AG34jNVMOLToj1jJUg5zTSdecUzQVCykWTA== ! =NyLk ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCApbdlrURoWJg0kQBzHM/E0o7djY82bNuspjxjAcPFrrtp0uvDdMQ4z2m ! /PM8jhgI5vxFYfNQjLl8y3fHYIomk9YflN9K/Q13iq8A8sjeTw== ! =FxbQ ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- Checking S2K modes ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k0.z0 ! ! jAQEBwAC0kQBKTaLAKE3xzps+QIZowqRNb2eAdzBw2LxEW2YD5PgNlbhJdGg+dvw ! Ah9GXjGS1TVALzTImJbz1uHUZRfhJlFbc5yGQw== ! =YvkV ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k1.z0 ! ! jAwEBwEC/QTByBLI3b/SRAHPxKzI6SZBo5lAEOD+EsvKQWO4adL9tDY+++Iqy1xK ! 4IaWXVKEj9R2Lr2xntWWMGZtcKtjD2lFFRXXd9dZp1ZThNDz ! =dbXm ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCEq4Su3ZqNEJg0kQB4QG5jBTKF0i04xtH+avzmLhstBNRxvV3nsmB3cwl ! z+9ZaA/XdSx5ZiFnMym8P6r8uY9rLjjNptvvRHlxIReF+p9MNg== ! =VJKg ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes192.sha1.mdc.s2k0.z0 ! ! jAQECAAC0kQBBDnQWkgsx9YFaqDfWmpsiyAJ6y2xG/sBvap1dySYEMuZ+wJTXQ9E ! Cr3i2M7TgVZ0M4jp4QL0adG1lpN5iK7aQeOwMw== ! =cg+i ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes192.sha1.mdc.s2k1.z0 ! ! jAwECAECruOfyNDFiTnSRAEVoGXm4A9UZKkWljdzjEO/iaE7mIraltIpQMkiqCh9 ! 7h8uZ2u9uRBOv222fZodGvc6bvq/4R4hAa/6qSHtm8mdmvGt ! =aHmC ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes192.sha1.mdc.s2k3.z0 ! ! jA0ECAMCjFn6SRi3SONg0kQBqtSHPaD0m7rXfDAhCWU/ypAsI93GuHGRyM99cvMv ! q6eF6859ZVnli3BFSDSk3a4e/pXhglxmDYCfjAXkozKNYLo6yw== ! =K0LS ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes256.sha1.mdc.s2k0.z0 ! ! jAQECQAC0kQB4L1eMbani07XF2ZYiXNK9LW3v8w41oUPl7dStmrJPQFwsdxmrDHu ! rQr3WbdKdY9ufjOE5+mXI+EFkSPrF9rL9NCq6w== ! =RGts ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes256.sha1.mdc.s2k1.z0 ! ! jAwECQECKHhrou7ZOIXSRAHWIVP+xjVQcjAVBTt+qh9SNzYe248xFTwozkwev3mO ! +KVJW0qhk0An+Y2KF99/bYFl9cL5D3Tl43fC8fXGl3x3m7pR ! =SUrU ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes256.sha1.mdc.s2k3.z0 ! ! jA0ECQMCjc8lwZu8Fz1g0kQBkEzjImi21liep5jj+3dAJ2aZFfUkohi8b3n9z+7+ ! 4+NRzL7cMW2RLAFnJbiqXDlRHMwleeuLN1up2WIxsxtYYuaBjA== ! =XZrG ! -----END PGP MESSAGE----- ! '), 'foobar'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- Checking longer passwords ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCx6dBiuqrYNRg0kQBEo63AvA1SCslxP7ayanLf1H0/hlk2nONVhTwVEWi ! tTGup1mMz6Cfh1uDRErUuXpx9A0gdMu7zX0o5XjrL7WGDAZdSw== ! =XKKG ! -----END PGP MESSAGE----- ! '), '0123456789abcdefghij'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCBDvYuS990iFg0kQBW31UK5OiCjWf5x6KJ8qNNT2HZWQCjCBZMU0XsOC6 ! CMxFKadf144H/vpoV9GA0f22keQgCl0EsTE4V4lweVOPTKCMJg== ! =gWDh ! -----END PGP MESSAGE----- ! '), '0123456789abcdefghij2jk4h5g2j54khg23h54g2kh54g2khj54g23hj54'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCqXbFafC+ofVg0kQBejyiPqH0QMERVGfmPOjtAxvyG5KDIJPYojTgVSDt ! FwsDabdQUz5O7bgNSnxfmyw1OifGF+W2bIn/8W+0rDf8u3+O+Q== ! =OxOF ! -----END PGP MESSAGE----- ! '), 'x'); ! pgp_sym_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- Checking various data ! select encode(digest(pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat1.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCGJ+SpuOysINg0kQBJfSjzsW0x4OVcAyr17O7FBvMTwIGeGcJd99oTQU8 ! Xtx3kDqnhUq9Z1fS3qPbi5iNP2A9NxOBxPWz2JzxhydANlgbxg== ! =W/ik ! -----END PGP MESSAGE----- ! '), '0123456789abcdefghij'), 'sha1'), 'hex'); ! encode ! ------------------------------------------ ! 0225e3ede6f2587b076d021a189ff60aad67e066 ! (1 row) ! ! -- expected: 0225e3ede6f2587b076d021a189ff60aad67e066 ! select encode(digest(pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat2.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCvdpDvidNzMxg0jUBvj8eS2+1t/9/zgemxvhtc0fvdKGGbjH7dleaTJRB ! SaV9L04ky1qECNDx3XjnoKLC+H7IOQ== ! =Fxen ! -----END PGP MESSAGE----- ! '), '0123456789abcdefghij'), 'sha1'), 'hex'); ! encode ! ------------------------------------------ ! da39a3ee5e6b4b0d3255bfef95601890afd80709 ! (1 row) ! ! -- expected: da39a3ee5e6b4b0d3255bfef95601890afd80709 ! select encode(digest(pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: dat3.aes.sha1.mdc.s2k3.z0 ! ! jA0EBwMCxQvxJZ3G/HRg0lgBeYmTa7/uDAjPyFwSX4CYBgpZWVn/JS8JzILrcWF8 ! gFnkUKIE0PSaYFp+Yi1VlRfUtRQ/X/LYNGa7tWZS+4VQajz2Xtz4vUeAEiYFYPXk ! 73Hb8m1yRhQK ! =ivrD ! -----END PGP MESSAGE----- ! '), '0123456789abcdefghij'), 'sha1'), 'hex'); ! encode ! ------------------------------------------ ! 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c ! (1 row) ! ! -- expected: 5e5c135efc0dd00633efc6dfd6e731ea408a5b4c ! -- Checking CRLF ! select encode(digest(pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: crlf mess ! ! ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms ! a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs ! =mBP9 ! -----END PGP MESSAGE----- ! '), 'key', 'convert-crlf=0'), 'sha1'), 'hex'); ! encode ! ------------------------------------------ ! 9353062be7720f1446d30b9e75573a4833886784 ! (1 row) ! ! -- expected: 9353062be7720f1446d30b9e75573a4833886784 ! select encode(digest(pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! Comment: crlf mess ! ! ww0ECQMCt7VAtby6l4Bi0lgB5KMIZiiF/b3CfMfUyY0eDncsGXtkbu1X+l9brjpMP8eJnY79Amms ! a3nsOzKTXUfS9VyaXo8IrncM6n7fdaXpwba/3tNsAhJG4lDv1k4g9v8Ix2dfv6Rs ! =mBP9 ! -----END PGP MESSAGE----- ! '), 'key', 'convert-crlf=1'), 'sha1'), 'hex'); ! encode ! ------------------------------------------ ! 7efefcab38467f7484d6fa43dc86cf5281bd78e2 ! (1 row) ! ! -- expected: 7efefcab38467f7484d6fa43dc86cf5281bd78e2 ! -- check BUG #11905, problem with messages 6 less than a power of 2. ! select pgp_sym_decrypt(pgp_sym_encrypt(repeat('x',65530),'1'),'1') = repeat('x',65530); ! ?column? ! ---------- ! t ! (1 row) ! ! -- expected: true ! -- Negative tests ! -- Decryption with a certain incorrect key yields an apparent Literal Data ! -- packet reporting its content to be binary data. Ciphertext source: ! -- iterative pgp_sym_encrypt('secret', 'key') until the random prefix gave ! -- rise to that property. ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! ! ww0EBwMCxf8PTrQBmJdl0jcB6y2joE7GSLKRv7trbNsF5Z8ou5NISLUg31llVH/S0B2wl4bvzZjV ! VsxxqLSPzNLAeIspJk5G ! =mSd/ ! -----END PGP MESSAGE----- ! '), 'wrong-key', 'debug=1'); ! NOTICE: dbg: prefix_init: corrupt prefix ! NOTICE: dbg: parse_literal_data: data type=b ! NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr ! ERROR: Wrong key or corrupt data ! -- Routine text/binary mismatch. ! select pgp_sym_decrypt(pgp_sym_encrypt_bytea('P', 'key'), 'key', 'debug=1'); ! NOTICE: dbg: parse_literal_data: data type=b ! ERROR: Not text data ! -- Decryption with a certain incorrect key yields an apparent BZip2-compressed ! -- plaintext. Ciphertext source: iterative pgp_sym_encrypt('secret', 'key') ! -- until the random prefix gave rise to that property. ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! ! ww0EBwMC9rK/dMkF5Zlt0jcBlzAQ1mQY2qYbKYbw8h3EZ5Jk0K2IiY92R82TRhWzBIF/8cmXDPtP ! GXsd65oYJZp3Khz0qfyn ! =Nmpq ! -----END PGP MESSAGE----- ! '), 'wrong-key', 'debug=1'); ! NOTICE: dbg: prefix_init: corrupt prefix ! NOTICE: dbg: parse_compressed_data: bzip2 unsupported ! NOTICE: dbg: mdcbuf_finish: bad MDC pkt hdr ! ERROR: Wrong key or corrupt data ! -- Routine use of BZip2 compression. Ciphertext source: ! -- echo x | gpg --homedir /nonexistent --personal-compress-preferences bzip2 \ ! -- --personal-cipher-preferences aes --no-emit-version --batch \ ! -- --symmetric --passphrase key --armor ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! ! jA0EBwMCRhFrAKNcLVJg0mMBLJG1cCASNk/x/3dt1zJ+2eo7jHfjgg3N6wpB3XIe ! QCwkWJwlBG5pzbO5gu7xuPQN+TbPJ7aQ2sLx3bAHhtYb0i3vV9RO10Gw++yUyd4R ! UCAAw2JRIISttRHMfDpDuZJpvYo= ! =AZ9M ! -----END PGP MESSAGE----- ! '), 'key', 'debug=1'); ! NOTICE: dbg: parse_compressed_data: bzip2 unsupported ! ERROR: Unsupported compression algorithm --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-encrypt.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-encrypt.out 2016-03-15 16:28:48.611642073 +0300 *************** *** 1,210 **** ! -- ! -- PGP encrypt ! -- ! -- ensure consistent test output regardless of the default bytea format ! SET bytea_output TO escape; ! select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), 'key'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- check whether the defaults are ok ! select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), ! 'key', 'expect-cipher-algo=aes128, ! expect-disable-mdc=0, ! expect-sess-key=0, ! expect-s2k-mode=3, ! expect-s2k-digest-algo=sha1, ! expect-compress-algo=0 ! '); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- maybe the expect- stuff simply does not work ! select pgp_sym_decrypt(pgp_sym_encrypt('Secret.', 'key'), ! 'key', 'expect-cipher-algo=bf, ! expect-disable-mdc=1, ! expect-sess-key=1, ! expect-s2k-mode=0, ! expect-s2k-digest-algo=md5, ! expect-compress-algo=1 ! '); ! NOTICE: pgp_decrypt: unexpected cipher_algo: expected 4 got 7 ! NOTICE: pgp_decrypt: unexpected s2k_mode: expected 0 got 3 ! NOTICE: pgp_decrypt: unexpected s2k_digest_algo: expected 1 got 2 ! NOTICE: pgp_decrypt: unexpected use_sess_key: expected 1 got 0 ! NOTICE: pgp_decrypt: unexpected disable_mdc: expected 1 got 0 ! NOTICE: pgp_decrypt: unexpected compress_algo: expected 1 got 0 ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- bytea as text ! select pgp_sym_decrypt(pgp_sym_encrypt_bytea('Binary', 'baz'), 'baz'); ! ERROR: Not text data ! -- text as bytea ! select pgp_sym_decrypt_bytea(pgp_sym_encrypt('Text', 'baz'), 'baz'); ! pgp_sym_decrypt_bytea ! ----------------------- ! Text ! (1 row) ! ! -- algorithm change ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=bf'), ! 'key', 'expect-cipher-algo=bf'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes'), ! 'key', 'expect-cipher-algo=aes128'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'cipher-algo=aes192'), ! 'key', 'expect-cipher-algo=aes192'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- s2k change ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-mode=0'), ! 'key', 'expect-s2k-mode=0'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-mode=1'), ! 'key', 'expect-s2k-mode=1'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-mode=3'), ! 'key', 'expect-s2k-mode=3'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- s2k count change ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-count=1024'), ! 'key', 'expect-s2k-count=1024'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- s2k_count rounds up ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-count=65000000'), ! 'key', 'expect-s2k-count=65000000'); ! NOTICE: pgp_decrypt: unexpected s2k_count: expected 65000000 got 65011712 ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- s2k digest change ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=md5'), ! 'key', 'expect-s2k-digest-algo=md5'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 's2k-digest-algo=sha1'), ! 'key', 'expect-s2k-digest-algo=sha1'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- sess key ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'sess-key=0'), ! 'key', 'expect-sess-key=0'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'sess-key=1'), ! 'key', 'expect-sess-key=1'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=bf'), ! 'key', 'expect-sess-key=1, expect-cipher-algo=bf'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes192'), ! 'key', 'expect-sess-key=1, expect-cipher-algo=aes192'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'sess-key=1, cipher-algo=aes256'), ! 'key', 'expect-sess-key=1, expect-cipher-algo=aes256'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- no mdc ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret.', 'key', 'disable-mdc=1'), ! 'key', 'expect-disable-mdc=1'); ! pgp_sym_decrypt ! ----------------- ! Secret. ! (1 row) ! ! -- crlf ! select encode(pgp_sym_decrypt_bytea( ! pgp_sym_encrypt(E'1\n2\n3\r\n', 'key', 'convert-crlf=1'), ! 'key'), 'hex'); ! encode ! ---------------------- ! 310d0a320d0a330d0d0a ! (1 row) ! ! -- conversion should be lossless ! select encode(digest(pgp_sym_decrypt( ! pgp_sym_encrypt(E'\r\n0\n1\r\r\n\n2\r', 'key', 'convert-crlf=1'), ! 'key', 'convert-crlf=1'), 'sha1'), 'hex') as result, ! encode(digest(E'\r\n0\n1\r\r\n\n2\r', 'sha1'), 'hex') as expect; ! result | expect ! ------------------------------------------+------------------------------------------ ! 47bde5d88d6ef8770572b9cbb4278b402aa69966 | 47bde5d88d6ef8770572b9cbb4278b402aa69966 ! (1 row) ! --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-compression.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-compression.out 2016-03-15 16:28:48.615642110 +0300 *************** *** 1,50 **** ! -- ! -- PGP compression support ! -- ! select pgp_sym_decrypt(dearmor(' ! -----BEGIN PGP MESSAGE----- ! ! ww0ECQMCsci6AdHnELlh0kQB4jFcVwHMJg0Bulop7m3Mi36s15TAhBo0AnzIrRFrdLVCkKohsS6+ ! DMcmR53SXfLoDJOv/M8uKj3QSq7oWNIp95pxfA== ! =tbSn ! -----END PGP MESSAGE----- ! '), 'key', 'expect-compress-algo=1'); ! pgp_sym_decrypt ! ----------------- ! Secret message ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret message', 'key', 'compress-algo=0'), ! 'key', 'expect-compress-algo=0'); ! pgp_sym_decrypt ! ----------------- ! Secret message ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret message', 'key', 'compress-algo=1'), ! 'key', 'expect-compress-algo=1'); ! pgp_sym_decrypt ! ----------------- ! Secret message ! (1 row) ! ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret message', 'key', 'compress-algo=2'), ! 'key', 'expect-compress-algo=2'); ! pgp_sym_decrypt ! ----------------- ! Secret message ! (1 row) ! ! -- level=0 should turn compression off ! select pgp_sym_decrypt( ! pgp_sym_encrypt('Secret message', 'key', ! 'compress-algo=2, compress-level=0'), ! 'key', 'expect-compress-algo=0'); ! pgp_sym_decrypt ! ----------------- ! Secret message ! (1 row) ! --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-pubkey-decrypt.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-pubkey-decrypt.out 2016-03-15 16:28:48.619642147 +0300 *************** *** 1,656 **** ! -- ! -- PGP Public Key Encryption ! -- ! -- As most of the low-level stuff is tested in symmetric key ! -- tests, here's only public-key specific tests ! create table keytbl ( ! id int4, ! name text, ! pubkey text, ! seckey text ! ); ! create table encdata ( ! id int4, ! data text ! ); ! insert into keytbl (id, name, pubkey, seckey) ! values (1, 'elg1024', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9 ! tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE ! xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth ! klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5 ! YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic ! PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL ! jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv ! saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v ! IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx ! MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV ! AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc ! AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd ! ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P ! sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI ! +h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9 ! 6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF ! k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v ! iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F ! ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80 ! =RWci ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQG7BELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9 ! tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE ! xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth ! klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5 ! YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic ! PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL ! jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv ! saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v ! IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQAAAnj4i4st+s+C6 ! WKTIDcL1Iy0Saq8lCp60H0VsZ2FtYWwgMTAyNCA8dGVzdEBleGFtcGxlLm9yZz6I ! XgQTEQIAHgUCQsghSAIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRAcKbwNGBdz ! ZDrbAJ9cp6AsjOhiLxwznsMJheGf4xkH8wCfUPjMCLm4tAEnyYn2hDNt7CB8B6Kd ! ATEEQsghShAEAIeUjW2yTALCfrEG3FhM3ZLvAHWAec2O0Mn/RDr59IN/W8wDYcZp ! m+oG0ZUDdIqMppQ8K2kylAH7gmYDXIP9D7MRRm/Zw3L4yFfKnVaZ6tT7szBbgW5h ! iOsHoOz49NXZT4jtMLdZS1/krm5Lam2MSPod9XN0Q2asY/igIMUfGDRjAAMGA/sE ! LNh3tWefqeDkoDBEYjcxdGnGVGJnNHvv/eoHy9H7dyD/kkhaOoRAa5ClYWSqD0kk ! a+SqTWhKG4XcbJyo1GsP6sqGhXDTM2+LBZPMKuVJQpEfoe9ruob/BbpXglfEiVE9 ! VNiY7ZVyUdj3svYn4fK2X7ue1G3cHR2tL4lnOA4pYQAA9030E4u2ZKOfJBpUM+EM ! m9VmsGjaQZV4teB0R/q3W8sRIYhJBBgRAgAJBQJCyCFKAhsMAAoJEBwpvA0YF3Nk ! 7a8AniFFotw1x2X+oryu3Q3nNtmxoKHpAJ9HU7jw7ydg33dI9J8gVkrmsSZ2/w== ! =nvqq ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (2, 'elg2048', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQGiBELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n ! vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke ! 5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO ! RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij ! 8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl ! Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt ! J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/ ! T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5 ! 0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6a7QjRWxnYW1hbCAy ! MDQ4IDx0ZXN0MjA0OEBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgiCgIbAwYLCQgH ! AwIDFQIDAxYCAQIeAQIXgAAKCRBI6c1W/qZo29PDAKCG724enIxRog1j+aeCp/uq ! or6mbwCePuKy2/1kD1FvnhkZ/R5fpm+pdm25Ag0EQsgiIhAIAJI3Gb2Ehtz1taQ9 ! AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMX ! MhoWyw8ZF5Zs1mLIjFGVorePrm94N3MNPWM7x9M36bHUjx0vCZKFIhcGY1g+htE/ ! QweaJzNVeA5z4qZmik41FbQyQSyHa3bOkTZu++/U6ghP+iDp5UDBjMTkVyqITUVN ! gC+MR+da/I60irBVhue7younh4ovF+CrVDQJC06HZl6CAJJyA81SmRfi+dmKbbjZ ! LF6rhz0norPjISJvkIqvdtM4VPBKI5wpgwCzpEqjuiKrAVujRT68zvBvJ4aVqb11 ! k5QdJscAAwUH/jVJh0HbWAoiFTe+NvohfrA8vPcD0rtU3Y+siiqrabotnxJd2NuC ! bxghJYGfNtnx0KDjFbCRKJVeTFok4UnuVYhXdH/c6i0/rCTNdeW2D6pmR4GfBozR ! Pw/ARf+jONawGLyUj7uq13iquwMSE7VyNuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0R ! QsetMq/iNBWraayKZnWUd+eQqNzE+NUo7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiF ! Z1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qunfGW00ZMMTCWabg0ZgxPzMfMeIcm6525A ! Yn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/RdWaISQQYEQIACQUCQsgiIgIbDAAKCRBI ! 6c1W/qZo25ZSAJ98WTrtl2HiX8ZqZq95v1+9cHtZPQCfZDoWQPybkNescLmXC7q5 ! 1kNTmEU= ! =8QM5 ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQG7BELIIgoRBAC1onBpxKYgDvrgCaUWPY34947X3ogxGOfCN0p6Eqrx+2PUhm4n ! vFvmczpMT4iDc0mUO+iwnwsEkXQI1eC99g8c0jnZAvzJZ5miAHL8hukMAMfDkYke ! 5aVvcPPc8uPDlItpszGmH0rM0V9TIt/i9QEXetpyNWhk4jj5qnohYhLeZwCgkOdO ! RFAdNi4vfFPivvtAp2ffjU8D/R3x/UJCvkzi7i9rQHGo313xxmQu5BuqIjANBUij ! 8IE7LRPI/Qhg2hYy3sTJwImDi7VkS+fuvNVk0d6MTWplAXYU96bn12JaD21R9sKl ! Fzcc+0iZI1wYA1PczisUkoTISE+dQFUsoGHfpDLhoBuesXQrhBavI8t8VPd+nkdt ! J+oKA/9iRQ87FzxdYTkh2drrv69FZHc3Frsjw9nPcBq/voAvXH0MRilqyCg7HpW/ ! T9naeOERksa+Rj4R57IF1l4e5oiiGJo9QmaKZcsCsXrREJCycrlEtMqXfSPy+bi5 ! 0yDZE/Qm1dwu13+OXOsRvkoNYjO8Mzo9K8wU12hMqN0a2bu6awAAn2F+iNBElfJS ! 8azqO/kEiIfpqu6/DQG0I0VsZ2FtYWwgMjA0OCA8dGVzdDIwNDhAZXhhbXBsZS5v ! cmc+iF0EExECAB4FAkLIIgoCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQSOnN ! Vv6maNvTwwCYkpcJmpl3aHCQdGomz7dFohDgjgCgiThZt2xTEi6GhBB1vuhk+f55 ! n3+dAj0EQsgiIhAIAJI3Gb2Ehtz1taQ9AhPY4Avad2BsqD3S5X/R11Cm0KBE/04D ! 29dxn3f8QfxDsexYvNIZjoJPBqqZ7iMXMhoWyw8ZF5Zs1mLIjFGVorePrm94N3MN ! PWM7x9M36bHUjx0vCZKFIhcGY1g+htE/QweaJzNVeA5z4qZmik41FbQyQSyHa3bO ! kTZu++/U6ghP+iDp5UDBjMTkVyqITUVNgC+MR+da/I60irBVhue7younh4ovF+Cr ! VDQJC06HZl6CAJJyA81SmRfi+dmKbbjZLF6rhz0norPjISJvkIqvdtM4VPBKI5wp ! gwCzpEqjuiKrAVujRT68zvBvJ4aVqb11k5QdJscAAwUH/jVJh0HbWAoiFTe+Nvoh ! frA8vPcD0rtU3Y+siiqrabotnxJd2NuCbxghJYGfNtnx0KDjFbCRKJVeTFok4Unu ! VYhXdH/c6i0/rCTNdeW2D6pmR4GfBozRPw/ARf+jONawGLyUj7uq13iquwMSE7Vy ! NuF3ycL2OxXjgOWMjkH8c+zfHHpjaZ0RQsetMq/iNBWraayKZnWUd+eQqNzE+NUo ! 7w1jAu7oDpy+8a1eipxzK+O0HfU5LTiFZ1Oe4Um0P2l3Xtx8nEgj4vSeoEkl2qun ! fGW00ZMMTCWabg0ZgxPzMfMeIcm6525AYn2qL+X/qBJTInAl7/hgPz2D1Yd7d5/R ! dWYAAVQKFPXbRaxbdArwRVXMzSD3qj/+VwwhwEDt8zmBGnlBfwVdkjQQrDUMmV1S ! EwyISQQYEQIACQUCQsgiIgIbDAAKCRBI6c1W/qZo25ZSAJ4sgUfHTVsG/x3p3fcM ! 3b5R86qKEACggYKSwPWCs0YVRHOWqZY0pnHtLH8= ! =3Dgk ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (3, 'elg4096', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQGiBELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY ! 05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz ! 2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98 ! cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN ! SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4 ! 18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG ! 7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt ! q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh ! uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk27QjRWxnYW1hbCA0 ! MDk2IDx0ZXN0NDA5NkBleGFtcGxlLm9yZz6IXgQTEQIAHgUCQsgjvAIbAwYLCQgH ! AwIDFQIDAxYCAQIeAQIXgAAKCRBj+HX2P2d0oAEDAJ9lI+CNmb42z3+a6TnVusM6 ! FI7oLwCfUwA1zEcRdsT3nIkoYh0iKxFSDFW5BA0EQsgkdhAQAJQbLXlgcJ/jq+Xh ! Eujb77/eeftFJObNIRYD9fmJ7HFIXbUcknEpbs+cRH/nrj5dGSY3OT3jCXOUtvec ! sCoX/CpZWL0oqDjAiZtNSFiulw5Gav4gHYkWKgKdSo+2rkavEPqKIVHvMeXaJtGT ! d7v/AmL/P8T7gls93o5WFBOLtPbDvWqaKRy2U5TAhl1laiM0vGALRVjvSCgnGw9g ! FpSnXbO3AfenUSjDzZujfGLHtU44ixHSS/D4DepiF3YaYLsN4CBqZRv6FbMZD5W3 ! DnJY4kS1kH0MzdcF19TlcZ3itTCcGIt1tMKf84mccPoqdMzH7vumBGTeFEly5Afp ! 9berJcirqh2fzlunN0GS02z6SGWnjTbDlkNDxuxPSBbpcpNyD3jpYAUqSwRsZ/+5 ! zkzcbGtDmvy9sJ5lAXkxGoIoQ1tEVX/LOHnh2NQHK8ourVOnr7MS0nozssITZJ5E ! XqtHiREjiYEuPyZiVZKJHLWuYYaF+n40znnz3sJuXFRreHhHbbvRdlYUU5mJV+XZ ! BLgKuS33NdpGeMIngnCc/9IQ6OZb6ixc94kbkd3w2PVr8CbKlu/IHTjWOO2mAo+D ! +OydlYl23FiM3KOyMP1HcEOJMB/nwkMtrvd+522Lu9n77ktKfot9IPrQDIQTyXjR ! 3pCOFtCOBnk2tJHMPoG9jn9ah/LHAAMHEACDZ5I/MHGfmiKg2hrmqBu2J2j/deC8 ! CpwcyDH1ovQ0gHvb9ESa+CVRU2Wdy2CD7Q9SmtMverB5eneL418iPVRcQdwRmQ2y ! IH4udlBa6ce9HTUCaecAZ4/tYBnaC0Av/9l9tz14eYcwRMDpB+bnkhgF+PZ1KAfD ! 9wcY2aHbtsf3lZBc5h4owPJkxpe/BNzuJxW3q4VpSbLsZhwnCZ2wg7DRwP44wFIk ! 00ptmoBY59gsU6I40XtzrF8JDr0cA57xND5RY21Z8lnnYRE1Tc8h5REps9ZIxW3/ ! yl91404bPLqxczpUHQAMSTAmBaStPYX1nS51uofOhLs5SKPCUmxfGKIOhsD0oLUn ! 78DnkONVGeXzBibSwwtbgfMzee4G8wSUfJ7w8WXz1TyanaGLnJ+DuKASSOrFoBCD ! HEDuWZWgSL74NOQupFRk0gxOPmqU94Y8HziQWma/cETbmD83q8rxN+GM2oBxQkQG ! xcbqMTHE7aVhV3tymbSWVaYhww3oIwsZS9oUIi1DnPEowS6CpVRrwdvLjLJnJzzV ! O3AFPn9eZ1Q7R1tNx+zZ4OOfhvI/OlRJ3HBx2L53embkbdY9gFYCCdTjPyjKoDIx ! kALgCajjCYMNUsAKNSd6mMCQ8TtvukSzkZS1RGKP27ohsdnzIVsiEAbxDMMcI4k1 ! ul0LExUTCXSjeIhJBBgRAgAJBQJCyCR2AhsMAAoJEGP4dfY/Z3Sg19sAn0NDS8pb ! qrMpQAxSb7zRTmcXEFd9AJ435H0ttP/NhLHXC9ezgbCMmpXMOQ== ! =kRxT ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQG7BELII7wRBACFuaAvb11cIvjJK9LkZr4cYuYhLWh3DJdojNNnLNiym5OEksvY ! 05cw8OgqKtPzICU7o/mHXTWhzJYUt3i50/AeYygI8Q0uATS6RnDAKNlES1EMoHKz ! 2a5iFbYs4bm4IwlkvYd8uWjcu+U0YLbxir39u+anIc6eT+q3WiH/q3zDRwCgkT98 ! cnIG8iO8PdwDSP8G4Lt6TYED/R45GvCzJ4onQALLE92KkLUz8aFWSl05r84kczEN ! SxiP9Ss6m465RmwWHfwYAu4b+c4GeNyU8fIU2EM8cezchC+edEi3xu1s+pCV0Dk4 ! 18DGC8WKCICO30vBynuNmYg7W/7Zd4wtjss454fMW7+idVDNM701mmXBtI1nsBtG ! 7Z4tA/9FxjFbJK9jh24RewfjHpLYqcfCo2SsUjOwsnMZ5yg2yv9KyVVQhRqwmrqt ! q8MRyjGmfoD9PPdCgvqgzy0hHvAHUtTm2zUczGTG+0g4hNIklxC/Mv6J4KE+NWTh ! uB4acqofHyaw2WnKOuRUsoDi6rG5AyjNMyAK/vVcEGj7J1tk2wAAoJCUNy6awTkw ! XfbLbpqh0fvDst7jDLa0I0VsZ2FtYWwgNDA5NiA8dGVzdDQwOTZAZXhhbXBsZS5v ! cmc+iF4EExECAB4FAkLII7wCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQY/h1 ! 9j9ndKABAwCeNEOVK87EzXYbtxYBsnjrUI948NIAn2+f3BXiBFDV5NvqPwIZ0m77 ! Fwy4nQRMBELIJHYQEACUGy15YHCf46vl4RLo2++/3nn7RSTmzSEWA/X5iexxSF21 ! HJJxKW7PnER/564+XRkmNzk94wlzlLb3nLAqF/wqWVi9KKg4wImbTUhYrpcORmr+ ! IB2JFioCnUqPtq5GrxD6iiFR7zHl2ibRk3e7/wJi/z/E+4JbPd6OVhQTi7T2w71q ! mikctlOUwIZdZWojNLxgC0VY70goJxsPYBaUp12ztwH3p1Eow82bo3xix7VOOIsR ! 0kvw+A3qYhd2GmC7DeAgamUb+hWzGQ+Vtw5yWOJEtZB9DM3XBdfU5XGd4rUwnBiL ! dbTCn/OJnHD6KnTMx+77pgRk3hRJcuQH6fW3qyXIq6odn85bpzdBktNs+khlp402 ! w5ZDQ8bsT0gW6XKTcg946WAFKksEbGf/uc5M3GxrQ5r8vbCeZQF5MRqCKENbRFV/ ! yzh54djUByvKLq1Tp6+zEtJ6M7LCE2SeRF6rR4kRI4mBLj8mYlWSiRy1rmGGhfp+ ! NM55897CblxUa3h4R2270XZWFFOZiVfl2QS4Crkt9zXaRnjCJ4JwnP/SEOjmW+os ! XPeJG5Hd8Nj1a/AmypbvyB041jjtpgKPg/jsnZWJdtxYjNyjsjD9R3BDiTAf58JD ! La73fudti7vZ++5LSn6LfSD60AyEE8l40d6QjhbQjgZ5NrSRzD6BvY5/WofyxwAD ! BxAAg2eSPzBxn5oioNoa5qgbtido/3XgvAqcHMgx9aL0NIB72/REmvglUVNlnctg ! g+0PUprTL3qweXp3i+NfIj1UXEHcEZkNsiB+LnZQWunHvR01AmnnAGeP7WAZ2gtA ! L//Zfbc9eHmHMETA6Qfm55IYBfj2dSgHw/cHGNmh27bH95WQXOYeKMDyZMaXvwTc ! 7icVt6uFaUmy7GYcJwmdsIOw0cD+OMBSJNNKbZqAWOfYLFOiONF7c6xfCQ69HAOe ! 8TQ+UWNtWfJZ52ERNU3PIeURKbPWSMVt/8pfdeNOGzy6sXM6VB0ADEkwJgWkrT2F ! 9Z0udbqHzoS7OUijwlJsXxiiDobA9KC1J+/A55DjVRnl8wYm0sMLW4HzM3nuBvME ! lHye8PFl89U8mp2hi5yfg7igEkjqxaAQgxxA7lmVoEi++DTkLqRUZNIMTj5qlPeG ! PB84kFpmv3BE25g/N6vK8TfhjNqAcUJEBsXG6jExxO2lYVd7cpm0llWmIcMN6CML ! GUvaFCItQ5zxKMEugqVUa8Hby4yyZyc81TtwBT5/XmdUO0dbTcfs2eDjn4byPzpU ! Sdxwcdi+d3pm5G3WPYBWAgnU4z8oyqAyMZAC4Amo4wmDDVLACjUnepjAkPE7b7pE ! s5GUtURij9u6IbHZ8yFbIhAG8QzDHCOJNbpdCxMVEwl0o3gAAckBdfKuasiNUn5G ! L5XRnSvaOFzftr8zteOlZChCSNvzH5k+i1j7RJbWq06OeKRywPzjfjgM2MvRzI43 ! ICeISQQYEQIACQUCQsgkdgIbDAAKCRBj+HX2P2d0oNfbAJ9+G3SeXrk+dWwo9EGi ! hqMi2GVTsgCfeoQJPsc8FLYUgfymc/3xqAVLUtg= ! =Gjq6 ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (4, 'rsa2048', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQELBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP ! ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2 ! 55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx ! 5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K ! MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz ! R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYptB5SU0EgMjA0OCA8cnNhMjA0 ! OEBleGFtcGxlLm9yZz6JATQEEwECAB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgEC ! HgECF4AACgkQnc+OnJvTHyQqHwf8DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liR ! nrLuVlLBpdO6CWmMUzfKRvyZlx54GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzw ! bLZyM5Gb3lsE/FEmE7Dxw/0Utf59uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDP ! D3dnU4uzKPhMcjnSN00pzjusP7C9NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv ! 9bgGWopumlOkt8Zu5YG6+CtTbJXprPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhv ! S3NZKoJ/1DrGgoDAu1mGkM4KvLAxfDs/qQ9dZhtEmDbKPLTVEA== ! =lR4n ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQOWBELIJbEBCADAIdtcoLAmQfl8pb73pPRuEYx8qW9klLfCGG5A4OUOi00JHNwP ! ZaABe1PGzjoeXrgM1MTQZhoZu1Vdg+KDI6XAtiy9P6bLg7ntsXksD4wBoIKtQKc2 ! 55pdukxTiu+xeJJG2q8ZZPOp97CV9fbQ9vPCwgnuSsDCoQlibZikDVPAyVTvp7Jx ! 5rz8yXsl4sxvaeMZPqqFPtA/ENeQ3cpsyR1BQXSvoZpH1Fq0b8GcZTEdWWD/w6/K ! MCRC8TmgEd+z3e8kIsCwFQ+TSHbCcxRWdgZE7gE31sJHHVkrZlXtLU8MPXWqslVz ! R0cX+yC8j6bXI6/BqZ2SvRndJwuunRAr4um7AAYpAAf/QZsrrz0c7dgWwGqMIpw6 ! fP+/lLa74+fa2CFRWtYowEiKsfDg/wN7Ua07036dNhPa8aZPsU6SRzm5PybKOURe ! D9pNt0FxJkX0j5pCWfjSJgTbc1rCdqZ/oyBk/U6pQtf//zfw3PbDl7I8TC6GOt2w ! 5NgcXdsWHP7LAmPctOVUyzFsenevR0MFTHkMbmKI1HpFm8XN/e1Fl+qIAD+OagTF ! 5B32VvpoJtkh5nxnIuToNJsa9Iy7F9MM2CeFOyTMihMcjXKBBUaAYoF115irBvqu ! 7N/qWmzqLg8yxBZ56mh6meCF3+67VA2y7fL8rhw2QuqgLg1JFlKAVL+9crCSrn// ! GQQA1kT7FytW6BNOffblFYZkrJer3icoRDqa/ljgH/yVaWoVT1igy0E9XzYO7MwP ! 2usj/resLy0NC1qCthk51cZ/wthooMl88e5Wb4l5FYwBEac7muSBTo4W8cAH1hFj ! TWL6XAGvEzGX3Mt9pn8uYGlQLZAhJoNCAU2EOCbN1PchDvsEAOWNKYesuUVk8+sQ ! St0NDNhd9BWtTWTHkCZb1dKC3JTfr9PqkTBLrWFbYjkOtvdPAW7FDaXXXZfdH1jH ! WfwP3Q+I6sqgSaWpCS4dBAns3/RVtO7czVgyIwma04iIvJqderYrfvkUq95KfwP2 ! V8wXkhrPPPxyrg5y3wQlpY2jb5RBBAC17SK1ms+DBtck4vpdjp3SJ32SbyC/DU30 ! 89Q12j74S7Zdu1qZlKnvy3kWPYX/hMuSzGZ+mLVJNFEqH2X01aFzppYz0hdI9PGB ! 9tTFEqZWQL9ZkXfjc79Cgnt12pNukRbtw0N/kyutOdIFHVT79wVAd+powqziXJsC ! Kc+4xjwSCkZitB5SU0EgMjA0OCA8cnNhMjA0OEBleGFtcGxlLm9yZz6JATQEEwEC ! AB4FAkLIJbECGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQnc+OnJvTHyQqHwf8 ! DtzuAGmObfe3ggtn14x2wnU1Nigebe1K5liRnrLuVlLBpdO6CWmMUzfKRvyZlx54 ! GlA9uUQSjW+RlgejdOTQqesDrcTEukYd4yzwbLZyM5Gb3lsE/FEmE7Dxw/0Utf59 ! uACqzG8LACQn9J6sEgZWKxAupuYTHXd12lDPD3dnU4uzKPhMcjnSN00pzjusP7C9 ! NZd3OLkAx2vw/dmb4Q+/QxeZhVYYsAUuR2hv9bgGWopumlOkt8Zu5YG6+CtTbJXp ! rPI7pJ1jHbeE+q/29hWJQtS8Abx82AcOkzhvS3NZKoJ/1DrGgoDAu1mGkM4KvLAx ! fDs/qQ9dZhtEmDbKPLTVEA== ! =WKAv ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (5, 'psw-elg1024', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQGiBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9 ! tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE ! xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth ! klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5 ! YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic ! PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL ! jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv ! saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v ! IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQLQfRWxnYW1hbCAx ! MDI0IDx0ZXN0QGV4YW1wbGUub3JnPoheBBMRAgAeBQJCyCFIAhsDBgsJCAcDAgMV ! AgMDFgIBAh4BAheAAAoJEBwpvA0YF3NkOtsAniI9W2bC3CxARTpYrev7ihreDzFc ! AJ9WYLQxDQAi5Ec9AQoodPkIagzZ4LkBDQRCyCFKEAQAh5SNbbJMAsJ+sQbcWEzd ! ku8AdYB5zY7Qyf9EOvn0g39bzANhxmmb6gbRlQN0ioymlDwraTKUAfuCZgNcg/0P ! sxFGb9nDcvjIV8qdVpnq1PuzMFuBbmGI6weg7Pj01dlPiO0wt1lLX+SubktqbYxI ! +h31c3RDZqxj+KAgxR8YNGMAAwYD+wQs2He1Z5+p4OSgMERiNzF0acZUYmc0e+/9 ! 6gfL0ft3IP+SSFo6hEBrkKVhZKoPSSRr5KpNaEobhdxsnKjUaw/qyoaFcNMzb4sF ! k8wq5UlCkR+h72u6hv8FuleCV8SJUT1U2JjtlXJR2Pey9ifh8rZfu57UbdwdHa0v ! iWc4DilhiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCfdPom+HlNVE9F ! ig3hGY1Rb4NEk1gAn1u9IuQB+BgDP40YHHz6bKWS/x80 ! =RWci ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQHpBELIIUgRBACp401L6jXrLB28c3YA4sM3OJKnxM1GT9YTkWyE3Vyte65H8WU9 ! tGPBX7OMuaX5eGZ84LFUGvaP0k7anfmXcDkCO3P9GgL+ro/dS2Ps/vChQPZqHaxE ! xpKDUt47B7DGdRJrC8DRnIR4wbSyQA6ma3S1yFqC5pJhSs+mqf9eExOjiwCgntth ! klRxIYw352ZX9Ov9oht/p/ED/1Xi4PS+tkXVvyIw5aZfa61bT6XvDkoPI0Aj3GE5 ! YmCHJlKA/IhEr8QJOLV++5VEv4l6KQ1/DFoJzoNdr1AGJukgTc6X/WcQRzfQtUic ! PHQme5oAWoHa6bVQZOwvbJh3mOXDq/Tk/KF22go8maM44vMn4bvv+SBbslviYLiL ! jZJ1A/9JXF1esNq+X9HehJyqHHU7LEEf/ck6zC7o2erM3/LZlZuLNPD2cv3oL3Nv ! saEgcTSZl+8XmO8pLmzjKIb+hi70qVx3t2IhMqbb4B/dMY1Ck62gPBKa81/Wwi7v ! IsEBQLEtyBmGmI64YpzoRNFeaaF9JY+sAKqROqe6dLjJ7vebQP4HAwImKZ5q2QwT ! D2DDAY/IQBjes7WgqZeacfLPDoB8ecD/KLoSCH6Z3etvbPHSOKiazxoJ962Ix74H ! ZAE6ZbMTtl5dZW1ptB9FbGdhbWFsIDEwMjQgPHRlc3RAZXhhbXBsZS5vcmc+iF4E ! ExECAB4FAkLIIUgCGwMGCwkIBwMCAxUCAwMWAgECHgECF4AACgkQHCm8DRgXc2Q6 ! 2wCfXKegLIzoYi8cM57DCYXhn+MZB/MAn1D4zAi5uLQBJ8mJ9oQzbewgfAeinQFf ! BELIIUoQBACHlI1tskwCwn6xBtxYTN2S7wB1gHnNjtDJ/0Q6+fSDf1vMA2HGaZvq ! BtGVA3SKjKaUPCtpMpQB+4JmA1yD/Q+zEUZv2cNy+MhXyp1WmerU+7MwW4FuYYjr ! B6Ds+PTV2U+I7TC3WUtf5K5uS2ptjEj6HfVzdENmrGP4oCDFHxg0YwADBgP7BCzY ! d7Vnn6ng5KAwRGI3MXRpxlRiZzR77/3qB8vR+3cg/5JIWjqEQGuQpWFkqg9JJGvk ! qk1oShuF3GycqNRrD+rKhoVw0zNviwWTzCrlSUKRH6Hva7qG/wW6V4JXxIlRPVTY ! mO2VclHY97L2J+Hytl+7ntRt3B0drS+JZzgOKWH+BwMCJimeatkMEw9gRkFjt4Xa ! 9rX8awMBE5+vVcGKv/DNiCvJnlYvSdCj8VfuHsYFliiJo6u17NJon+K43e3yvDNk ! f631VOVanGEz7TyqOkWQiEkEGBECAAkFAkLIIUoCGwwACgkQHCm8DRgXc2TtrwCe ! IUWi3DXHZf6ivK7dDec22bGgoekAn0dTuPDvJ2Dfd0j0nyBWSuaxJnb/ ! =SNvr ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (6, 'rsaenc2048', ' ! -----BEGIN PGP PUBLIC KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! mQELBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj ! UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW ! czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT ! 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ ! dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4 ! NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYptCVSU0EgMjA0OCBFbmMgPHJz ! YTIwNDhlbmNAZXhhbXBsZS5vcmc+iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMV ! AgMDFgIBAh4BAheAAAoJEMiZ6pNEGVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8 ! JCaxHa31wH3PKqGtq2M+cpb2rXf7gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw ! +IkhihEb5bWxQBNj+3zAFs1YX6v2HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzku ! UOhcgfpBgIt3Q+MpT6M2+OIF7lVfSb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQ ! RJ6DWH61F8fFIDJg1z+A/Obx4fqX6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO8 ! 0g/oVYBbuvOYedffDBeQarhERZ5W2TnIE+nqY61YOLBqosliygdZTXULzNi5AQsE ! QuvaugEIAOuCJZdkzORA6e1lr81Lnr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPX ! z1YIrMTu+1rMIiy10IWbA6zgMTpzPhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfK ! lAXIxJurCHXTbEa+YvPdn76vJ3HsXOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zE ! FZcAoKbFqAAjDLEai64SoOFh0W3CsD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9U ! rHlolqYNhYze/uRLyfnUx9PN4r/GhEzauyDMV0smo91uB3aewPft+eCpmeWnu0PF ! JVK4xyRmhIq2rVCw16a1pBJirvGM+y0ABimJAR8EGAECAAkFAkLr2roCGwwACgkQ ! yJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+1iqYE0B0 ! WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwarANhHxkWg ! w/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx2eVM1k+X ! dmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOyla+wJdro ! PYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CChbt6LhKh ! CLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug== ! =pwU2 ! -----END PGP PUBLIC KEY BLOCK----- ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! lQOWBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj ! UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW ! czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT ! 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ ! dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4 ! NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYpAAf9GuKpxrXp267eSPw9ZeSw ! Ik6ob1I0MHbhhHeaXQnF0SuOViJ1+Bs74hUB3/F5fqrnjVLIS/ysYzegYpbpXOIa ! MZwYcp2e+dpmVb7tkGQgzXH0igGtBQBqoSUVq9mG2XKPVh2JmiYgOH6GrHSGmnCq ! GCgEK4ezSomB/3OtPFSjAxOlSw6dXSkapSxW3pEGvCdaWd9p8yl4rSpGsZEErPPL ! uSbZZrHtWfgq5UXdPeE1UnMlBcvSruvpN4qgWMgSMs4d2lXvzXJLcht/nryP+atT ! H1gwnRmlDCVv5BeJepKo3ORJDvcPlXkJPhqS9If3BhTqt6QgQEFI4aIYYZOZpZoi ! 2QQA2Zckzktmsc1MS04zS9gm1CbxM9d2KK8EOlh7fycRQhYYqqavhTBH2MgEp+Dd ! ZtuEN5saNDe9x/fwi2ok1Bq6luGMWPZU/nZe7fxadzwfliy/qPzStWFW3vY9mMLu ! 6uEqgjin/lf4YrAswXDZaEc5e4GuNgGfwr27hpjxE1jg3PsEAPMqXEOMT2yh+yRu ! DlLRbFhYOI4aUHY2CGoQQONnwv2O5gFvmOcPlg3J5lvnwlOYCx0c3bDxAtHyjPJq ! FAZqcJBaB9RDhKHwlWDrbx/6FPH2SuKE+u4msIhPFin4V3FAP+yTem/TKrdnaWy6 ! EUrhCWTXVRTijBaCudfjFd/ipHZbA/0dv7UAcoWK6kiVLzyE+jOvtN+ZxTzxq7CW ! mlFPgAC966hgJmz9IXqadtMgPAoL3PK9q1DbPM3JhsQcJrNzTJqZrdN1/kPU0HHa ! +aof1BVy3wSvp2mXgaRUULStyhUIyBRM6hAYp3/MoWEYn/bwr+zQkIU8Zsk6OsZ6 ! q1xE3cowrUWFtCVSU0EgMjA0OCBFbmMgPHJzYTIwNDhlbmNAZXhhbXBsZS5vcmc+ ! iQE0BBMBAgAeBQJC69ptAhsDBgsJCAcDAgMVAgMDFgIBAh4BAheAAAoJEMiZ6pNE ! GVVZHMkIAJtGHHZ9iM8Yq1rr0zl1L6SvlQP8JCaxHa31wH3PKqGtq2M+cpb2rXf7 ! gAY/doHJPXggfVzkyFrysmQ1gPbDGYLyOutw+IkhihEb5bWxQBNj+3zAFs1YX6v2 ! HXWbSUSmyY1V9/+NTtKk03olDc/swd3lXzkuUOhcgfpBgIt3Q+MpT6M2+OIF7lVf ! Sb1rWdpwTfGhZzW9szQOeoS4gPvxCCRyuabQRJ6DWH61F8fFIDJg1z+A/Obx4fqX ! 6GOA69RzgZ3oukFBIXxNwV9PZNnAmHtZVYO80g/oVYBbuvOYedffDBeQarhERZ5W ! 2TnIE+nqY61YOLBqosliygdZTXULzNidA5YEQuvaugEIAOuCJZdkzORA6e1lr81L ! nr4JzMsVBFA+X/yIkBbV6qX/A4nVSLAZKNPXz1YIrMTu+1rMIiy10IWbA6zgMTpz ! PhJRfgePONgdnCYyK5Ksh5/C5ntzKwwGwxfKlAXIxJurCHXTbEa+YvPdn76vJ3Hs ! XOXVEL+fLb4U3l3Ng87YM202Lh1Ha2MeS2zEFZcAoKbFqAAjDLEai64SoOFh0W3C ! sD1DL4zmfp+YZrUPHTtZadsi53i4KKW/ws9UrHlolqYNhYze/uRLyfnUx9PN4r/G ! hEzauyDMV0smo91uB3aewPft+eCpmeWnu0PFJVK4xyRmhIq2rVCw16a1pBJirvGM ! +y0ABikAB/oC3z7lv6sVg+ngjbpWy9lZu2/ECZ9FqViVz7bUkjfvSuowgpncryLW ! 4EpVV4U6mMSgU6kAi5VGT/BvYGSAtnqDWGiPs7Kk+h4Adz74bEAXzU280pNBtSfX ! tGvzlS4a376KzYFSCJDRBdMebEhJMbY0wQmR8lTZu5JSUI4YYEuN0c7ckdsw8w42 ! QWTLonG8HC6h8UPKS0EAcaCo7tFubMIesU6cWuTYucsHE+wjbADjuSNX968qczNe ! NoL2BUznXOQoPu6HQO4/8cr7ib+VQkB2bHQcMoZazPUStIID1e4CL4XcxfuAmT8o ! 3XDvMLgVqNp5W2f8Mzmk3/DbtsLXLOv5BADsCzQpseC8ikSYJC72hcon1wlUmGeH ! 3qgGiiHhYXFa18xgI5juoO8DaWno0rPPlgr36Y8mSB5qjYHMXwjKnKyUmt11H+hU ! +6uk4hq3Rjd8l+vfuOSr1xoTrtBUg9Rwfw6JVo0DC+8CWg4oBWsLXVM6KQXPFdJs ! 8kyFQplR/iP1XQQA/2tbDANjAYGNNDjJO9/0kEnSAUyYMasFJDrA2q17J5CroVQw ! QpMmWwdDkRANUVPKnWHS5sS65BRc7UytKe2f3A3ZInGXJIK2Hl+TzapWYcYxql+4 ! ol5mEDDMDbhEE8Wmj9KyB6iifdLI0K+yxNb9T4Jpj3J18+St+G8+9AcFcBEEAM1b ! M9C+/05cnV8gjcByqH9M9ypo8fzPvMKVXWwCLQXpaL50QIkzLURkiMoEWrCdELaA ! sVPotRzePTIQ1ooLeDxd1gRnDqjZiIR0kwmv6vq8tfzY96O2ZbGWFI5eth89aWEJ ! WB8AR3zYcXpwJLwPuhXW2/NlZF0bclJ3jNzAfTIeQmeJAR8EGAECAAkFAkLr2roC ! GwwACgkQyJnqk0QZVVku1wgAg1bLSjPkhw+ldG5HzumpqR84+JKyozdJaJzefu2+ ! 1iqYE0B0WLz2PJVIiK41xiEkKhBvTOQYuXmtWqAWXptD91P5SoXoNJWLQO3TNwar ! ANhHxkWgw/TOUxQqoctlRUej5NDD+4eW5G9lcS1FEGuKDWtX096u80vO+TbyJjvx ! 2eVM1k+XdmeYsGOiNgDimCreJGYc14G7eY9jt24gw10n1sMAKI1qm6lcoHqZ9OOy ! la+wJdroPYZGO7R8+1O9R22WrK6BYDT5j/1JwMZqbOESjNvDEVT0yOHClCHRN4CC ! hbt6LhKhCLUNdz/udIt0JAC6c/HdPLSW3HnmM3+iNj+Kug== ! =UKh3 ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! insert into keytbl (id, name, pubkey, seckey) ! values (7, 'rsaenc2048-psw', ' ! same key with password ! ', ' ! -----BEGIN PGP PRIVATE KEY BLOCK----- ! Version: GnuPG v1.4.11 (GNU/Linux) ! ! lQPEBELr2m0BCADOrnknlnXI0EzRExf/TgoHvK7Xx/E0keWqV3KrOyC3/tY2KOrj ! UVxaAX5pkFX9wdQObGPIJm06u6D16CH6CildX/vxG7YgvvKzK8JGAbwrXAfk7OIW ! czO2zRaZGDynoK3mAxHRBReyTKtNv8rDQhuZs6AOozJNARdbyUO/yqUnqNNygWuT ! 4htFDEuLPIJwAbMSD0BvFW6YQaPdxzaAZm3EWVNbwDzjgbBUdBiUUwRdZIFUhsjJ ! dirFdy5+uuZru6y6CNC1OERkJ7P8EyoFiZckAIE5gshVZzNuyLOZjc5DhWBvLbX4 ! NZElAnfiv+4nA6y8wQLSIbmHA3nqJaBklj85AAYp/gcDCNnoEKwFo86JYCE1J92R ! HRQ7DoyAZpW1O0dTXL8Epk0sKsKDrCJOrIkDymsjfyBexADIeqOkioy/50wD2Mku ! CVHKWO2duAiJN5t/FoRgpR1/Q11K6QdfqOG0HxwfIXLcPv7eSIso8kWorj+I01BP ! Fn/atGEbIjdWaz/q2XHbu0Q3x6Et2gIsbLRVMhiYz1UG9uzGJ0TYCdBa2SFhs184 ! 52akMpD+XVdM0Sq9/Cx40Seo8hzERB96+GXnQ48q2OhlvcEXiFyD6M6wYCWbEV+6 ! XQVMymbl22FPP/bD9ReQX2kjrkQlFAtmhr+0y8reMCbcxwLuQfA3173lSPo7jrbH ! oLrGhkRpqd2bYCelqdy/XMmRFso0+7uytHfTFrUNfDWfmHVrygoVrNnarCbxMMI0 ! I8Q+tKHMThWgf0rIOSh0+w38kOXFCEqEWF8YkAqCrMZIlJIed78rOCFgG4aHajZR ! D8rpXdUOIr/WeUddK25Tu8IuNJb0kFf12IMgNh0nS+mzlqWiofS5kA0TeB8wBV6t ! RotaeyDNSsMoowfN8cf1yHMTxli+K1Tasg003WVUoWgUc+EsJ5+KTNwaX5uGv0Cs ! j6dg6/FVeVRL9UsyF+2kt7euX3mABuUtcVGx/ZKTq/MNGEh6/r3B5U37qt+FDRbw ! ppKPc2AP+yBUWsQskyrxFgv4eSpcLEg+lgdz/zLyG4qW4lrFUoO790Cm/J6C7/WQ ! Z+E8kcS8aINJkg1skahH31d59ZkbW9PVeJMFGzNb0Z2LowngNP/BMrJ0LT2CQyLs ! UxbT16S/gwAyUpJnbhWYr3nDdlwtC0rVopVTPD7khPRppcsq1f8D70rdIxI4Ouuw ! vbjNZ1EWRJ9f2Ywb++k/xgSXwJkGodUlrUr+3i8cv8mPx+fWvif9q7Y5Ex1wCRa8 ! 8FAj/o+hEbQlUlNBIDIwNDggRW5jIDxyc2EyMDQ4ZW5jQGV4YW1wbGUub3JnPokB ! NAQTAQIAHgUCQuvabQIbAwYLCQgHAwIDFQIDAxYCAQIeAQIXgAAKCRDImeqTRBlV ! WRzJCACbRhx2fYjPGKta69M5dS+kr5UD/CQmsR2t9cB9zyqhratjPnKW9q13+4AG ! P3aByT14IH1c5Mha8rJkNYD2wxmC8jrrcPiJIYoRG+W1sUATY/t8wBbNWF+r9h11 ! m0lEpsmNVff/jU7SpNN6JQ3P7MHd5V85LlDoXIH6QYCLd0PjKU+jNvjiBe5VX0m9 ! a1nacE3xoWc1vbM0DnqEuID78Qgkcrmm0ESeg1h+tRfHxSAyYNc/gPzm8eH6l+hj ! gOvUc4Gd6LpBQSF8TcFfT2TZwJh7WVWDvNIP6FWAW7rzmHnX3wwXkGq4REWeVtk5 ! yBPp6mOtWDiwaqLJYsoHWU11C8zYnQPEBELr2roBCADrgiWXZMzkQOntZa/NS56+ ! CczLFQRQPl/8iJAW1eql/wOJ1UiwGSjT189WCKzE7vtazCIstdCFmwOs4DE6cz4S ! UX4HjzjYHZwmMiuSrIefwuZ7cysMBsMXypQFyMSbqwh102xGvmLz3Z++rydx7Fzl ! 1RC/ny2+FN5dzYPO2DNtNi4dR2tjHktsxBWXAKCmxagAIwyxGouuEqDhYdFtwrA9 ! Qy+M5n6fmGa1Dx07WWnbIud4uCilv8LPVKx5aJamDYWM3v7kS8n51MfTzeK/xoRM ! 2rsgzFdLJqPdbgd2nsD37fngqZnlp7tDxSVSuMckZoSKtq1QsNemtaQSYq7xjPst ! AAYp/gcDCNnoEKwFo86JYAsxoD+wQ0zBi5RBM5EphXTpM1qKxmigsKOvBSaMmr0y ! VjHtGY3poyV3t6VboOGCsFcaKm0tIdDL7vrxxwyYESETpF29b7QrYcoaLKMG7fsy ! t9SUI3UV2H9uUquHgqHtsqz0jYOgm9tYnpesgQ/kOAWI/tej1ZJXUIWEmZMH/W6d ! ATNvZ3ivwApfC0qF5G3oPgBSoIuQ/8I+pN/kmuyNAnJWNgagFhA/2VFBvh5XgztV ! NW7G//KpR1scsn140SO/wpGBM3Kr4m8ztl9w9U6a7NlQZ2ub3/pIUTpSzyLBxJZ/ ! RfuZI7ROdgDMKmEgCYrN2kfp0LIxnYL6ZJu3FDcS4V098lyf5rHvB3PAEdL6Zyhd ! qYp3Sx68r0F4vzk5iAIWf6pG2YdfoP2Z48Pmq9xW8qD9iwFcoz9oAzDEMENn6dfq ! 6MzfoaXEoYp8cR/o+aeEaGUtYBHiaxQcJYx35B9IhsXXA49yRORK8qdwhSHxB3NQ ! H3pUWkfw368f/A207hQVs9yYXlEvMZikxl58gldCd3BAPqHm/XzgknRRNQZBPPKJ ! BMZebZ22Dm0qDuIqW4GXLB4sLf0+UXydVINIUOlzg+S4jrwx7eZqb6UkRXTIWVo5 ! psTsD14wzWBRdUQHZOZD33+M8ugmewvLY/0Uix+2RorkmB7/jqoZvx/MehDwmCZd ! VH8sb2wpZ55sj7gCXxvrfieQD/VeH54OwjjbtK56iYq56RVD0h1az8xDY2GZXeT7 ! J0c3BGpuoca5xOFWr1SylAr/miEPxOBfnfk8oZQJvZrjSBGjsTbALep2vDJk8ROD ! sdQCJuU1RHDrwKHlbUL0NbGRO2juJGsatdWnuVKsFbaFW2pHHkezKuwOcaAJv7Xt ! 8LRF17czAJ1uaLKwV8Paqx6UIv+089GbWZi7HIkBHwQYAQIACQUCQuvaugIbDAAK ! CRDImeqTRBlVWS7XCACDVstKM+SHD6V0bkfO6ampHzj4krKjN0lonN5+7b7WKpgT ! QHRYvPY8lUiIrjXGISQqEG9M5Bi5ea1aoBZem0P3U/lKheg0lYtA7dM3BqsA2EfG ! RaDD9M5TFCqhy2VFR6Pk0MP7h5bkb2VxLUUQa4oNa1fT3q7zS875NvImO/HZ5UzW ! T5d2Z5iwY6I2AOKYKt4kZhzXgbt5j2O3biDDXSfWwwAojWqbqVygepn047KVr7Al ! 2ug9hkY7tHz7U71HbZasroFgNPmP/UnAxmps4RKM28MRVPTI4cKUIdE3gIKFu3ou ! EqEItQ13P+50i3QkALpz8d08tJbceeYzf6I2P4q6 ! =QFm5 ! -----END PGP PRIVATE KEY BLOCK----- ! '); ! -- elg1024 / aes128 ! insert into encdata (id, data) values (1, ' ! -----BEGIN PGP MESSAGE----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! hQEOA9k2z2S7c/RmEAQAgVWW0DeLrZ+1thWJGBPp2WRFL9HeNqqWHbKJCXJbz1Uy ! faUY7yxVvG5Eutmo+JMiY3mg23/DgVVXHQZsTWpGvGM6djgUNGKUjZDbW6Nog7Mr ! e78IywattCOmgUP9vIwwg3OVjuDCN/nVirGQFnXpJBc8DzWqDMWRWDy1M0ZsK7AD ! /2JTosSFxUdpON0DKtIY3GLzmh6Nk3iV0g8VgJKUBT1rhCXuMDj3snm//EMm7hTY ! PlnObq4mIhgz8NqprmhooxnU0Kapofb3P3wCHPpU14zxhXY8iKO/3JhBq2uFcx4X ! uBMwkW4AdNxY/mzJZELteTL8Tr0s7PISk+owb4URpG3n0jsBc0CVULxrjh5Ejkdw ! wCM195J6+KbQxOOFQ0b3uOVvv4dEgd/hRERCOq5EPaFhlHegyYJ7YO842vnSDA== ! =PABx ! -----END PGP MESSAGE----- ! '); ! -- elg2048 / blowfish ! insert into encdata (id, data) values (2, ' ! -----BEGIN PGP MESSAGE----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! hQIOAywibh/+XMfUEAf+OINhBngEsw4a/IJIeJvUgv1gTQzBwOdQEuc/runr4Oa8 ! Skw/Bj0X/zgABVZLem1a35NHaNwaQaCFwMQ41YyWCu+jTdsiyX/Nw0w8LKKz0rNC ! vVpG6YuV7Turtsf8a5lXy1K0SHkLlgxQ6c76GS4gtSl5+bsL2+5R1gSRJ9NXqCQP ! OHRipEiYwBPqr5R21ZG0FXXNKGOGkj6jt/M/wh3WVtAhYuBI+HPKRfAEjd/Pu/eD ! e1zYtkH1dKKFmp44+nF0tTI274xpuso7ShfKYrOK3saFWrl0DWiWteUinjSA1YBY ! m7dG7NZ8PW+g1SZWhEoPjEEEHz3kWMvlKheMRDudnQf/dDyX6kZVIAQF/5B012hq ! QyVewgTGysowFIDn01uIewoEA9cASw699jw9IoJp+k5WZXnU+INllBLzQxniQCSu ! iEcr0x3fYqNtj9QBfbIqyRcY6HTWcmzyOUeGaSyX76j+tRAvtVtXpraFFFnaHB70 ! YpXTjLkp8EBafzMghFaKDeXlr2TG/T7rbwcwWrFIwPqEAUKWN5m97Q3eyo8/ioMd ! YoFD64J9ovSsgbuU5IpIGAsjxK+NKzg/2STH7zZFEVCtgcIXsTHTZfiwS98/+1H9 ! p1DIDaXIcUFV2ztmcKxh9gt2sXRz1W+x6D8O0k3nanU5yGG4miLKaq18fbcA0BD1 ! +NIzAfelq6nvvxYKcGcamBMgLo5JkZOBHvyr6RsAKIT5QYc0QTjysTk9l0Am3gYc ! G2pAE+3k ! =TBHV ! -----END PGP MESSAGE----- ! '); ! -- elg4096 / aes256 ! insert into encdata (id, data) values (3, ' ! -----BEGIN PGP MESSAGE----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! hQQOA7aFBP0Sjh/5EA/+JCgncc8IZmmRjPStWnGf9tVJhgHTn+smIclibGzs0deS ! SPSCitzpblwbUDvu964+/5e5Q1l7rRuNN+AgETlEd4eppv7Swn2ChdgOXxRwukcT ! Nh3G+PTFvD4ayi7w1db3qvXIt0MwN4Alt436wJmK1oz2Ka9IcyO+wHWrDy1nSGSx ! z5x7YEj+EZPgWc/YAvudqE8Jpzd/OT5zSHN09UFkIAk6NxisKaIstbEGFgpqtoDZ ! 1SJM84XAdL2IcaJ3YY7k/yzwlawhsakKd4GSd5vWmAwvyzzbSiBMfKsDE16ePLNU ! ZBF7CzmlCBPZ7YrFAHLpXBXXkCQvzD2BEYOjse50ZEfJ036T7950Ozcdy1EQbGon ! nyQ4Gh0PBpnMcBuiXOceWuYzhlzFOzDtlVKdNTxFRDcbEyW2jo9xQYvCCLnYy8EH ! 2M7S8jCtVYJBbn63a82ELv+3+kWYcsvBJv2ZVBh4ncrBu9o0P+OYS7ApoOU+j6p2 ! +t0RXHksqXS1YiUwYF5KSw09EbYMgNZ9G04Px/PxLU6fSC9iDrGX7Xt3kOUP0mku ! C518fPckT0zzRXqfFruJNRzDytW50KxkOQZzU1/Az1YlYN9QzWeU4EtLPb2fftZo ! D0qH/ln+f9Op5t6sD2fcxZVECU1b/bFtZsxvwH406YL+UQ7hU/XnZrzVVzODal8P ! /j1hg7v7BdJqu1DTp9nFWUuwMFcYAczuXn29IG183NZ7Ts4whDeYEhS8eNoLPX4j ! txY12ILD/w/3Q4LoW/hPa6OdfEzsn0U5GLf1WiGmJE1H6ft2U/xUnerc/u0kt+FU ! WAisArd4MuKtf7B5Vu/VF3kUdrR0hTniUKUivmC4o1jSId31Dufxj4aadVyldXAr ! 6TNBcdyragZjxEZ6hsBCYzA0Rd1a8atd6OaQoIEEfAzCu5Ks29pydHErStYGjWJ1 ! KA5KPLVvjbHpDmRhlCcm8vgpYQsBYEB5gE9fx5yCTlsVhCB6y23h7hfdMqerDqkO ! ZOPsO5h+tiHCdIrQ36sMjuINy1/K2rYcXd+Crh2iHcfidpU9fvDz2ihTRNQlhjuT ! 0cQZM5JhctEx4VXF4LDctRhit7Hn0iqsk604woQfJVvP8O673xSXT/kBY0A/v9C0 ! 3C4YoFNeSaKwbfZQ/4u1ZFPJxK2IIJa8UGpyAUewLMlzGVVagljybv/f4Z9ERAhy ! huq5sMmw8UPsrJF2TUGHz5WSIwoh0J/qovoQI09I9sdEnFczDvRavMO2Mldy3E5i ! exz9oewtel6GOmsZQSYWT/vJzbYMmvHNmNpVwwoKrLV6oI3kyQ80GHBwI1WlwHoK ! 2iRB0w8q4VVvJeYAz8ZIp380cqC3pfO0uZsrOx4g3k4X0jsB5y7rF5xXcZfnVbvG ! DYKcOy60/OHMWVvpw6trAoA+iP+cVWPtrbRvLglTVTfYmi1ToZDDipkALBhndQ== ! =L/M/ ! -----END PGP MESSAGE----- ! '); ! -- rsaenc2048 / aes128 ! insert into encdata (id, data) values (4, ' ! -----BEGIN PGP MESSAGE----- ! Version: GnuPG v1.4.1 (GNU/Linux) ! ! hQEMA/0CBsQJt0h1AQf+JyYnCiortj26P11zk28MKOGfWpWyAhuIgwbJXsdQ+e6r ! pEyyqs9GC6gI7SNF6+J8B/gsMwvkAL4FHAQCvA4ZZ6eeXR1Of4YG22JQGmpWVWZg ! DTyfhA2vkczuqfAD2tgUpMT6sdyGkQ/fnQ0lknlfHgC5GRx7aavOoAKtMqiZW5PR ! yae/qR48mjX7Mb+mLvbagv9mHEgQSmHwFpaq2k456BbcZ23bvCmBnCvqV/90Ggfb ! VP6gkSoFVsJ19RHsOhW1dk9ehbl51WB3zUOO5FZWwUTY9DJvKblRK/frF0+CXjE4 ! HfcZXHSpSjx4haGGTsMvEJ85qFjZpr0eTGOdY5cFhNJAAVP8MZfji7OhPRAoOOIK ! eRGOCkao12pvPyFTFnPd5vqmyBbdNpK4Q0hS82ljugMJvM0p3vJZVzW402Kz6iBL ! GQ== ! =XHkF ! -----END PGP MESSAGE----- ! '); ! -- rsaenc2048 / aes128 (not from gnupg) ! insert into encdata (id, data) values (5, ' ! -----BEGIN PGP MESSAGE----- ! ! wcBMA/0CBsQJt0h1AQgAzxZ8j+OTeZ8IlLxfZ/mVd28/gUsCY+xigWBk/anZlK3T ! p2tNU2idHzKdAttH2Hu/PWbZp4kwjl9spezYxMqCeBZqtfGED88Y+rqK0n/ul30A ! 7jjFHaw0XUOqFNlST1v6H2i7UXndnp+kcLfHPhnO5BIYWxB2CYBehItqtrn75eqr ! C7trGzU/cr74efcWagbCDSNjiAV7GlEptlzmgVMmNikyI6w0ojEUx8lCLc/OsFz9 ! pJUAX8xuwjxDVv+W7xk6c96grQiQlm+FLDYGiGNXoAzx3Wi/howu3uV40dXfY+jx ! 3WBrhEew5Pkpt1SsWoFnJWOfJ8GLd0ec8vfRCqAIVdLgAeS7NyawQYtd6wuVrEAj ! 5SMg4Thb4d+g45RksuGLHUUr4qO9tiXglODa4InhmJfgNuLk+RGz4LXjq8wepEmW ! vRbgFOG54+Cf4C/gC+HkreDm5JKSKjvvw4B/jC6CDxq+JoziEe2Z1uEjCuEcr+Es ! /eGzeOi36BejXPMHeKxXejj5qBBHKV0pHVhZSgffR0TtlXdB967Yl/5agV0R89hI ! 7Gw52emfnH4Z0Y4V0au2H0k1dR/2IxXdJEWSTG7Be1JHT59p9ei2gSEOrdBMIOjP ! tbYYUlmmbvD49bHfThkDiC+oc9947LgQsk3kOOLbNHcjkbrjH8R5kjII4m/SEZA1 ! g09T+338SzevBcVXh/cFrQ6/Et+lyyO2LJRUMs69g/HyzJOVWT2Iu8E0eS9MWevY ! Qtrkrhrpkl3Y02qEp/j6M03Yu2t6ZF7dp51aJ5VhO2mmmtHaTnCyCc8Fcf72LmD8 ! blH2nKZC9d6fi4YzSYMepZpMOFR65M80MCMiDUGnZBB8sEADu2/iVtqDUeG8mAA= ! =PHJ1 ! -----END PGP MESSAGE----- ! '); ! -- successful decrypt ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=1 and encdata.id=1; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=2 and encdata.id=2; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=3 and encdata.id=3; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=6 and encdata.id=4; ! pgp_pub_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- wrong key ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=2 and encdata.id=1; ! ERROR: Wrong key ! -- sign-only key ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=4 and encdata.id=1; ! ERROR: No encryption key found ! -- rsa: password-protected secret key, wrong password ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey), '123') ! from keytbl, encdata where keytbl.id=7 and encdata.id=4; ! ERROR: Wrong key or corrupt data ! -- rsa: password-protected secret key, right password ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool') ! from keytbl, encdata where keytbl.id=7 and encdata.id=4; ! pgp_pub_decrypt ! ----------------- ! Secret message. ! (1 row) ! ! -- password-protected secret key, no password ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=5 and encdata.id=1; ! ERROR: Need password for secret key ! -- password-protected secret key, wrong password ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'foo') ! from keytbl, encdata where keytbl.id=5 and encdata.id=1; ! ERROR: Wrong key or corrupt data ! -- password-protected secret key, right password ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey), 'parool') ! from keytbl, encdata where keytbl.id=5 and encdata.id=1; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! -- test for a short read from prefix_init ! select pgp_pub_decrypt(dearmor(data), dearmor(seckey)) ! from keytbl, encdata where keytbl.id=6 and encdata.id=5; ! ERROR: Wrong key or corrupt data --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-pubkey-encrypt.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-pubkey-encrypt.out 2016-03-15 16:28:48.623642183 +0300 *************** *** 1,70 **** ! -- ! -- PGP Public Key Encryption ! -- ! -- ensure consistent test output regardless of the default bytea format ! SET bytea_output TO escape; ! -- successful encrypt/decrypt ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=1; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=2; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=3; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=6; ! pgp_pub_decrypt ! ----------------- ! Secret msg ! (1 row) ! ! -- try with rsa-sign only ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=4; ! ERROR: No encryption key found ! -- try with secret key ! select pgp_pub_decrypt( ! pgp_pub_encrypt('Secret msg', dearmor(seckey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=1; ! ERROR: Refusing to encrypt with secret key ! -- does text-to-bytea works ! select pgp_pub_decrypt_bytea( ! pgp_pub_encrypt('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=1; ! pgp_pub_decrypt_bytea ! ----------------------- ! Secret msg ! (1 row) ! ! -- and bytea-to-text? ! select pgp_pub_decrypt( ! pgp_pub_encrypt_bytea('Secret msg', dearmor(pubkey)), ! dearmor(seckey)) ! from keytbl where keytbl.id=1; ! ERROR: Not text data --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/expected/pgp-info.out 2016-03-15 14:32:12.933977992 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/pgcrypto/results/pgp-info.out 2016-03-15 16:28:48.631642256 +0300 *************** *** 1,79 **** ! -- ! -- PGP info functions ! -- ! -- pgp_key_id ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=1; ! pgp_key_id ! ------------------ ! D936CF64BB73F466 ! (1 row) ! ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=2; ! pgp_key_id ! ------------------ ! 2C226E1FFE5CC7D4 ! (1 row) ! ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=3; ! pgp_key_id ! ------------------ ! B68504FD128E1FF9 ! (1 row) ! ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=4; -- should fail ! ERROR: No encryption key found ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=5; ! pgp_key_id ! ------------------ ! D936CF64BB73F466 ! (1 row) ! ! select pgp_key_id(dearmor(pubkey)) from keytbl where id=6; ! pgp_key_id ! ------------------ ! FD0206C409B74875 ! (1 row) ! ! select pgp_key_id(dearmor(seckey)) from keytbl where id=1; ! pgp_key_id ! ------------------ ! D936CF64BB73F466 ! (1 row) ! ! select pgp_key_id(dearmor(seckey)) from keytbl where id=2; ! pgp_key_id ! ------------------ ! 2C226E1FFE5CC7D4 ! (1 row) ! ! select pgp_key_id(dearmor(seckey)) from keytbl where id=3; ! pgp_key_id ! ------------------ ! B68504FD128E1FF9 ! (1 row) ! ! select pgp_key_id(dearmor(seckey)) from keytbl where id=4; -- should fail ! ERROR: No encryption key found ! select pgp_key_id(dearmor(seckey)) from keytbl where id=5; ! pgp_key_id ! ------------------ ! D936CF64BB73F466 ! (1 row) ! ! select pgp_key_id(dearmor(seckey)) from keytbl where id=6; ! pgp_key_id ! ------------------ ! FD0206C409B74875 ! (1 row) ! ! select pgp_key_id(dearmor(data)) as data_key_id ! from encdata order by id; ! data_key_id ! ------------------ ! D936CF64BB73F466 ! 2C226E1FFE5CC7D4 ! B68504FD128E1FF9 ! FD0206C409B74875 ! FD0206C409B74875 ! (5 rows) ! --- 1 ---- ! psql: FATAL: the database system is in recovery mode ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="pgcrypto.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pgcrypto.out" 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) --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="pgstattuple.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pgstattuple.diffs" *** /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. ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="pgstattuple.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="pgstattuple.out" test pgstattuple ... FAILED --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="postgres_fdw.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="postgres_fdw.diffs" *** /home/vpopov/Projects/pwdtest.new/postgresql/contrib/postgres_fdw/expected/postgres_fdw.out 2016-03-15 14:32:12.937978027 +0300 --- /home/vpopov/Projects/pwdtest.new/postgresql/contrib/postgres_fdw/results/postgres_fdw.out 2016-03-15 16:47:34.565851690 +0300 *************** *** 187,5102 **** -- To exercise multiple code paths, we use local stats on ft1 -- and remote-estimate mode on ft2. ANALYZE ft1; ALTER FOREIGN TABLE ft2 OPTIONS (use_remote_estimate 'true'); -- =================================================================== -- simple queries -- =================================================================== -- single table without alias EXPLAIN (COSTS false) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------- ! Limit ! -> Foreign Scan on ft1 ! (2 rows) ! ! SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo ! 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo ! 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo ! 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo ! (10 rows) ! ! -- single table with alias - also test that tableoid sort is not pushed to remote side ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------- ! Limit ! Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid ! -> Sort ! Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid ! Sort Key: t1.c3, t1.c1, t1.tableoid ! -> Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8, tableoid ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (8 rows) ! ! SELECT * FROM ft1 t1 ORDER BY t1.c3, t1.c1, t1.tableoid OFFSET 100 LIMIT 10; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! 103 | 3 | 00103 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo ! 105 | 5 | 00105 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo ! 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 107 | 7 | 00107 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 109 | 9 | 00109 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo ! 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo ! (10 rows) ! ! -- whole-row reference ! EXPLAIN (VERBOSE, COSTS false) SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.*, c3, c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.*, c3, c1 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c3 ASC NULLS LAST, "C 1" ASC NULLS LAST ! (5 rows) ! ! SELECT t1 FROM ft1 t1 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! t1 ! -------------------------------------------------------------------------------------------- ! (101,1,00101,"Fri Jan 02 00:00:00 1970 PST","Fri Jan 02 00:00:00 1970",1,"1 ",foo) ! (102,2,00102,"Sat Jan 03 00:00:00 1970 PST","Sat Jan 03 00:00:00 1970",2,"2 ",foo) ! (103,3,00103,"Sun Jan 04 00:00:00 1970 PST","Sun Jan 04 00:00:00 1970",3,"3 ",foo) ! (104,4,00104,"Mon Jan 05 00:00:00 1970 PST","Mon Jan 05 00:00:00 1970",4,"4 ",foo) ! (105,5,00105,"Tue Jan 06 00:00:00 1970 PST","Tue Jan 06 00:00:00 1970",5,"5 ",foo) ! (106,6,00106,"Wed Jan 07 00:00:00 1970 PST","Wed Jan 07 00:00:00 1970",6,"6 ",foo) ! (107,7,00107,"Thu Jan 08 00:00:00 1970 PST","Thu Jan 08 00:00:00 1970",7,"7 ",foo) ! (108,8,00108,"Fri Jan 09 00:00:00 1970 PST","Fri Jan 09 00:00:00 1970",8,"8 ",foo) ! (109,9,00109,"Sat Jan 10 00:00:00 1970 PST","Sat Jan 10 00:00:00 1970",9,"9 ",foo) ! (110,0,00110,"Sun Jan 11 00:00:00 1970 PST","Sun Jan 11 00:00:00 1970",0,"0 ",foo) ! (10 rows) ! ! -- empty result ! SELECT * FROM ft1 WHERE false; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+----+----+----+----+----+---- ! (0 rows) ! ! -- with WHERE clause ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------ ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c7 >= '1'::bpchar)) AND (("C 1" = 101)) AND ((c6 = '1'::text)) ! (3 rows) ! ! SELECT * FROM ft1 t1 WHERE t1.c1 = 101 AND t1.c6 = '1' AND t1.c7 >= '1'; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! -- with FOR UPDATE/SHARE ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; ! QUERY PLAN ! ---------------------------------------------------------------------------------------------------------------- ! LockRows ! Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* ! -> Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 101)) FOR UPDATE ! (5 rows) ! ! SELECT * FROM ft1 t1 WHERE c1 = 101 FOR UPDATE; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------- ! LockRows ! Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* ! -> Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 102)) FOR SHARE ! (5 rows) ! ! SELECT * FROM ft1 t1 WHERE c1 = 102 FOR SHARE; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 102 | 2 | 00102 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! (1 row) ! ! -- aggregate ! SELECT COUNT(*) FROM ft1 t1; ! count ! ------- ! 1000 ! (1 row) ! ! -- subquery ! SELECT * FROM ft1 t1 WHERE t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 <= 10) ORDER BY c1; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo ! 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST | Tue Jan 06 00:00:00 1970 | 5 | 5 | foo ! 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | 9 | foo ! 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo ! (10 rows) ! ! -- subquery+MAX ! SELECT * FROM ft1 t1 WHERE t1.c3 = (SELECT MAX(c3) FROM ft2 t2) ORDER BY c1; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+----+-------+------------------------------+--------------------------+----+------------+----- ! 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo ! (1 row) ! ! -- used in CTE ! WITH t1 AS (SELECT * FROM ft1 WHERE c1 <= 10) SELECT t2.c1, t2.c2, t2.c3, t2.c4 FROM t1, ft2 t2 WHERE t1.c1 = t2.c1 ORDER BY t1.c1; ! c1 | c2 | c3 | c4 ! ----+----+-------+------------------------------ ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST ! 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST ! 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST ! 5 | 5 | 00005 | Tue Jan 06 00:00:00 1970 PST ! 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST ! 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST ! 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST ! 9 | 9 | 00009 | Sat Jan 10 00:00:00 1970 PST ! 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST ! (10 rows) ! ! -- fixed values ! SELECT 'fixed', NULL FROM ft1 t1 WHERE c1 = 1; ! ?column? | ?column? ! ----------+---------- ! fixed | ! (1 row) ! ! -- Test forcing the remote server to produce sorted data for a merge join. ! SET enable_hashjoin TO false; ! SET enable_nestloop TO false; ! -- inner join; expressions in the clauses appear in the equivalence class list ! EXPLAIN (VERBOSE, COSTS false) ! SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2."C 1" ! -> Merge Join ! Output: t1.c1, t2."C 1" ! Merge Cond: (t1.c1 = t2."C 1") ! -> Foreign Scan on public.ft2 t1 ! Output: t1.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST ! -> Index Only Scan using t1_pkey on "S 1"."T 1" t2 ! Output: t2."C 1" ! (10 rows) ! ! SELECT t1.c1, t2."C 1" FROM ft2 t1 JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ! c1 | C 1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- outer join; expressions in the clauses do not appear in equivalence class ! -- list but no output change as compared to the previous query ! EXPLAIN (VERBOSE, COSTS false) ! SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2."C 1" ! -> Merge Left Join ! Output: t1.c1, t2."C 1" ! Merge Cond: (t1.c1 = t2."C 1") ! -> Foreign Scan on public.ft2 t1 ! Output: t1.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST ! -> Index Only Scan using t1_pkey on "S 1"."T 1" t2 ! Output: t2."C 1" ! (10 rows) ! ! SELECT t1.c1, t2."C 1" FROM ft2 t1 LEFT JOIN "S 1"."T 1" t2 ON (t1.c1 = t2."C 1") OFFSET 100 LIMIT 10; ! c1 | C 1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- A join between local table and foreign join. ORDER BY clause is added to the ! -- foreign join so that the local table can be joined using merge join strategy. ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1."C 1" ! -> Merge Right Join ! Output: t1."C 1" ! Merge Cond: (t3.c1 = t1."C 1") ! -> Foreign Scan ! Output: t3.c1 ! Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3) ! Remote SQL: SELECT r3."C 1" FROM ("S 1"."T 1" r2 INNER JOIN "S 1"."T 1" r3 ON (TRUE)) WHERE ((r2."C 1" = r3."C 1")) ORDER BY r2."C 1" ASC NULLS LAST ! -> Index Only Scan using t1_pkey on "S 1"."T 1" t1 ! Output: t1."C 1" ! (11 rows) ! ! SELECT t1."C 1" FROM "S 1"."T 1" t1 left join ft1 t2 join ft2 t3 on (t2.c1 = t3.c1) on (t3.c1 = t1."C 1") OFFSET 100 LIMIT 10; ! C 1 ! ----- ! 101 ! 102 ! 103 ! 104 ! 105 ! 106 ! 107 ! 108 ! 109 ! 110 ! (10 rows) ! ! RESET enable_hashjoin; ! RESET enable_nestloop; ! -- =================================================================== ! -- WHERE with remotely-executable conditions ! -- =================================================================== ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = 1; -- Var, OpExpr(b), Const ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE t1.c1 = 100 AND t1.c2 = 0; -- BoolExpr ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 100)) AND ((c2 = 0)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 IS NULL; -- NullTest ! QUERY PLAN ! ------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" IS NULL)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 IS NOT NULL; -- NullTest ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" IS NOT NULL)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE round(abs(c1), 0) = 1; -- FuncExpr ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((round(abs("C 1"), 0) = 1::numeric)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = -c1; -- OpExpr(l) ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = (- "C 1"))) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE 1 = c1!; -- OpExpr(r) ! QUERY PLAN ! ---------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((1::numeric = ("C 1" !))) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE (c1 IS NOT NULL) IS DISTINCT FROM (c1 IS NOT NULL); -- DistinctExpr ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" IS NOT NULL) IS DISTINCT FROM ("C 1" IS NOT NULL))) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = ANY(ARRAY[c2, 1, c1 + 0]); -- ScalarArrayOpExpr ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = ANY (ARRAY[c2, 1, ("C 1" + 0)]))) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c1 = (ARRAY[c1,c2,3])[1]; -- ArrayRef ! QUERY PLAN ! ---------------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = ((ARRAY["C 1", c2, 3])[1]))) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c6 = E'foo''s\\bar'; -- check special chars ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c6 = E'foo''s\\bar'::text)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 t1 WHERE c8 = 'foo'; -- can't be sent to remote ! QUERY PLAN ! ------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (4 rows) ! ! -- parameterized remote path for foreign table ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM "S 1"."T 1" a, ft2 b WHERE a."C 1" = 47 AND b.c1 = a.c2; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------- ! Nested Loop ! Output: a."C 1", a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8 ! -> Index Scan using t1_pkey on "S 1"."T 1" a ! Output: a."C 1", a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8 ! Index Cond: (a."C 1" = 47) ! -> Foreign Scan on public.ft2 b ! Output: b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1")) ! (8 rows) ! ! SELECT * FROM ft2 a, ft2 b WHERE a.c1 = 47 AND b.c1 = a.c2; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+-----+----+----+-------+------------------------------+--------------------------+----+------------+----- ! 47 | 7 | 00047 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo | 7 | 7 | 00007 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! (1 row) ! ! -- check both safe and unsafe join conditions ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM ft2 a, ft2 b ! WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7); ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------- ! Nested Loop ! Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8, b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8 ! -> Foreign Scan on public.ft2 a ! Output: a.c1, a.c2, a.c3, a.c4, a.c5, a.c6, a.c7, a.c8 ! Filter: (a.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((c2 = 6)) ! -> Foreign Scan on public.ft2 b ! Output: b.c1, b.c2, b.c3, b.c4, b.c5, b.c6, b.c7, b.c8 ! Filter: (upper((a.c7)::text) = (b.c7)::text) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (($1::integer = "C 1")) ! (10 rows) ! ! SELECT * FROM ft2 a, ft2 b ! WHERE a.c2 = 6 AND b.c1 = a.c1 AND a.c8 = 'foo' AND b.c7 = upper(a.c7); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+-----+-----+----+-------+------------------------------+--------------------------+----+------------+----- ! 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo | 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST | Wed Jan 07 00:00:00 1970 | 6 | 6 | foo ! 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo | 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo | 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST | Tue Jan 27 00:00:00 1970 | 6 | 6 | foo ! 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo | 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST | Fri Feb 06 00:00:00 1970 | 6 | 6 | foo ! 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo | 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST | Mon Feb 16 00:00:00 1970 | 6 | 6 | foo ! 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo | 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST | Thu Feb 26 00:00:00 1970 | 6 | 6 | foo ! 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo | 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST | Sun Mar 08 00:00:00 1970 | 6 | 6 | foo ! 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo | 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST | Wed Mar 18 00:00:00 1970 | 6 | 6 | foo ! 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo | 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST | Sat Mar 28 00:00:00 1970 | 6 | 6 | foo ! 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo | 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST | Tue Apr 07 00:00:00 1970 | 6 | 6 | foo ! (100 rows) ! ! -- bug before 9.3.5 due to sloppy handling of remote-estimate parameters ! SELECT * FROM ft1 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft2 WHERE c1 < 5)); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo ! (4 rows) ! ! SELECT * FROM ft2 WHERE c1 = ANY (ARRAY(SELECT c1 FROM ft1 WHERE c1 < 5)); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST | Mon Jan 05 00:00:00 1970 | 4 | 4 | foo ! (4 rows) ! ! -- we should not push order by clause with volatile expressions or unsafe ! -- collations ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM ft2 ORDER BY ft2.c1, random(); ! QUERY PLAN ! ------------------------------------------------------------------------------- ! Sort ! Output: c1, c2, c3, c4, c5, c6, c7, c8, (random()) ! Sort Key: ft2.c1, (random()) ! -> Foreign Scan on public.ft2 ! Output: c1, c2, c3, c4, c5, c6, c7, c8, random() ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (6 rows) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM ft2 ORDER BY ft2.c1, ft2.c3 collate "C"; ! QUERY PLAN ! ------------------------------------------------------------------------------- ! Sort ! Output: c1, c2, c3, c4, c5, c6, c7, c8, ((c3)::text) ! Sort Key: ft2.c1, ft2.c3 COLLATE "C" ! -> Foreign Scan on public.ft2 ! Output: c1, c2, c3, c4, c5, c6, c7, c8, c3 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (6 rows) ! ! -- user-defined operator/function ! CREATE FUNCTION postgres_fdw_abs(int) RETURNS int AS $$ ! BEGIN ! RETURN abs($1); ! END ! $$ LANGUAGE plpgsql IMMUTABLE; ! CREATE OPERATOR === ( ! LEFTARG = int, ! RIGHTARG = int, ! PROCEDURE = int4eq, ! COMMUTATOR = === ! ); ! -- built-in operators and functions can be shipped for remote execution ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); ! QUERY PLAN ! -------------------------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = abs(c2))) ! (5 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = abs(t1.c2); ! count ! ------- ! 9 ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; ! QUERY PLAN ! --------------------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = c2)) ! (5 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = t1.c2; ! count ! ------- ! 9 ! (1 row) ! ! -- by default, user-defined ones cannot ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); ! QUERY PLAN ! ----------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Filter: (t1.c1 = postgres_fdw_abs(t1.c2)) ! Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" ! (6 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); ! count ! ------- ! 9 ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ! QUERY PLAN ! ----------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Filter: (t1.c1 === t1.c2) ! Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" ! (6 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ! count ! ------- ! 9 ! (1 row) ! ! -- but let's put them in an extension ... ! ALTER EXTENSION postgres_fdw ADD FUNCTION postgres_fdw_abs(int); ! ALTER EXTENSION postgres_fdw ADD OPERATOR === (int, int); ! ALTER SERVER loopback OPTIONS (ADD extensions 'postgres_fdw'); ! -- ... now they can be shipped ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); ! QUERY PLAN ! ---------------------------------------------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" = public.postgres_fdw_abs(c2))) ! (5 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 = postgres_fdw_abs(t1.c2); ! count ! ------- ! 9 ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ! QUERY PLAN ! ---------------------------------------------------------------------------------------- ! Aggregate ! Output: count(c3) ! -> Foreign Scan on public.ft1 t1 ! Output: c3 ! Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" OPERATOR(public.===) c2)) ! (5 rows) ! ! SELECT count(c3) FROM ft1 t1 WHERE t1.c1 === t1.c2; ! count ! ------- ! 9 ! (1 row) ! ! -- =================================================================== ! -- JOIN queries ! -- =================================================================== ! -- Analyze ft4 and ft5 so that we have better statistics. These tables do not ! -- have use_remote_estimate set. ! ANALYZE ft4; ! ANALYZE ft5; ! -- join two tables ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1, t1.c3 ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST ! (6 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- join three tables ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c2, t3.c3, t1.c3 ! -> Sort ! Output: t1.c1, t2.c2, t3.c3, t1.c3 ! Sort Key: t1.c3, t1.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c2, t3.c3, t1.c3 ! Relations: ((public.ft1 t1) INNER JOIN (public.ft2 t2)) INNER JOIN (public.ft4 t3) ! Remote SQL: SELECT r1."C 1", r1.c3, r2.c2, r4.c3 FROM (("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) INNER JOIN "S 1"."T 3" r4 ON (TRUE)) WHERE ((r1."C 1" = r4.c1)) AND ((r1."C 1" = r2."C 1")) ! (9 rows) ! ! SELECT t1.c1, t2.c2, t3.c3 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) JOIN ft4 t3 ON (t3.c1 = t1.c1) ORDER BY t1.c3, t1.c1 OFFSET 10 LIMIT 10; ! c1 | c2 | c3 ! ----+----+-------- ! 22 | 2 | AAA022 ! 24 | 4 | AAA024 ! 26 | 6 | AAA026 ! 28 | 8 | AAA028 ! 30 | 0 | AAA030 ! 32 | 2 | AAA032 ! 34 | 4 | AAA034 ! 36 | 6 | AAA036 ! 38 | 8 | AAA038 ! 40 | 0 | AAA040 ! (10 rows) ! ! -- left outer join ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft4 t1) LEFT JOIN (public.ft5 t2) ! Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST ! (6 rows) ! ! SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ! c1 | c1 ! ----+---- ! 22 | ! 24 | 24 ! 26 | ! 28 | ! 30 | 30 ! 32 | ! 34 | ! 36 | 36 ! 38 | ! 40 | ! (10 rows) ! ! -- left outer join + placement of clauses. ! -- clauses within the nullable side are not pulled up, but top level clause on ! -- non-nullable side is pushed into non-nullable side ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Foreign Scan ! Output: t1.c1, t1.c2, ft5.c1, ft5.c2 ! Relations: (public.ft4 t1) LEFT JOIN (public.ft5) ! Remote SQL: SELECT r1.c1, r1.c2, r4.c1, r4.c2 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r4 ON (((r1.c1 = r4.c1)) AND ((r4.c1 < 10)))) WHERE ((r1.c1 < 10)) ! (4 rows) ! ! SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) WHERE t1.c1 < 10; ! c1 | c2 | c1 | c2 ! ----+----+----+---- ! 2 | 3 | | ! 4 | 5 | | ! 6 | 7 | 6 | 7 ! 8 | 9 | | ! (4 rows) ! ! -- clauses within the nullable side are not pulled up, but the top level clause ! -- on nullable side is not pushed down into nullable side ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) ! WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Foreign Scan ! Output: t1.c1, t1.c2, ft5.c1, ft5.c2 ! Relations: (public.ft4 t1) LEFT JOIN (public.ft5) ! Remote SQL: SELECT r1.c1, r1.c2, r4.c1, r4.c2 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r4 ON (((r1.c1 = r4.c1)) AND ((r4.c1 < 10)))) WHERE (((r4.c1 < 10) OR (r4.c1 IS NULL))) AND ((r1.c1 < 10)) ! (4 rows) ! ! SELECT t1.c1, t1.c2, t2.c1, t2.c2 FROM ft4 t1 LEFT JOIN (SELECT * FROM ft5 WHERE c1 < 10) t2 ON (t1.c1 = t2.c1) ! WHERE (t2.c1 < 10 OR t2.c1 IS NULL) AND t1.c1 < 10; ! c1 | c2 | c1 | c2 ! ----+----+----+---- ! 2 | 3 | | ! 4 | 5 | | ! 6 | 7 | 6 | 7 ! 8 | 9 | | ! (4 rows) ! ! -- right outer join ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft4 t2) LEFT JOIN (public.ft5 t1) ! Remote SQL: SELECT r2.c1, r1.c1 FROM ("S 1"."T 3" r2 LEFT JOIN "S 1"."T 4" r1 ON (((r1.c1 = r2.c1)))) ORDER BY r2.c1 ASC NULLS LAST, r1.c1 ASC NULLS LAST ! (6 rows) ! ! SELECT t1.c1, t2.c1 FROM ft5 t1 RIGHT JOIN ft4 t2 ON (t1.c1 = t2.c1) ORDER BY t2.c1, t1.c1 OFFSET 10 LIMIT 10; ! c1 | c1 ! ----+---- ! | 22 ! 24 | 24 ! | 26 ! | 28 ! 30 | 30 ! | 32 ! | 34 ! 36 | 36 ! | 38 ! | 40 ! (10 rows) ! ! -- full outer join ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2) ! Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST ! (6 rows) ! ! SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 45 LIMIT 10; ! c1 | c1 ! -----+---- ! 92 | ! 94 | ! 96 | 96 ! 98 | ! 100 | ! | 3 ! | 9 ! | 15 ! | 21 ! | 27 ! (10 rows) ! ! -- full outer join + WHERE clause, only matched rows ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ! Limit ! Output: t1.c1, t2.c1 ! -> Sort ! Output: t1.c1, t2.c1 ! Sort Key: t1.c1, t2.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft4 t1) FULL JOIN (public.ft5 t2) ! Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 FULL JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) WHERE (((r1.c1 = r2.c1) OR (r1.c1 IS NULL))) ! (9 rows) ! ! SELECT t1.c1, t2.c1 FROM ft4 t1 FULL JOIN ft5 t2 ON (t1.c1 = t2.c1) WHERE (t1.c1 = t2.c1 OR t1.c1 IS NULL) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ! c1 | c1 ! ----+---- ! 66 | 66 ! 72 | 72 ! 78 | 78 ! 84 | 84 ! 90 | 90 ! 96 | 96 ! | 3 ! | 9 ! | 15 ! | 21 ! (10 rows) ! ! -- join two tables with FOR UPDATE clause ! -- tests whole-row reference for row marks ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ! Limit ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> LockRows ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8), r2."C 1", ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1 ! -> Merge Join ! Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* ! Merge Cond: (t1.c1 = t2.c1) ! -> Sort ! Output: t1.c1, t1.c3, t1.* ! Sort Key: t1.c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c3, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE ! -> Sort ! Output: t2.c1, t2.* ! Sort Key: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1, t2.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (23 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE OF t1; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> LockRows ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8), r2."C 1", ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR UPDATE OF r1 FOR UPDATE OF r2 ! -> Merge Join ! Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* ! Merge Cond: (t1.c1 = t2.c1) ! -> Sort ! Output: t1.c1, t1.c3, t1.* ! Sort Key: t1.c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c3, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE ! -> Sort ! Output: t2.c1, t2.* ! Sort Key: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1, t2.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR UPDATE ! (23 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR UPDATE; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- join two tables with FOR SHARE clause ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> LockRows ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8), r2."C 1", ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1 ! -> Merge Join ! Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* ! Merge Cond: (t1.c1 = t2.c1) ! -> Sort ! Output: t1.c1, t1.c3, t1.* ! Sort Key: t1.c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c3, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE ! -> Sort ! Output: t2.c1, t2.* ! Sort Key: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1, t2.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (23 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE OF t1; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> LockRows ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3, t1.*, t2.* ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8), r2."C 1", ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST FOR SHARE OF r1 FOR SHARE OF r2 ! -> Merge Join ! Output: t1.c1, t1.c3, t1.*, t2.c1, t2.* ! Merge Cond: (t1.c1 = t2.c1) ! -> Sort ! Output: t1.c1, t1.c3, t1.* ! Sort Key: t1.c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c3, t1.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE ! -> Sort ! Output: t2.c1, t2.* ! Sort Key: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1, t2.* ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" FOR SHARE ! (23 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10 FOR SHARE; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- join in CTE ! EXPLAIN (COSTS false, VERBOSE) ! WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------ ! Limit ! Output: t.c1_1, t.c2_1, t.c1_3 ! CTE t ! -> Foreign Scan ! Output: t1.c1, t1.c3, t2.c1 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ! -> Sort ! Output: t.c1_1, t.c2_1, t.c1_3 ! Sort Key: t.c1_3, t.c1_1 ! -> CTE Scan on t ! Output: t.c1_1, t.c2_1, t.c1_3 ! (12 rows) ! ! WITH t (c1_1, c1_3, c2_1) AS (SELECT t1.c1, t1.c3, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) SELECT c1_1, c2_1 FROM t ORDER BY c1_3, c1_1 OFFSET 100 LIMIT 10; ! c1_1 | c2_1 ! ------+------ ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- ctid with whole-row reference ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.ctid, t1, t2, t1.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ! Limit ! Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 ! -> Foreign Scan ! Output: t1.ctid, t1.*, t2.*, t1.c1, t1.c3 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1.ctid, ROW(r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c7, r1.c8), r1."C 1", r1.c3, ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ORDER BY r1.c3 ASC NULLS LAST, r1."C 1" ASC NULLS LAST ! (6 rows) ! ! -- SEMI JOIN, not pushed down ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1 ! -> Merge Semi Join ! Output: t1.c1 ! Merge Cond: (t1.c1 = t2.c1) ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST ! -> Materialize ! Output: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST ! (13 rows) ! ! SELECT t1.c1 FROM ft1 t1 WHERE EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c1) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ! c1 ! ----- ! 101 ! 102 ! 103 ! 104 ! 105 ! 106 ! 107 ! 108 ! 109 ! 110 ! (10 rows) ! ! -- ANTI JOIN, not pushed down ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1 ! -> Merge Anti Join ! Output: t1.c1 ! Merge Cond: (t1.c1 = t2.c2) ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ORDER BY "C 1" ASC NULLS LAST ! -> Materialize ! Output: t2.c2 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c2 ! Remote SQL: SELECT c2 FROM "S 1"."T 1" ORDER BY c2 ASC NULLS LAST ! (13 rows) ! ! SELECT t1.c1 FROM ft1 t1 WHERE NOT EXISTS (SELECT 1 FROM ft2 t2 WHERE t1.c1 = t2.c2) ORDER BY t1.c1 OFFSET 100 LIMIT 10; ! c1 ! ----- ! 110 ! 111 ! 112 ! 113 ! 114 ! 115 ! 116 ! 117 ! 118 ! 119 ! (10 rows) ! ! -- CROSS JOIN, not pushed down ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Sort ! Output: t1.c1, t2.c1 ! Sort Key: t1.c1, t2.c1 ! -> Nested Loop ! Output: t1.c1, t2.c1 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ! -> Materialize ! Output: t2.c1 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ! (15 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 CROSS JOIN ft2 t2 ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! ----+----- ! 1 | 101 ! 1 | 102 ! 1 | 103 ! 1 | 104 ! 1 | 105 ! 1 | 106 ! 1 | 107 ! 1 | 108 ! 1 | 109 ! 1 | 110 ! (10 rows) ! ! -- different server, not pushed down. No result expected. ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Merge Join ! Output: t1.c1, t2.c1 ! Merge Cond: (t2.c1 = t1.c1) ! -> Foreign Scan on public.ft6 t2 ! Output: t2.c1, t2.c2, t2.c3 ! Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST ! -> Materialize ! Output: t1.c1, t1.c2, t1.c3 ! -> Foreign Scan on public.ft5 t1 ! Output: t1.c1, t1.c2, t1.c3 ! Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST ! (13 rows) ! ! SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN ft6 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! ----+---- ! (0 rows) ! ! -- unsafe join conditions (c8 has a UDT), not pushed down. Practically a CROSS ! -- JOIN since c8 in both tables has same value. ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Sort ! Output: t1.c1, t2.c1 ! Sort Key: t1.c1, t2.c1 ! -> Merge Left Join ! Output: t1.c1, t2.c1 ! Merge Cond: (t1.c8 = t2.c8) ! -> Sort ! Output: t1.c1, t1.c8 ! Sort Key: t1.c8 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c8 ! Remote SQL: SELECT "C 1", c8 FROM "S 1"."T 1" ! -> Sort ! Output: t2.c1, t2.c8 ! Sort Key: t2.c8 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1, t2.c8 ! Remote SQL: SELECT "C 1", c8 FROM "S 1"."T 1" ! (20 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c8 = t2.c8) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! ----+----- ! 1 | 101 ! 1 | 102 ! 1 | 103 ! 1 | 104 ! 1 | 105 ! 1 | 106 ! 1 | 107 ! 1 | 108 ! 1 | 109 ! 1 | 110 ! (10 rows) ! ! -- unsafe conditions on one side (c8 has a UDT), not pushed down. ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ----------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1, t1.c3 ! -> Sort ! Output: t1.c1, t2.c1, t1.c3 ! Sort Key: t1.c3, t1.c1 ! -> Hash Right Join ! Output: t1.c1, t2.c1, t1.c3 ! Hash Cond: (t2.c1 = t1.c1) ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c1 ! Remote SQL: SELECT "C 1" FROM "S 1"."T 1" ! -> Hash ! Output: t1.c1, t1.c3 ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c3 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c3, c8 FROM "S 1"."T 1" ! (17 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 LEFT JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = 'foo' ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- join where unsafe to pushdown condition in WHERE clause has a column not ! -- in the SELECT clause. In this test unsafe clause needs to have column ! -- references from both joining sides so that the clause is not pushed down ! -- into one of the joining sides. ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------ ! Limit ! Output: t1.c1, t2.c1, t1.c3 ! -> Sort ! Output: t1.c1, t2.c1, t1.c3 ! Sort Key: t1.c3, t1.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1, t1.c3 ! Filter: (t1.c8 = t2.c8) ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r1.c3, r2."C 1", r1.c8, r2.c8 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ! (10 rows) ! ! SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) WHERE t1.c8 = t2.c8 ORDER BY t1.c3, t1.c1 OFFSET 100 LIMIT 10; ! c1 | c1 ! -----+----- ! 101 | 101 ! 102 | 102 ! 103 | 103 ! 104 | 104 ! 105 | 105 ! 106 | 106 ! 107 | 107 ! 108 | 108 ! 109 | 109 ! 110 | 110 ! (10 rows) ! ! -- Aggregate after UNION, for testing setrefs ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, (avg((t1.c1 + t2.c1))) ! -> Sort ! Output: t1.c1, (avg((t1.c1 + t2.c1))) ! Sort Key: t1.c1 ! -> HashAggregate ! Output: t1.c1, avg((t1.c1 + t2.c1)) ! Group Key: t1.c1 ! -> HashAggregate ! Output: t1.c1, t2.c1 ! Group Key: t1.c1, t2.c1 ! -> Append ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ! -> Foreign Scan ! Output: t1_1.c1, t2_1.c1 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) ! (20 rows) ! ! SELECT t1c1, avg(t1c1 + t2c1) FROM (SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1) UNION SELECT t1.c1, t2.c1 FROM ft1 t1 JOIN ft2 t2 ON (t1.c1 = t2.c1)) AS t (t1c1, t2c1) GROUP BY t1c1 ORDER BY t1c1 OFFSET 100 LIMIT 10; ! t1c1 | avg ! ------+---------------------- ! 101 | 202.0000000000000000 ! 102 | 204.0000000000000000 ! 103 | 206.0000000000000000 ! 104 | 208.0000000000000000 ! 105 | 210.0000000000000000 ! 106 | 212.0000000000000000 ! 107 | 214.0000000000000000 ! 108 | 216.0000000000000000 ! 109 | 218.0000000000000000 ! 110 | 220.0000000000000000 ! (10 rows) ! ! -- join with lateral reference ! EXPLAIN (COSTS false, VERBOSE) ! SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1."C 1" ! -> Nested Loop ! Output: t1."C 1" ! -> Index Scan using t1_pkey on "S 1"."T 1" t1 ! Output: t1."C 1", t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! -> HashAggregate ! Output: t2.c1, t3.c1 ! Group Key: t2.c1, t3.c1 ! -> Foreign Scan ! Output: t2.c1, t3.c1 ! Relations: (public.ft1 t2) INNER JOIN (public.ft2 t3) ! Remote SQL: SELECT r1."C 1", r2."C 1" FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1."C 1" = r2."C 1")) AND ((r1.c2 = $1::integer)) ! (13 rows) ! ! SELECT t1."C 1" FROM "S 1"."T 1" t1, LATERAL (SELECT DISTINCT t2.c1, t3.c1 FROM ft1 t2, ft2 t3 WHERE t2.c1 = t3.c1 AND t2.c2 = t1.c2) q ORDER BY t1."C 1" OFFSET 10 LIMIT 10; ! C 1 ! ----- ! 1 ! 1 ! 1 ! 1 ! 1 ! 1 ! 1 ! 1 ! 1 ! 1 ! (10 rows) ! ! -- create another user for permission, user mapping, effective user tests ! CREATE USER view_owner; ! -- grant privileges on ft4 and ft5 to view_owner ! GRANT ALL ON ft4 TO view_owner; ! GRANT ALL ON ft5 TO view_owner; ! -- prepare statement with current session user ! PREPARE join_stmt AS SELECT t1.c1, t2.c1 FROM ft4 t1 LEFT JOIN ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 10 LIMIT 10; ! EXPLAIN (COSTS OFF, VERBOSE) EXECUTE join_stmt; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, t2.c1 ! -> Foreign Scan ! Output: t1.c1, t2.c1 ! Relations: (public.ft4 t1) LEFT JOIN (public.ft5 t2) ! Remote SQL: SELECT r1.c1, r2.c1 FROM ("S 1"."T 3" r1 LEFT JOIN "S 1"."T 4" r2 ON (((r1.c1 = r2.c1)))) ORDER BY r1.c1 ASC NULLS LAST, r2.c1 ASC NULLS LAST ! (6 rows) ! ! EXECUTE join_stmt; ! c1 | c1 ! ----+---- ! 22 | ! 24 | 24 ! 26 | ! 28 | ! 30 | 30 ! 32 | ! 34 | ! 36 | 36 ! 38 | ! 40 | ! (10 rows) ! ! -- change the session user to view_owner and execute the statement. Because of ! -- change in session user, the plan should get invalidated and created again. ! -- While creating the plan, it should throw error since there is no user mapping ! -- available for view_owner. ! SET SESSION ROLE view_owner; ! EXPLAIN (COSTS OFF, VERBOSE) EXECUTE join_stmt; ! ERROR: user mapping not found for "view_owner" ! EXECUTE join_stmt; ! ERROR: user mapping not found for "view_owner" ! RESET ROLE; ! DEALLOCATE join_stmt; ! CREATE VIEW v_ft5 AS SELECT * FROM ft5; ! -- change owner of v_ft5 to view_owner so that the effective user for scan on ! -- ft5 is view_owner and not the current user. ! ALTER VIEW v_ft5 OWNER TO view_owner; ! -- create a public user mapping for loopback server ! -- drop user mapping for current_user. ! DROP USER MAPPING FOR CURRENT_USER SERVER loopback; ! CREATE USER MAPPING FOR PUBLIC SERVER loopback; ! -- different effective user for permission check, but same user mapping for the ! -- joining sides, join pushed down, no result expected. ! PREPARE join_stmt AS SELECT t1.c1, t2.c1 FROM ft5 t1 JOIN v_ft5 t2 ON (t1.c1 = t2.c1) ORDER BY t1.c1, t2.c1 OFFSET 100 LIMIT 10; ! EXPLAIN (COSTS false, VERBOSE) EXECUTE join_stmt; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, ft5.c1 ! -> Foreign Scan ! Output: t1.c1, ft5.c1 ! Relations: (public.ft5 t1) INNER JOIN (public.ft5) ! Remote SQL: SELECT r1.c1, r6.c1 FROM ("S 1"."T 4" r1 INNER JOIN "S 1"."T 4" r6 ON (TRUE)) WHERE ((r1.c1 = r6.c1)) ORDER BY r1.c1 ASC NULLS LAST ! (6 rows) ! ! EXECUTE join_stmt; ! c1 | c1 ! ----+---- ! (0 rows) ! ! -- create user mapping for view_owner and execute the prepared statement ! -- the join should not be pushed down since joining relations now use two ! -- different user mappings ! CREATE USER MAPPING FOR view_owner SERVER loopback; ! EXPLAIN (COSTS false, VERBOSE) EXECUTE join_stmt; ! QUERY PLAN ! --------------------------------------------------------------------------------------- ! Limit ! Output: t1.c1, ft5.c1 ! -> Merge Join ! Output: t1.c1, ft5.c1 ! Merge Cond: (t1.c1 = ft5.c1) ! -> Foreign Scan on public.ft5 t1 ! Output: t1.c1, t1.c2, t1.c3 ! Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST ! -> Materialize ! Output: ft5.c1, ft5.c2, ft5.c3 ! -> Foreign Scan on public.ft5 ! Output: ft5.c1, ft5.c2, ft5.c3 ! Remote SQL: SELECT c1 FROM "S 1"."T 4" ORDER BY c1 ASC NULLS LAST ! (13 rows) ! ! EXECUTE join_stmt; ! c1 | c1 ! ----+---- ! (0 rows) ! ! -- recreate the dropped user mapping for further tests ! CREATE USER MAPPING FOR CURRENT_USER SERVER loopback; ! DROP USER MAPPING FOR PUBLIC SERVER loopback; ! -- =================================================================== ! -- parameterized queries ! -- =================================================================== ! -- simple join ! PREPARE st1(int, int) AS SELECT t1.c3, t2.c3 FROM ft1 t1, ft2 t2 WHERE t1.c1 = $1 AND t2.c1 = $2; ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st1(1, 2); ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------------------------- ! Foreign Scan ! Output: t1.c3, t2.c3 ! Relations: (public.ft1 t1) INNER JOIN (public.ft2 t2) ! Remote SQL: SELECT r1.c3, r2.c3 FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r2."C 1" = 2)) AND ((r1."C 1" = 1)) ! (4 rows) ! ! EXECUTE st1(1, 1); ! c3 | c3 ! -------+------- ! 00001 | 00001 ! (1 row) ! ! EXECUTE st1(101, 101); ! c3 | c3 ! -------+------- ! 00101 | 00101 ! (1 row) ! ! -- subquery using stable function (can't be sent to remote) ! PREPARE st2(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c4) = '1970-01-17'::date) ORDER BY c1; ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st2(10, 20); ! QUERY PLAN ! ---------------------------------------------------------------------------------------------------------- ! Sort ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Sort Key: t1.c1 ! -> Nested Loop Semi Join ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Join Filter: (t1.c3 = t2.c3) ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 20)) ! -> Materialize ! Output: t2.c3 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c3 ! Filter: (date(t2.c4) = '01-17-1970'::date) ! Remote SQL: SELECT c3, c4 FROM "S 1"."T 1" WHERE (("C 1" > 10)) ! (15 rows) ! ! EXECUTE st2(10, 20); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! (1 row) ! ! EXECUTE st2(101, 121); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -----+----+-------+------------------------------+--------------------------+----+------------+----- ! 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! (1 row) ! ! -- subquery using immutable function (can be sent to remote) ! PREPARE st3(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 < $2 AND t1.c3 IN (SELECT c3 FROM ft2 t2 WHERE c1 > $1 AND date(c5) = '1970-01-17'::date) ORDER BY c1; ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st3(10, 20); ! QUERY PLAN ! ----------------------------------------------------------------------------------------------------------------------- ! Sort ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Sort Key: t1.c1 ! -> Nested Loop Semi Join ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Join Filter: (t1.c3 = t2.c3) ! -> Foreign Scan on public.ft1 t1 ! Output: t1.c1, t1.c2, t1.c3, t1.c4, t1.c5, t1.c6, t1.c7, t1.c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" < 20)) ! -> Materialize ! Output: t2.c3 ! -> Foreign Scan on public.ft2 t2 ! Output: t2.c3 ! Remote SQL: SELECT c3 FROM "S 1"."T 1" WHERE (("C 1" > 10)) AND ((date(c5) = '1970-01-17'::date)) ! (14 rows) ! ! EXECUTE st3(10, 20); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST | Sat Jan 17 00:00:00 1970 | 6 | 6 | foo ! (1 row) ! ! EXECUTE st3(20, 30); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+----+----+----+----+----+---- ! (0 rows) ! ! -- custom plan should be chosen initially ! PREPARE st4(int) AS SELECT * FROM ft1 t1 WHERE t1.c1 = $1; ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (3 rows) ! ! -- once we try it enough times, should switch to generic plan ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st4(1); ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = $1::integer)) ! (3 rows) ! ! -- value of $1 should not be sent to remote ! PREPARE st5(user_enum,int) AS SELECT * FROM ft1 t1 WHERE c8 = $1 and c1 = $2; ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (4 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (4 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (4 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (4 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = 'foo'::user_enum) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = 1)) ! (4 rows) ! ! EXPLAIN (VERBOSE, COSTS false) EXECUTE st5('foo', 1); ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.c8 = $1) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (("C 1" = $1::integer)) ! (4 rows) ! ! EXECUTE st5('foo', 1); ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! -- cleanup ! DEALLOCATE st1; ! DEALLOCATE st2; ! DEALLOCATE st3; ! DEALLOCATE st4; ! DEALLOCATE st5; ! -- System columns, except ctid, should not be sent to remote ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM ft1 t1 WHERE t1.tableoid = 'pg_class'::regclass LIMIT 1; ! QUERY PLAN ! ------------------------------------------------------------------------------- ! Limit ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Filter: (t1.tableoid = '1259'::oid) ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (6 rows) ! ! SELECT * FROM ft1 t1 WHERE t1.tableoid = 'ft1'::regclass LIMIT 1; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; ! QUERY PLAN ! ------------------------------------------------------------------------------- ! Limit ! Output: ((tableoid)::regclass), c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 t1 ! Output: (tableoid)::regclass, c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ! (5 rows) ! ! SELECT tableoid::regclass, * FROM ft1 t1 LIMIT 1; ! tableoid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----------+----+----+-------+------------------------------+--------------------------+----+------------+----- ! ft1 | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------- ! Foreign Scan on public.ft1 t1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((ctid = '(0,2)'::tid)) ! (3 rows) ! ! SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)'; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! (1 row) ! ! EXPLAIN (VERBOSE, COSTS false) ! SELECT ctid, * FROM ft1 t1 LIMIT 1; ! QUERY PLAN ! ------------------------------------------------------------------------------------- ! Limit ! Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 t1 ! Output: ctid, c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" ! (5 rows) ! ! SELECT ctid, * FROM ft1 t1 LIMIT 1; ! ctid | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! -------+----+----+-------+------------------------------+--------------------------+----+------------+----- ! (0,1) | 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! -- =================================================================== ! -- used in pl/pgsql function ! -- =================================================================== ! CREATE OR REPLACE FUNCTION f_test(p_c1 int) RETURNS int AS $$ ! DECLARE ! v_c1 int; ! BEGIN ! SELECT c1 INTO v_c1 FROM ft1 WHERE c1 = p_c1 LIMIT 1; ! PERFORM c1 FROM ft1 WHERE c1 = p_c1 AND p_c1 = v_c1 LIMIT 1; ! RETURN v_c1; ! END; ! $$ LANGUAGE plpgsql; ! SELECT f_test(100); ! f_test ! -------- ! 100 ! (1 row) ! ! DROP FUNCTION f_test(int); ! -- =================================================================== ! -- conversion error ! -- =================================================================== ! ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE int; ! SELECT * FROM ft1 WHERE c1 = 1; -- ERROR ! ERROR: invalid input syntax for integer: "foo" ! CONTEXT: column "c8" of foreign table "ft1" ! SELECT ft1.c1, ft2.c2, ft1.c8 FROM ft1, ft2 WHERE ft1.c1 = ft2.c1 AND ft1.c1 = 1; -- ERROR ! ERROR: invalid input syntax for integer: "foo" ! CONTEXT: column "c8" of foreign table "ft1" ! ALTER FOREIGN TABLE ft1 ALTER COLUMN c8 TYPE user_enum; ! -- =================================================================== ! -- subtransaction ! -- + local/remote error doesn't break cursor ! -- =================================================================== ! BEGIN; ! DECLARE c CURSOR FOR SELECT * FROM ft1 ORDER BY c1; ! FETCH c; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! SAVEPOINT s; ! ERROR OUT; -- ERROR ! ERROR: syntax error at or near "ERROR" ! LINE 1: ERROR OUT; ! ^ ! ROLLBACK TO s; ! FETCH c; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 2 | 2 | 00002 | Sat Jan 03 00:00:00 1970 PST | Sat Jan 03 00:00:00 1970 | 2 | 2 | foo ! (1 row) ! ! SAVEPOINT s; ! SELECT * FROM ft1 WHERE 1 / (c1 - 1) > 0; -- ERROR ! ERROR: division by zero ! CONTEXT: Remote SQL command: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE (((1 / ("C 1" - 1)) > 0)) ! ROLLBACK TO s; ! FETCH c; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 3 | 3 | 00003 | Sun Jan 04 00:00:00 1970 PST | Sun Jan 04 00:00:00 1970 | 3 | 3 | foo ! (1 row) ! ! SELECT * FROM ft1 ORDER BY c1 LIMIT 1; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ----+----+-------+------------------------------+--------------------------+----+------------+----- ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1 | 1 | foo ! (1 row) ! ! COMMIT; ! -- =================================================================== ! -- test handling of collations ! -- =================================================================== ! create table loct3 (f1 text collate "C" unique, f2 text, f3 varchar(10) unique); ! create foreign table ft3 (f1 text collate "C", f2 text, f3 varchar(10)) ! server loopback options (table_name 'loct3', use_remote_estimate 'true'); ! -- can be sent to remote ! explain (verbose, costs off) select * from ft3 where f1 = 'foo'; ! QUERY PLAN ! ------------------------------------------------------------------------------ ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text)) ! (3 rows) ! ! explain (verbose, costs off) select * from ft3 where f1 COLLATE "C" = 'foo'; ! QUERY PLAN ! ------------------------------------------------------------------------------ ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f1 = 'foo'::text)) ! (3 rows) ! ! explain (verbose, costs off) select * from ft3 where f2 = 'foo'; ! QUERY PLAN ! ------------------------------------------------------------------------------ ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f2 = 'foo'::text)) ! (3 rows) ! ! explain (verbose, costs off) select * from ft3 where f3 = 'foo'; ! QUERY PLAN ! ------------------------------------------------------------------------------ ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE ((f3 = 'foo'::text)) ! (3 rows) ! ! explain (verbose, costs off) select * from ft3 f, loct3 l ! where f.f3 = l.f3 and l.f1 = 'foo'; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------- ! Nested Loop ! Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 ! -> Index Scan using loct3_f1_key on public.loct3 l ! Output: l.f1, l.f2, l.f3 ! Index Cond: (l.f1 = 'foo'::text) ! -> Foreign Scan on public.ft3 f ! Output: f.f1, f.f2, f.f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 WHERE (($1::character varying(10) = f3)) ! (8 rows) ! ! -- can't be sent to remote ! explain (verbose, costs off) select * from ft3 where f1 COLLATE "POSIX" = 'foo'; ! QUERY PLAN ! --------------------------------------------------- ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Filter: ((ft3.f1)::text = 'foo'::text) ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 ! (4 rows) ! ! explain (verbose, costs off) select * from ft3 where f1 = 'foo' COLLATE "C"; ! QUERY PLAN ! --------------------------------------------------- ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Filter: (ft3.f1 = 'foo'::text COLLATE "C") ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 ! (4 rows) ! ! explain (verbose, costs off) select * from ft3 where f2 COLLATE "C" = 'foo'; ! QUERY PLAN ! --------------------------------------------------- ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Filter: ((ft3.f2)::text = 'foo'::text) ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 ! (4 rows) ! ! explain (verbose, costs off) select * from ft3 where f2 = 'foo' COLLATE "C"; ! QUERY PLAN ! --------------------------------------------------- ! Foreign Scan on public.ft3 ! Output: f1, f2, f3 ! Filter: (ft3.f2 = 'foo'::text COLLATE "C") ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 ! (4 rows) ! ! explain (verbose, costs off) select * from ft3 f, loct3 l ! where f.f3 = l.f3 COLLATE "POSIX" and l.f1 = 'foo'; ! QUERY PLAN ! ------------------------------------------------------------- ! Hash Join ! Output: f.f1, f.f2, f.f3, l.f1, l.f2, l.f3 ! Hash Cond: ((f.f3)::text = (l.f3)::text) ! -> Foreign Scan on public.ft3 f ! Output: f.f1, f.f2, f.f3 ! Remote SQL: SELECT f1, f2, f3 FROM public.loct3 ! -> Hash ! Output: l.f1, l.f2, l.f3 ! -> Index Scan using loct3_f1_key on public.loct3 l ! Output: l.f1, l.f2, l.f3 ! Index Cond: (l.f1 = 'foo'::text) ! (11 rows) ! ! -- =================================================================== ! -- test writable foreign table stuff ! -- =================================================================== ! EXPLAIN (verbose, costs off) ! INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Insert on public.ft2 ! Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ! -> Subquery Scan on "*SELECT*" ! Output: "*SELECT*"."?column?", "*SELECT*"."?column?_1", NULL::integer, "*SELECT*"."?column?_2", NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum ! -> Limit ! Output: ((ft2_1.c1 + 1000)), ((ft2_1.c2 + 100)), ((ft2_1.c3 || ft2_1.c3)) ! -> Foreign Scan on public.ft2 ft2_1 ! Output: (ft2_1.c1 + 1000), (ft2_1.c2 + 100), (ft2_1.c3 || ft2_1.c3) ! Remote SQL: SELECT "C 1", c2, c3 FROM "S 1"."T 1" ! (9 rows) ! ! INSERT INTO ft2 (c1,c2,c3) SELECT c1+1000,c2+100, c3 || c3 FROM ft2 LIMIT 20; ! INSERT INTO ft2 (c1,c2,c3) ! VALUES (1101,201,'aaa'), (1102,202,'bbb'), (1103,203,'ccc') RETURNING *; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+-----+----+----+----+------------+---- ! 1101 | 201 | aaa | | | | ft2 | ! 1102 | 202 | bbb | | | | ft2 | ! 1103 | 203 | ccc | | | | ft2 | ! (3 rows) ! ! INSERT INTO ft2 (c1,c2,c3) VALUES (1104,204,'ddd'), (1105,205,'eee'); ! UPDATE ft2 SET c2 = c2 + 300, c3 = c3 || '_update3' WHERE c1 % 10 = 3; ! UPDATE ft2 SET c2 = c2 + 400, c3 = c3 || '_update7' WHERE c1 % 10 = 7 RETURNING *; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+--------------------+------------------------------+--------------------------+----+------------+----- ! 7 | 407 | 00007_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 17 | 407 | 00017_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 27 | 407 | 00027_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 37 | 407 | 00037_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 47 | 407 | 00047_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 57 | 407 | 00057_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 67 | 407 | 00067_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 77 | 407 | 00077_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 87 | 407 | 00087_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 97 | 407 | 00097_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 107 | 407 | 00107_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 117 | 407 | 00117_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 127 | 407 | 00127_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 137 | 407 | 00137_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 147 | 407 | 00147_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 157 | 407 | 00157_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 167 | 407 | 00167_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 177 | 407 | 00177_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 187 | 407 | 00187_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 197 | 407 | 00197_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 207 | 407 | 00207_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 217 | 407 | 00217_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 227 | 407 | 00227_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 237 | 407 | 00237_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 247 | 407 | 00247_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 257 | 407 | 00257_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 267 | 407 | 00267_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 277 | 407 | 00277_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 287 | 407 | 00287_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 297 | 407 | 00297_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 307 | 407 | 00307_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 317 | 407 | 00317_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 327 | 407 | 00327_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 337 | 407 | 00337_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 347 | 407 | 00347_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 357 | 407 | 00357_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 367 | 407 | 00367_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 377 | 407 | 00377_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 387 | 407 | 00387_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 397 | 407 | 00397_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 407 | 407 | 00407_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 417 | 407 | 00417_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 427 | 407 | 00427_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 437 | 407 | 00437_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 447 | 407 | 00447_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 457 | 407 | 00457_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 467 | 407 | 00467_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 477 | 407 | 00477_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 487 | 407 | 00487_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 497 | 407 | 00497_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 507 | 407 | 00507_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 517 | 407 | 00517_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 527 | 407 | 00527_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 537 | 407 | 00537_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 547 | 407 | 00547_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 557 | 407 | 00557_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 567 | 407 | 00567_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 577 | 407 | 00577_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 587 | 407 | 00587_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 597 | 407 | 00597_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 607 | 407 | 00607_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 617 | 407 | 00617_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 627 | 407 | 00627_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 637 | 407 | 00637_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 647 | 407 | 00647_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 657 | 407 | 00657_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 667 | 407 | 00667_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 677 | 407 | 00677_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 687 | 407 | 00687_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 697 | 407 | 00697_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 707 | 407 | 00707_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 717 | 407 | 00717_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 727 | 407 | 00727_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 737 | 407 | 00737_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 747 | 407 | 00747_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 757 | 407 | 00757_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 767 | 407 | 00767_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 777 | 407 | 00777_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 787 | 407 | 00787_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 797 | 407 | 00797_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 807 | 407 | 00807_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 817 | 407 | 00817_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 827 | 407 | 00827_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 837 | 407 | 00837_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 847 | 407 | 00847_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 857 | 407 | 00857_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 867 | 407 | 00867_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 877 | 407 | 00877_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 887 | 407 | 00887_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 897 | 407 | 00897_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 907 | 407 | 00907_update7 | Thu Jan 08 00:00:00 1970 PST | Thu Jan 08 00:00:00 1970 | 7 | 7 | foo ! 917 | 407 | 00917_update7 | Sun Jan 18 00:00:00 1970 PST | Sun Jan 18 00:00:00 1970 | 7 | 7 | foo ! 927 | 407 | 00927_update7 | Wed Jan 28 00:00:00 1970 PST | Wed Jan 28 00:00:00 1970 | 7 | 7 | foo ! 937 | 407 | 00937_update7 | Sat Feb 07 00:00:00 1970 PST | Sat Feb 07 00:00:00 1970 | 7 | 7 | foo ! 947 | 407 | 00947_update7 | Tue Feb 17 00:00:00 1970 PST | Tue Feb 17 00:00:00 1970 | 7 | 7 | foo ! 957 | 407 | 00957_update7 | Fri Feb 27 00:00:00 1970 PST | Fri Feb 27 00:00:00 1970 | 7 | 7 | foo ! 967 | 407 | 00967_update7 | Mon Mar 09 00:00:00 1970 PST | Mon Mar 09 00:00:00 1970 | 7 | 7 | foo ! 977 | 407 | 00977_update7 | Thu Mar 19 00:00:00 1970 PST | Thu Mar 19 00:00:00 1970 | 7 | 7 | foo ! 987 | 407 | 00987_update7 | Sun Mar 29 00:00:00 1970 PST | Sun Mar 29 00:00:00 1970 | 7 | 7 | foo ! 997 | 407 | 00997_update7 | Wed Apr 08 00:00:00 1970 PST | Wed Apr 08 00:00:00 1970 | 7 | 7 | foo ! 1007 | 507 | 0000700007_update7 | | | | ft2 | ! 1017 | 507 | 0001700017_update7 | | | | ft2 | ! (102 rows) ! ! EXPLAIN (verbose, costs off) ! UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT ! FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ! Update on public.ft2 ! Remote SQL: UPDATE "S 1"."T 1" SET c2 = $2, c3 = $3, c7 = $4 WHERE ctid = $1 ! -> Foreign Scan ! Output: ft2.c1, (ft2.c2 + 500), NULL::integer, (ft2.c3 || '_update9'::text), ft2.c4, ft2.c5, ft2.c6, 'ft2 '::character(10), ft2.c8, ft2.ctid, ft1.* ! Relations: (public.ft2) INNER JOIN (public.ft1) ! Remote SQL: SELECT r1."C 1", r1.c2, r1.c3, r1.c4, r1.c5, r1.c6, r1.c8, r1.ctid, ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1.c2 = r2."C 1")) AND (((r2."C 1" % 10) = 9)) FOR UPDATE OF r1 ! -> Hash Join ! Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c8, ft2.ctid, ft1.* ! Hash Cond: (ft2.c2 = ft1.c1) ! -> Foreign Scan on public.ft2 ! Output: ft2.c1, ft2.c2, ft2.c3, ft2.c4, ft2.c5, ft2.c6, ft2.c8, ft2.ctid ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c8, ctid FROM "S 1"."T 1" FOR UPDATE ! -> Hash ! Output: ft1.*, ft1.c1 ! -> Foreign Scan on public.ft1 ! Output: ft1.*, ft1.c1 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 9)) ! (17 rows) ! ! UPDATE ft2 SET c2 = ft2.c2 + 500, c3 = ft2.c3 || '_update9', c7 = DEFAULT ! FROM ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 9; ! EXPLAIN (verbose, costs off) ! DELETE FROM ft2 WHERE c1 % 10 = 5 RETURNING c1, c4; ! QUERY PLAN ! ---------------------------------------------------------------------------------------- ! Delete on public.ft2 ! Output: c1, c4 ! Remote SQL: DELETE FROM "S 1"."T 1" WHERE ctid = $1 RETURNING "C 1", c4 ! -> Foreign Scan on public.ft2 ! Output: ctid ! Remote SQL: SELECT ctid FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 5)) FOR UPDATE ! (6 rows) ! ! DELETE FROM ft2 WHERE c1 % 10 = 5 RETURNING c1, c4; ! c1 | c4 ! ------+------------------------------ ! 5 | Tue Jan 06 00:00:00 1970 PST ! 15 | Fri Jan 16 00:00:00 1970 PST ! 25 | Mon Jan 26 00:00:00 1970 PST ! 35 | Thu Feb 05 00:00:00 1970 PST ! 45 | Sun Feb 15 00:00:00 1970 PST ! 55 | Wed Feb 25 00:00:00 1970 PST ! 65 | Sat Mar 07 00:00:00 1970 PST ! 75 | Tue Mar 17 00:00:00 1970 PST ! 85 | Fri Mar 27 00:00:00 1970 PST ! 95 | Mon Apr 06 00:00:00 1970 PST ! 105 | Tue Jan 06 00:00:00 1970 PST ! 115 | Fri Jan 16 00:00:00 1970 PST ! 125 | Mon Jan 26 00:00:00 1970 PST ! 135 | Thu Feb 05 00:00:00 1970 PST ! 145 | Sun Feb 15 00:00:00 1970 PST ! 155 | Wed Feb 25 00:00:00 1970 PST ! 165 | Sat Mar 07 00:00:00 1970 PST ! 175 | Tue Mar 17 00:00:00 1970 PST ! 185 | Fri Mar 27 00:00:00 1970 PST ! 195 | Mon Apr 06 00:00:00 1970 PST ! 205 | Tue Jan 06 00:00:00 1970 PST ! 215 | Fri Jan 16 00:00:00 1970 PST ! 225 | Mon Jan 26 00:00:00 1970 PST ! 235 | Thu Feb 05 00:00:00 1970 PST ! 245 | Sun Feb 15 00:00:00 1970 PST ! 255 | Wed Feb 25 00:00:00 1970 PST ! 265 | Sat Mar 07 00:00:00 1970 PST ! 275 | Tue Mar 17 00:00:00 1970 PST ! 285 | Fri Mar 27 00:00:00 1970 PST ! 295 | Mon Apr 06 00:00:00 1970 PST ! 305 | Tue Jan 06 00:00:00 1970 PST ! 315 | Fri Jan 16 00:00:00 1970 PST ! 325 | Mon Jan 26 00:00:00 1970 PST ! 335 | Thu Feb 05 00:00:00 1970 PST ! 345 | Sun Feb 15 00:00:00 1970 PST ! 355 | Wed Feb 25 00:00:00 1970 PST ! 365 | Sat Mar 07 00:00:00 1970 PST ! 375 | Tue Mar 17 00:00:00 1970 PST ! 385 | Fri Mar 27 00:00:00 1970 PST ! 395 | Mon Apr 06 00:00:00 1970 PST ! 405 | Tue Jan 06 00:00:00 1970 PST ! 415 | Fri Jan 16 00:00:00 1970 PST ! 425 | Mon Jan 26 00:00:00 1970 PST ! 435 | Thu Feb 05 00:00:00 1970 PST ! 445 | Sun Feb 15 00:00:00 1970 PST ! 455 | Wed Feb 25 00:00:00 1970 PST ! 465 | Sat Mar 07 00:00:00 1970 PST ! 475 | Tue Mar 17 00:00:00 1970 PST ! 485 | Fri Mar 27 00:00:00 1970 PST ! 495 | Mon Apr 06 00:00:00 1970 PST ! 505 | Tue Jan 06 00:00:00 1970 PST ! 515 | Fri Jan 16 00:00:00 1970 PST ! 525 | Mon Jan 26 00:00:00 1970 PST ! 535 | Thu Feb 05 00:00:00 1970 PST ! 545 | Sun Feb 15 00:00:00 1970 PST ! 555 | Wed Feb 25 00:00:00 1970 PST ! 565 | Sat Mar 07 00:00:00 1970 PST ! 575 | Tue Mar 17 00:00:00 1970 PST ! 585 | Fri Mar 27 00:00:00 1970 PST ! 595 | Mon Apr 06 00:00:00 1970 PST ! 605 | Tue Jan 06 00:00:00 1970 PST ! 615 | Fri Jan 16 00:00:00 1970 PST ! 625 | Mon Jan 26 00:00:00 1970 PST ! 635 | Thu Feb 05 00:00:00 1970 PST ! 645 | Sun Feb 15 00:00:00 1970 PST ! 655 | Wed Feb 25 00:00:00 1970 PST ! 665 | Sat Mar 07 00:00:00 1970 PST ! 675 | Tue Mar 17 00:00:00 1970 PST ! 685 | Fri Mar 27 00:00:00 1970 PST ! 695 | Mon Apr 06 00:00:00 1970 PST ! 705 | Tue Jan 06 00:00:00 1970 PST ! 715 | Fri Jan 16 00:00:00 1970 PST ! 725 | Mon Jan 26 00:00:00 1970 PST ! 735 | Thu Feb 05 00:00:00 1970 PST ! 745 | Sun Feb 15 00:00:00 1970 PST ! 755 | Wed Feb 25 00:00:00 1970 PST ! 765 | Sat Mar 07 00:00:00 1970 PST ! 775 | Tue Mar 17 00:00:00 1970 PST ! 785 | Fri Mar 27 00:00:00 1970 PST ! 795 | Mon Apr 06 00:00:00 1970 PST ! 805 | Tue Jan 06 00:00:00 1970 PST ! 815 | Fri Jan 16 00:00:00 1970 PST ! 825 | Mon Jan 26 00:00:00 1970 PST ! 835 | Thu Feb 05 00:00:00 1970 PST ! 845 | Sun Feb 15 00:00:00 1970 PST ! 855 | Wed Feb 25 00:00:00 1970 PST ! 865 | Sat Mar 07 00:00:00 1970 PST ! 875 | Tue Mar 17 00:00:00 1970 PST ! 885 | Fri Mar 27 00:00:00 1970 PST ! 895 | Mon Apr 06 00:00:00 1970 PST ! 905 | Tue Jan 06 00:00:00 1970 PST ! 915 | Fri Jan 16 00:00:00 1970 PST ! 925 | Mon Jan 26 00:00:00 1970 PST ! 935 | Thu Feb 05 00:00:00 1970 PST ! 945 | Sun Feb 15 00:00:00 1970 PST ! 955 | Wed Feb 25 00:00:00 1970 PST ! 965 | Sat Mar 07 00:00:00 1970 PST ! 975 | Tue Mar 17 00:00:00 1970 PST ! 985 | Fri Mar 27 00:00:00 1970 PST ! 995 | Mon Apr 06 00:00:00 1970 PST ! 1005 | ! 1015 | ! 1105 | ! (103 rows) ! ! EXPLAIN (verbose, costs off) ! DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Delete on public.ft2 ! Remote SQL: DELETE FROM "S 1"."T 1" WHERE ctid = $1 ! -> Foreign Scan ! Output: ft2.ctid, ft1.* ! Relations: (public.ft2) INNER JOIN (public.ft1) ! Remote SQL: SELECT r1.ctid, ROW(r2."C 1", r2.c2, r2.c3, r2.c4, r2.c5, r2.c6, r2.c7, r2.c8) FROM ("S 1"."T 1" r1 INNER JOIN "S 1"."T 1" r2 ON (TRUE)) WHERE ((r1.c2 = r2."C 1")) AND (((r2."C 1" % 10) = 2)) FOR UPDATE OF r1 ! -> Hash Join ! Output: ft2.ctid, ft1.* ! Hash Cond: (ft2.c2 = ft1.c1) ! -> Foreign Scan on public.ft2 ! Output: ft2.ctid, ft2.c2 ! Remote SQL: SELECT c2, ctid FROM "S 1"."T 1" FOR UPDATE ! -> Hash ! Output: ft1.*, ft1.c1 ! -> Foreign Scan on public.ft1 ! Output: ft1.*, ft1.c1 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" WHERE ((("C 1" % 10) = 2)) ! (17 rows) ! ! DELETE FROM ft2 USING ft1 WHERE ft1.c1 = ft2.c2 AND ft1.c1 % 10 = 2; ! SELECT c1,c2,c3,c4 FROM ft2 ORDER BY c1; ! c1 | c2 | c3 | c4 ! ------+-----+--------------------+------------------------------ ! 1 | 1 | 00001 | Fri Jan 02 00:00:00 1970 PST ! 3 | 303 | 00003_update3 | Sun Jan 04 00:00:00 1970 PST ! 4 | 4 | 00004 | Mon Jan 05 00:00:00 1970 PST ! 6 | 6 | 00006 | Wed Jan 07 00:00:00 1970 PST ! 7 | 407 | 00007_update7 | Thu Jan 08 00:00:00 1970 PST ! 8 | 8 | 00008 | Fri Jan 09 00:00:00 1970 PST ! 9 | 509 | 00009_update9 | Sat Jan 10 00:00:00 1970 PST ! 10 | 0 | 00010 | Sun Jan 11 00:00:00 1970 PST ! 11 | 1 | 00011 | Mon Jan 12 00:00:00 1970 PST ! 13 | 303 | 00013_update3 | Wed Jan 14 00:00:00 1970 PST ! 14 | 4 | 00014 | Thu Jan 15 00:00:00 1970 PST ! 16 | 6 | 00016 | Sat Jan 17 00:00:00 1970 PST ! 17 | 407 | 00017_update7 | Sun Jan 18 00:00:00 1970 PST ! 18 | 8 | 00018 | Mon Jan 19 00:00:00 1970 PST ! 19 | 509 | 00019_update9 | Tue Jan 20 00:00:00 1970 PST ! 20 | 0 | 00020 | Wed Jan 21 00:00:00 1970 PST ! 21 | 1 | 00021 | Thu Jan 22 00:00:00 1970 PST ! 23 | 303 | 00023_update3 | Sat Jan 24 00:00:00 1970 PST ! 24 | 4 | 00024 | Sun Jan 25 00:00:00 1970 PST ! 26 | 6 | 00026 | Tue Jan 27 00:00:00 1970 PST ! 27 | 407 | 00027_update7 | Wed Jan 28 00:00:00 1970 PST ! 28 | 8 | 00028 | Thu Jan 29 00:00:00 1970 PST ! 29 | 509 | 00029_update9 | Fri Jan 30 00:00:00 1970 PST ! 30 | 0 | 00030 | Sat Jan 31 00:00:00 1970 PST ! 31 | 1 | 00031 | Sun Feb 01 00:00:00 1970 PST ! 33 | 303 | 00033_update3 | Tue Feb 03 00:00:00 1970 PST ! 34 | 4 | 00034 | Wed Feb 04 00:00:00 1970 PST ! 36 | 6 | 00036 | Fri Feb 06 00:00:00 1970 PST ! 37 | 407 | 00037_update7 | Sat Feb 07 00:00:00 1970 PST ! 38 | 8 | 00038 | Sun Feb 08 00:00:00 1970 PST ! 39 | 509 | 00039_update9 | Mon Feb 09 00:00:00 1970 PST ! 40 | 0 | 00040 | Tue Feb 10 00:00:00 1970 PST ! 41 | 1 | 00041 | Wed Feb 11 00:00:00 1970 PST ! 43 | 303 | 00043_update3 | Fri Feb 13 00:00:00 1970 PST ! 44 | 4 | 00044 | Sat Feb 14 00:00:00 1970 PST ! 46 | 6 | 00046 | Mon Feb 16 00:00:00 1970 PST ! 47 | 407 | 00047_update7 | Tue Feb 17 00:00:00 1970 PST ! 48 | 8 | 00048 | Wed Feb 18 00:00:00 1970 PST ! 49 | 509 | 00049_update9 | Thu Feb 19 00:00:00 1970 PST ! 50 | 0 | 00050 | Fri Feb 20 00:00:00 1970 PST ! 51 | 1 | 00051 | Sat Feb 21 00:00:00 1970 PST ! 53 | 303 | 00053_update3 | Mon Feb 23 00:00:00 1970 PST ! 54 | 4 | 00054 | Tue Feb 24 00:00:00 1970 PST ! 56 | 6 | 00056 | Thu Feb 26 00:00:00 1970 PST ! 57 | 407 | 00057_update7 | Fri Feb 27 00:00:00 1970 PST ! 58 | 8 | 00058 | Sat Feb 28 00:00:00 1970 PST ! 59 | 509 | 00059_update9 | Sun Mar 01 00:00:00 1970 PST ! 60 | 0 | 00060 | Mon Mar 02 00:00:00 1970 PST ! 61 | 1 | 00061 | Tue Mar 03 00:00:00 1970 PST ! 63 | 303 | 00063_update3 | Thu Mar 05 00:00:00 1970 PST ! 64 | 4 | 00064 | Fri Mar 06 00:00:00 1970 PST ! 66 | 6 | 00066 | Sun Mar 08 00:00:00 1970 PST ! 67 | 407 | 00067_update7 | Mon Mar 09 00:00:00 1970 PST ! 68 | 8 | 00068 | Tue Mar 10 00:00:00 1970 PST ! 69 | 509 | 00069_update9 | Wed Mar 11 00:00:00 1970 PST ! 70 | 0 | 00070 | Thu Mar 12 00:00:00 1970 PST ! 71 | 1 | 00071 | Fri Mar 13 00:00:00 1970 PST ! 73 | 303 | 00073_update3 | Sun Mar 15 00:00:00 1970 PST ! 74 | 4 | 00074 | Mon Mar 16 00:00:00 1970 PST ! 76 | 6 | 00076 | Wed Mar 18 00:00:00 1970 PST ! 77 | 407 | 00077_update7 | Thu Mar 19 00:00:00 1970 PST ! 78 | 8 | 00078 | Fri Mar 20 00:00:00 1970 PST ! 79 | 509 | 00079_update9 | Sat Mar 21 00:00:00 1970 PST ! 80 | 0 | 00080 | Sun Mar 22 00:00:00 1970 PST ! 81 | 1 | 00081 | Mon Mar 23 00:00:00 1970 PST ! 83 | 303 | 00083_update3 | Wed Mar 25 00:00:00 1970 PST ! 84 | 4 | 00084 | Thu Mar 26 00:00:00 1970 PST ! 86 | 6 | 00086 | Sat Mar 28 00:00:00 1970 PST ! 87 | 407 | 00087_update7 | Sun Mar 29 00:00:00 1970 PST ! 88 | 8 | 00088 | Mon Mar 30 00:00:00 1970 PST ! 89 | 509 | 00089_update9 | Tue Mar 31 00:00:00 1970 PST ! 90 | 0 | 00090 | Wed Apr 01 00:00:00 1970 PST ! 91 | 1 | 00091 | Thu Apr 02 00:00:00 1970 PST ! 93 | 303 | 00093_update3 | Sat Apr 04 00:00:00 1970 PST ! 94 | 4 | 00094 | Sun Apr 05 00:00:00 1970 PST ! 96 | 6 | 00096 | Tue Apr 07 00:00:00 1970 PST ! 97 | 407 | 00097_update7 | Wed Apr 08 00:00:00 1970 PST ! 98 | 8 | 00098 | Thu Apr 09 00:00:00 1970 PST ! 99 | 509 | 00099_update9 | Fri Apr 10 00:00:00 1970 PST ! 100 | 0 | 00100 | Thu Jan 01 00:00:00 1970 PST ! 101 | 1 | 00101 | Fri Jan 02 00:00:00 1970 PST ! 103 | 303 | 00103_update3 | Sun Jan 04 00:00:00 1970 PST ! 104 | 4 | 00104 | Mon Jan 05 00:00:00 1970 PST ! 106 | 6 | 00106 | Wed Jan 07 00:00:00 1970 PST ! 107 | 407 | 00107_update7 | Thu Jan 08 00:00:00 1970 PST ! 108 | 8 | 00108 | Fri Jan 09 00:00:00 1970 PST ! 109 | 509 | 00109_update9 | Sat Jan 10 00:00:00 1970 PST ! 110 | 0 | 00110 | Sun Jan 11 00:00:00 1970 PST ! 111 | 1 | 00111 | Mon Jan 12 00:00:00 1970 PST ! 113 | 303 | 00113_update3 | Wed Jan 14 00:00:00 1970 PST ! 114 | 4 | 00114 | Thu Jan 15 00:00:00 1970 PST ! 116 | 6 | 00116 | Sat Jan 17 00:00:00 1970 PST ! 117 | 407 | 00117_update7 | Sun Jan 18 00:00:00 1970 PST ! 118 | 8 | 00118 | Mon Jan 19 00:00:00 1970 PST ! 119 | 509 | 00119_update9 | Tue Jan 20 00:00:00 1970 PST ! 120 | 0 | 00120 | Wed Jan 21 00:00:00 1970 PST ! 121 | 1 | 00121 | Thu Jan 22 00:00:00 1970 PST ! 123 | 303 | 00123_update3 | Sat Jan 24 00:00:00 1970 PST ! 124 | 4 | 00124 | Sun Jan 25 00:00:00 1970 PST ! 126 | 6 | 00126 | Tue Jan 27 00:00:00 1970 PST ! 127 | 407 | 00127_update7 | Wed Jan 28 00:00:00 1970 PST ! 128 | 8 | 00128 | Thu Jan 29 00:00:00 1970 PST ! 129 | 509 | 00129_update9 | Fri Jan 30 00:00:00 1970 PST ! 130 | 0 | 00130 | Sat Jan 31 00:00:00 1970 PST ! 131 | 1 | 00131 | Sun Feb 01 00:00:00 1970 PST ! 133 | 303 | 00133_update3 | Tue Feb 03 00:00:00 1970 PST ! 134 | 4 | 00134 | Wed Feb 04 00:00:00 1970 PST ! 136 | 6 | 00136 | Fri Feb 06 00:00:00 1970 PST ! 137 | 407 | 00137_update7 | Sat Feb 07 00:00:00 1970 PST ! 138 | 8 | 00138 | Sun Feb 08 00:00:00 1970 PST ! 139 | 509 | 00139_update9 | Mon Feb 09 00:00:00 1970 PST ! 140 | 0 | 00140 | Tue Feb 10 00:00:00 1970 PST ! 141 | 1 | 00141 | Wed Feb 11 00:00:00 1970 PST ! 143 | 303 | 00143_update3 | Fri Feb 13 00:00:00 1970 PST ! 144 | 4 | 00144 | Sat Feb 14 00:00:00 1970 PST ! 146 | 6 | 00146 | Mon Feb 16 00:00:00 1970 PST ! 147 | 407 | 00147_update7 | Tue Feb 17 00:00:00 1970 PST ! 148 | 8 | 00148 | Wed Feb 18 00:00:00 1970 PST ! 149 | 509 | 00149_update9 | Thu Feb 19 00:00:00 1970 PST ! 150 | 0 | 00150 | Fri Feb 20 00:00:00 1970 PST ! 151 | 1 | 00151 | Sat Feb 21 00:00:00 1970 PST ! 153 | 303 | 00153_update3 | Mon Feb 23 00:00:00 1970 PST ! 154 | 4 | 00154 | Tue Feb 24 00:00:00 1970 PST ! 156 | 6 | 00156 | Thu Feb 26 00:00:00 1970 PST ! 157 | 407 | 00157_update7 | Fri Feb 27 00:00:00 1970 PST ! 158 | 8 | 00158 | Sat Feb 28 00:00:00 1970 PST ! 159 | 509 | 00159_update9 | Sun Mar 01 00:00:00 1970 PST ! 160 | 0 | 00160 | Mon Mar 02 00:00:00 1970 PST ! 161 | 1 | 00161 | Tue Mar 03 00:00:00 1970 PST ! 163 | 303 | 00163_update3 | Thu Mar 05 00:00:00 1970 PST ! 164 | 4 | 00164 | Fri Mar 06 00:00:00 1970 PST ! 166 | 6 | 00166 | Sun Mar 08 00:00:00 1970 PST ! 167 | 407 | 00167_update7 | Mon Mar 09 00:00:00 1970 PST ! 168 | 8 | 00168 | Tue Mar 10 00:00:00 1970 PST ! 169 | 509 | 00169_update9 | Wed Mar 11 00:00:00 1970 PST ! 170 | 0 | 00170 | Thu Mar 12 00:00:00 1970 PST ! 171 | 1 | 00171 | Fri Mar 13 00:00:00 1970 PST ! 173 | 303 | 00173_update3 | Sun Mar 15 00:00:00 1970 PST ! 174 | 4 | 00174 | Mon Mar 16 00:00:00 1970 PST ! 176 | 6 | 00176 | Wed Mar 18 00:00:00 1970 PST ! 177 | 407 | 00177_update7 | Thu Mar 19 00:00:00 1970 PST ! 178 | 8 | 00178 | Fri Mar 20 00:00:00 1970 PST ! 179 | 509 | 00179_update9 | Sat Mar 21 00:00:00 1970 PST ! 180 | 0 | 00180 | Sun Mar 22 00:00:00 1970 PST ! 181 | 1 | 00181 | Mon Mar 23 00:00:00 1970 PST ! 183 | 303 | 00183_update3 | Wed Mar 25 00:00:00 1970 PST ! 184 | 4 | 00184 | Thu Mar 26 00:00:00 1970 PST ! 186 | 6 | 00186 | Sat Mar 28 00:00:00 1970 PST ! 187 | 407 | 00187_update7 | Sun Mar 29 00:00:00 1970 PST ! 188 | 8 | 00188 | Mon Mar 30 00:00:00 1970 PST ! 189 | 509 | 00189_update9 | Tue Mar 31 00:00:00 1970 PST ! 190 | 0 | 00190 | Wed Apr 01 00:00:00 1970 PST ! 191 | 1 | 00191 | Thu Apr 02 00:00:00 1970 PST ! 193 | 303 | 00193_update3 | Sat Apr 04 00:00:00 1970 PST ! 194 | 4 | 00194 | Sun Apr 05 00:00:00 1970 PST ! 196 | 6 | 00196 | Tue Apr 07 00:00:00 1970 PST ! 197 | 407 | 00197_update7 | Wed Apr 08 00:00:00 1970 PST ! 198 | 8 | 00198 | Thu Apr 09 00:00:00 1970 PST ! 199 | 509 | 00199_update9 | Fri Apr 10 00:00:00 1970 PST ! 200 | 0 | 00200 | Thu Jan 01 00:00:00 1970 PST ! 201 | 1 | 00201 | Fri Jan 02 00:00:00 1970 PST ! 203 | 303 | 00203_update3 | Sun Jan 04 00:00:00 1970 PST ! 204 | 4 | 00204 | Mon Jan 05 00:00:00 1970 PST ! 206 | 6 | 00206 | Wed Jan 07 00:00:00 1970 PST ! 207 | 407 | 00207_update7 | Thu Jan 08 00:00:00 1970 PST ! 208 | 8 | 00208 | Fri Jan 09 00:00:00 1970 PST ! 209 | 509 | 00209_update9 | Sat Jan 10 00:00:00 1970 PST ! 210 | 0 | 00210 | Sun Jan 11 00:00:00 1970 PST ! 211 | 1 | 00211 | Mon Jan 12 00:00:00 1970 PST ! 213 | 303 | 00213_update3 | Wed Jan 14 00:00:00 1970 PST ! 214 | 4 | 00214 | Thu Jan 15 00:00:00 1970 PST ! 216 | 6 | 00216 | Sat Jan 17 00:00:00 1970 PST ! 217 | 407 | 00217_update7 | Sun Jan 18 00:00:00 1970 PST ! 218 | 8 | 00218 | Mon Jan 19 00:00:00 1970 PST ! 219 | 509 | 00219_update9 | Tue Jan 20 00:00:00 1970 PST ! 220 | 0 | 00220 | Wed Jan 21 00:00:00 1970 PST ! 221 | 1 | 00221 | Thu Jan 22 00:00:00 1970 PST ! 223 | 303 | 00223_update3 | Sat Jan 24 00:00:00 1970 PST ! 224 | 4 | 00224 | Sun Jan 25 00:00:00 1970 PST ! 226 | 6 | 00226 | Tue Jan 27 00:00:00 1970 PST ! 227 | 407 | 00227_update7 | Wed Jan 28 00:00:00 1970 PST ! 228 | 8 | 00228 | Thu Jan 29 00:00:00 1970 PST ! 229 | 509 | 00229_update9 | Fri Jan 30 00:00:00 1970 PST ! 230 | 0 | 00230 | Sat Jan 31 00:00:00 1970 PST ! 231 | 1 | 00231 | Sun Feb 01 00:00:00 1970 PST ! 233 | 303 | 00233_update3 | Tue Feb 03 00:00:00 1970 PST ! 234 | 4 | 00234 | Wed Feb 04 00:00:00 1970 PST ! 236 | 6 | 00236 | Fri Feb 06 00:00:00 1970 PST ! 237 | 407 | 00237_update7 | Sat Feb 07 00:00:00 1970 PST ! 238 | 8 | 00238 | Sun Feb 08 00:00:00 1970 PST ! 239 | 509 | 00239_update9 | Mon Feb 09 00:00:00 1970 PST ! 240 | 0 | 00240 | Tue Feb 10 00:00:00 1970 PST ! 241 | 1 | 00241 | Wed Feb 11 00:00:00 1970 PST ! 243 | 303 | 00243_update3 | Fri Feb 13 00:00:00 1970 PST ! 244 | 4 | 00244 | Sat Feb 14 00:00:00 1970 PST ! 246 | 6 | 00246 | Mon Feb 16 00:00:00 1970 PST ! 247 | 407 | 00247_update7 | Tue Feb 17 00:00:00 1970 PST ! 248 | 8 | 00248 | Wed Feb 18 00:00:00 1970 PST ! 249 | 509 | 00249_update9 | Thu Feb 19 00:00:00 1970 PST ! 250 | 0 | 00250 | Fri Feb 20 00:00:00 1970 PST ! 251 | 1 | 00251 | Sat Feb 21 00:00:00 1970 PST ! 253 | 303 | 00253_update3 | Mon Feb 23 00:00:00 1970 PST ! 254 | 4 | 00254 | Tue Feb 24 00:00:00 1970 PST ! 256 | 6 | 00256 | Thu Feb 26 00:00:00 1970 PST ! 257 | 407 | 00257_update7 | Fri Feb 27 00:00:00 1970 PST ! 258 | 8 | 00258 | Sat Feb 28 00:00:00 1970 PST ! 259 | 509 | 00259_update9 | Sun Mar 01 00:00:00 1970 PST ! 260 | 0 | 00260 | Mon Mar 02 00:00:00 1970 PST ! 261 | 1 | 00261 | Tue Mar 03 00:00:00 1970 PST ! 263 | 303 | 00263_update3 | Thu Mar 05 00:00:00 1970 PST ! 264 | 4 | 00264 | Fri Mar 06 00:00:00 1970 PST ! 266 | 6 | 00266 | Sun Mar 08 00:00:00 1970 PST ! 267 | 407 | 00267_update7 | Mon Mar 09 00:00:00 1970 PST ! 268 | 8 | 00268 | Tue Mar 10 00:00:00 1970 PST ! 269 | 509 | 00269_update9 | Wed Mar 11 00:00:00 1970 PST ! 270 | 0 | 00270 | Thu Mar 12 00:00:00 1970 PST ! 271 | 1 | 00271 | Fri Mar 13 00:00:00 1970 PST ! 273 | 303 | 00273_update3 | Sun Mar 15 00:00:00 1970 PST ! 274 | 4 | 00274 | Mon Mar 16 00:00:00 1970 PST ! 276 | 6 | 00276 | Wed Mar 18 00:00:00 1970 PST ! 277 | 407 | 00277_update7 | Thu Mar 19 00:00:00 1970 PST ! 278 | 8 | 00278 | Fri Mar 20 00:00:00 1970 PST ! 279 | 509 | 00279_update9 | Sat Mar 21 00:00:00 1970 PST ! 280 | 0 | 00280 | Sun Mar 22 00:00:00 1970 PST ! 281 | 1 | 00281 | Mon Mar 23 00:00:00 1970 PST ! 283 | 303 | 00283_update3 | Wed Mar 25 00:00:00 1970 PST ! 284 | 4 | 00284 | Thu Mar 26 00:00:00 1970 PST ! 286 | 6 | 00286 | Sat Mar 28 00:00:00 1970 PST ! 287 | 407 | 00287_update7 | Sun Mar 29 00:00:00 1970 PST ! 288 | 8 | 00288 | Mon Mar 30 00:00:00 1970 PST ! 289 | 509 | 00289_update9 | Tue Mar 31 00:00:00 1970 PST ! 290 | 0 | 00290 | Wed Apr 01 00:00:00 1970 PST ! 291 | 1 | 00291 | Thu Apr 02 00:00:00 1970 PST ! 293 | 303 | 00293_update3 | Sat Apr 04 00:00:00 1970 PST ! 294 | 4 | 00294 | Sun Apr 05 00:00:00 1970 PST ! 296 | 6 | 00296 | Tue Apr 07 00:00:00 1970 PST ! 297 | 407 | 00297_update7 | Wed Apr 08 00:00:00 1970 PST ! 298 | 8 | 00298 | Thu Apr 09 00:00:00 1970 PST ! 299 | 509 | 00299_update9 | Fri Apr 10 00:00:00 1970 PST ! 300 | 0 | 00300 | Thu Jan 01 00:00:00 1970 PST ! 301 | 1 | 00301 | Fri Jan 02 00:00:00 1970 PST ! 303 | 303 | 00303_update3 | Sun Jan 04 00:00:00 1970 PST ! 304 | 4 | 00304 | Mon Jan 05 00:00:00 1970 PST ! 306 | 6 | 00306 | Wed Jan 07 00:00:00 1970 PST ! 307 | 407 | 00307_update7 | Thu Jan 08 00:00:00 1970 PST ! 308 | 8 | 00308 | Fri Jan 09 00:00:00 1970 PST ! 309 | 509 | 00309_update9 | Sat Jan 10 00:00:00 1970 PST ! 310 | 0 | 00310 | Sun Jan 11 00:00:00 1970 PST ! 311 | 1 | 00311 | Mon Jan 12 00:00:00 1970 PST ! 313 | 303 | 00313_update3 | Wed Jan 14 00:00:00 1970 PST ! 314 | 4 | 00314 | Thu Jan 15 00:00:00 1970 PST ! 316 | 6 | 00316 | Sat Jan 17 00:00:00 1970 PST ! 317 | 407 | 00317_update7 | Sun Jan 18 00:00:00 1970 PST ! 318 | 8 | 00318 | Mon Jan 19 00:00:00 1970 PST ! 319 | 509 | 00319_update9 | Tue Jan 20 00:00:00 1970 PST ! 320 | 0 | 00320 | Wed Jan 21 00:00:00 1970 PST ! 321 | 1 | 00321 | Thu Jan 22 00:00:00 1970 PST ! 323 | 303 | 00323_update3 | Sat Jan 24 00:00:00 1970 PST ! 324 | 4 | 00324 | Sun Jan 25 00:00:00 1970 PST ! 326 | 6 | 00326 | Tue Jan 27 00:00:00 1970 PST ! 327 | 407 | 00327_update7 | Wed Jan 28 00:00:00 1970 PST ! 328 | 8 | 00328 | Thu Jan 29 00:00:00 1970 PST ! 329 | 509 | 00329_update9 | Fri Jan 30 00:00:00 1970 PST ! 330 | 0 | 00330 | Sat Jan 31 00:00:00 1970 PST ! 331 | 1 | 00331 | Sun Feb 01 00:00:00 1970 PST ! 333 | 303 | 00333_update3 | Tue Feb 03 00:00:00 1970 PST ! 334 | 4 | 00334 | Wed Feb 04 00:00:00 1970 PST ! 336 | 6 | 00336 | Fri Feb 06 00:00:00 1970 PST ! 337 | 407 | 00337_update7 | Sat Feb 07 00:00:00 1970 PST ! 338 | 8 | 00338 | Sun Feb 08 00:00:00 1970 PST ! 339 | 509 | 00339_update9 | Mon Feb 09 00:00:00 1970 PST ! 340 | 0 | 00340 | Tue Feb 10 00:00:00 1970 PST ! 341 | 1 | 00341 | Wed Feb 11 00:00:00 1970 PST ! 343 | 303 | 00343_update3 | Fri Feb 13 00:00:00 1970 PST ! 344 | 4 | 00344 | Sat Feb 14 00:00:00 1970 PST ! 346 | 6 | 00346 | Mon Feb 16 00:00:00 1970 PST ! 347 | 407 | 00347_update7 | Tue Feb 17 00:00:00 1970 PST ! 348 | 8 | 00348 | Wed Feb 18 00:00:00 1970 PST ! 349 | 509 | 00349_update9 | Thu Feb 19 00:00:00 1970 PST ! 350 | 0 | 00350 | Fri Feb 20 00:00:00 1970 PST ! 351 | 1 | 00351 | Sat Feb 21 00:00:00 1970 PST ! 353 | 303 | 00353_update3 | Mon Feb 23 00:00:00 1970 PST ! 354 | 4 | 00354 | Tue Feb 24 00:00:00 1970 PST ! 356 | 6 | 00356 | Thu Feb 26 00:00:00 1970 PST ! 357 | 407 | 00357_update7 | Fri Feb 27 00:00:00 1970 PST ! 358 | 8 | 00358 | Sat Feb 28 00:00:00 1970 PST ! 359 | 509 | 00359_update9 | Sun Mar 01 00:00:00 1970 PST ! 360 | 0 | 00360 | Mon Mar 02 00:00:00 1970 PST ! 361 | 1 | 00361 | Tue Mar 03 00:00:00 1970 PST ! 363 | 303 | 00363_update3 | Thu Mar 05 00:00:00 1970 PST ! 364 | 4 | 00364 | Fri Mar 06 00:00:00 1970 PST ! 366 | 6 | 00366 | Sun Mar 08 00:00:00 1970 PST ! 367 | 407 | 00367_update7 | Mon Mar 09 00:00:00 1970 PST ! 368 | 8 | 00368 | Tue Mar 10 00:00:00 1970 PST ! 369 | 509 | 00369_update9 | Wed Mar 11 00:00:00 1970 PST ! 370 | 0 | 00370 | Thu Mar 12 00:00:00 1970 PST ! 371 | 1 | 00371 | Fri Mar 13 00:00:00 1970 PST ! 373 | 303 | 00373_update3 | Sun Mar 15 00:00:00 1970 PST ! 374 | 4 | 00374 | Mon Mar 16 00:00:00 1970 PST ! 376 | 6 | 00376 | Wed Mar 18 00:00:00 1970 PST ! 377 | 407 | 00377_update7 | Thu Mar 19 00:00:00 1970 PST ! 378 | 8 | 00378 | Fri Mar 20 00:00:00 1970 PST ! 379 | 509 | 00379_update9 | Sat Mar 21 00:00:00 1970 PST ! 380 | 0 | 00380 | Sun Mar 22 00:00:00 1970 PST ! 381 | 1 | 00381 | Mon Mar 23 00:00:00 1970 PST ! 383 | 303 | 00383_update3 | Wed Mar 25 00:00:00 1970 PST ! 384 | 4 | 00384 | Thu Mar 26 00:00:00 1970 PST ! 386 | 6 | 00386 | Sat Mar 28 00:00:00 1970 PST ! 387 | 407 | 00387_update7 | Sun Mar 29 00:00:00 1970 PST ! 388 | 8 | 00388 | Mon Mar 30 00:00:00 1970 PST ! 389 | 509 | 00389_update9 | Tue Mar 31 00:00:00 1970 PST ! 390 | 0 | 00390 | Wed Apr 01 00:00:00 1970 PST ! 391 | 1 | 00391 | Thu Apr 02 00:00:00 1970 PST ! 393 | 303 | 00393_update3 | Sat Apr 04 00:00:00 1970 PST ! 394 | 4 | 00394 | Sun Apr 05 00:00:00 1970 PST ! 396 | 6 | 00396 | Tue Apr 07 00:00:00 1970 PST ! 397 | 407 | 00397_update7 | Wed Apr 08 00:00:00 1970 PST ! 398 | 8 | 00398 | Thu Apr 09 00:00:00 1970 PST ! 399 | 509 | 00399_update9 | Fri Apr 10 00:00:00 1970 PST ! 400 | 0 | 00400 | Thu Jan 01 00:00:00 1970 PST ! 401 | 1 | 00401 | Fri Jan 02 00:00:00 1970 PST ! 403 | 303 | 00403_update3 | Sun Jan 04 00:00:00 1970 PST ! 404 | 4 | 00404 | Mon Jan 05 00:00:00 1970 PST ! 406 | 6 | 00406 | Wed Jan 07 00:00:00 1970 PST ! 407 | 407 | 00407_update7 | Thu Jan 08 00:00:00 1970 PST ! 408 | 8 | 00408 | Fri Jan 09 00:00:00 1970 PST ! 409 | 509 | 00409_update9 | Sat Jan 10 00:00:00 1970 PST ! 410 | 0 | 00410 | Sun Jan 11 00:00:00 1970 PST ! 411 | 1 | 00411 | Mon Jan 12 00:00:00 1970 PST ! 413 | 303 | 00413_update3 | Wed Jan 14 00:00:00 1970 PST ! 414 | 4 | 00414 | Thu Jan 15 00:00:00 1970 PST ! 416 | 6 | 00416 | Sat Jan 17 00:00:00 1970 PST ! 417 | 407 | 00417_update7 | Sun Jan 18 00:00:00 1970 PST ! 418 | 8 | 00418 | Mon Jan 19 00:00:00 1970 PST ! 419 | 509 | 00419_update9 | Tue Jan 20 00:00:00 1970 PST ! 420 | 0 | 00420 | Wed Jan 21 00:00:00 1970 PST ! 421 | 1 | 00421 | Thu Jan 22 00:00:00 1970 PST ! 423 | 303 | 00423_update3 | Sat Jan 24 00:00:00 1970 PST ! 424 | 4 | 00424 | Sun Jan 25 00:00:00 1970 PST ! 426 | 6 | 00426 | Tue Jan 27 00:00:00 1970 PST ! 427 | 407 | 00427_update7 | Wed Jan 28 00:00:00 1970 PST ! 428 | 8 | 00428 | Thu Jan 29 00:00:00 1970 PST ! 429 | 509 | 00429_update9 | Fri Jan 30 00:00:00 1970 PST ! 430 | 0 | 00430 | Sat Jan 31 00:00:00 1970 PST ! 431 | 1 | 00431 | Sun Feb 01 00:00:00 1970 PST ! 433 | 303 | 00433_update3 | Tue Feb 03 00:00:00 1970 PST ! 434 | 4 | 00434 | Wed Feb 04 00:00:00 1970 PST ! 436 | 6 | 00436 | Fri Feb 06 00:00:00 1970 PST ! 437 | 407 | 00437_update7 | Sat Feb 07 00:00:00 1970 PST ! 438 | 8 | 00438 | Sun Feb 08 00:00:00 1970 PST ! 439 | 509 | 00439_update9 | Mon Feb 09 00:00:00 1970 PST ! 440 | 0 | 00440 | Tue Feb 10 00:00:00 1970 PST ! 441 | 1 | 00441 | Wed Feb 11 00:00:00 1970 PST ! 443 | 303 | 00443_update3 | Fri Feb 13 00:00:00 1970 PST ! 444 | 4 | 00444 | Sat Feb 14 00:00:00 1970 PST ! 446 | 6 | 00446 | Mon Feb 16 00:00:00 1970 PST ! 447 | 407 | 00447_update7 | Tue Feb 17 00:00:00 1970 PST ! 448 | 8 | 00448 | Wed Feb 18 00:00:00 1970 PST ! 449 | 509 | 00449_update9 | Thu Feb 19 00:00:00 1970 PST ! 450 | 0 | 00450 | Fri Feb 20 00:00:00 1970 PST ! 451 | 1 | 00451 | Sat Feb 21 00:00:00 1970 PST ! 453 | 303 | 00453_update3 | Mon Feb 23 00:00:00 1970 PST ! 454 | 4 | 00454 | Tue Feb 24 00:00:00 1970 PST ! 456 | 6 | 00456 | Thu Feb 26 00:00:00 1970 PST ! 457 | 407 | 00457_update7 | Fri Feb 27 00:00:00 1970 PST ! 458 | 8 | 00458 | Sat Feb 28 00:00:00 1970 PST ! 459 | 509 | 00459_update9 | Sun Mar 01 00:00:00 1970 PST ! 460 | 0 | 00460 | Mon Mar 02 00:00:00 1970 PST ! 461 | 1 | 00461 | Tue Mar 03 00:00:00 1970 PST ! 463 | 303 | 00463_update3 | Thu Mar 05 00:00:00 1970 PST ! 464 | 4 | 00464 | Fri Mar 06 00:00:00 1970 PST ! 466 | 6 | 00466 | Sun Mar 08 00:00:00 1970 PST ! 467 | 407 | 00467_update7 | Mon Mar 09 00:00:00 1970 PST ! 468 | 8 | 00468 | Tue Mar 10 00:00:00 1970 PST ! 469 | 509 | 00469_update9 | Wed Mar 11 00:00:00 1970 PST ! 470 | 0 | 00470 | Thu Mar 12 00:00:00 1970 PST ! 471 | 1 | 00471 | Fri Mar 13 00:00:00 1970 PST ! 473 | 303 | 00473_update3 | Sun Mar 15 00:00:00 1970 PST ! 474 | 4 | 00474 | Mon Mar 16 00:00:00 1970 PST ! 476 | 6 | 00476 | Wed Mar 18 00:00:00 1970 PST ! 477 | 407 | 00477_update7 | Thu Mar 19 00:00:00 1970 PST ! 478 | 8 | 00478 | Fri Mar 20 00:00:00 1970 PST ! 479 | 509 | 00479_update9 | Sat Mar 21 00:00:00 1970 PST ! 480 | 0 | 00480 | Sun Mar 22 00:00:00 1970 PST ! 481 | 1 | 00481 | Mon Mar 23 00:00:00 1970 PST ! 483 | 303 | 00483_update3 | Wed Mar 25 00:00:00 1970 PST ! 484 | 4 | 00484 | Thu Mar 26 00:00:00 1970 PST ! 486 | 6 | 00486 | Sat Mar 28 00:00:00 1970 PST ! 487 | 407 | 00487_update7 | Sun Mar 29 00:00:00 1970 PST ! 488 | 8 | 00488 | Mon Mar 30 00:00:00 1970 PST ! 489 | 509 | 00489_update9 | Tue Mar 31 00:00:00 1970 PST ! 490 | 0 | 00490 | Wed Apr 01 00:00:00 1970 PST ! 491 | 1 | 00491 | Thu Apr 02 00:00:00 1970 PST ! 493 | 303 | 00493_update3 | Sat Apr 04 00:00:00 1970 PST ! 494 | 4 | 00494 | Sun Apr 05 00:00:00 1970 PST ! 496 | 6 | 00496 | Tue Apr 07 00:00:00 1970 PST ! 497 | 407 | 00497_update7 | Wed Apr 08 00:00:00 1970 PST ! 498 | 8 | 00498 | Thu Apr 09 00:00:00 1970 PST ! 499 | 509 | 00499_update9 | Fri Apr 10 00:00:00 1970 PST ! 500 | 0 | 00500 | Thu Jan 01 00:00:00 1970 PST ! 501 | 1 | 00501 | Fri Jan 02 00:00:00 1970 PST ! 503 | 303 | 00503_update3 | Sun Jan 04 00:00:00 1970 PST ! 504 | 4 | 00504 | Mon Jan 05 00:00:00 1970 PST ! 506 | 6 | 00506 | Wed Jan 07 00:00:00 1970 PST ! 507 | 407 | 00507_update7 | Thu Jan 08 00:00:00 1970 PST ! 508 | 8 | 00508 | Fri Jan 09 00:00:00 1970 PST ! 509 | 509 | 00509_update9 | Sat Jan 10 00:00:00 1970 PST ! 510 | 0 | 00510 | Sun Jan 11 00:00:00 1970 PST ! 511 | 1 | 00511 | Mon Jan 12 00:00:00 1970 PST ! 513 | 303 | 00513_update3 | Wed Jan 14 00:00:00 1970 PST ! 514 | 4 | 00514 | Thu Jan 15 00:00:00 1970 PST ! 516 | 6 | 00516 | Sat Jan 17 00:00:00 1970 PST ! 517 | 407 | 00517_update7 | Sun Jan 18 00:00:00 1970 PST ! 518 | 8 | 00518 | Mon Jan 19 00:00:00 1970 PST ! 519 | 509 | 00519_update9 | Tue Jan 20 00:00:00 1970 PST ! 520 | 0 | 00520 | Wed Jan 21 00:00:00 1970 PST ! 521 | 1 | 00521 | Thu Jan 22 00:00:00 1970 PST ! 523 | 303 | 00523_update3 | Sat Jan 24 00:00:00 1970 PST ! 524 | 4 | 00524 | Sun Jan 25 00:00:00 1970 PST ! 526 | 6 | 00526 | Tue Jan 27 00:00:00 1970 PST ! 527 | 407 | 00527_update7 | Wed Jan 28 00:00:00 1970 PST ! 528 | 8 | 00528 | Thu Jan 29 00:00:00 1970 PST ! 529 | 509 | 00529_update9 | Fri Jan 30 00:00:00 1970 PST ! 530 | 0 | 00530 | Sat Jan 31 00:00:00 1970 PST ! 531 | 1 | 00531 | Sun Feb 01 00:00:00 1970 PST ! 533 | 303 | 00533_update3 | Tue Feb 03 00:00:00 1970 PST ! 534 | 4 | 00534 | Wed Feb 04 00:00:00 1970 PST ! 536 | 6 | 00536 | Fri Feb 06 00:00:00 1970 PST ! 537 | 407 | 00537_update7 | Sat Feb 07 00:00:00 1970 PST ! 538 | 8 | 00538 | Sun Feb 08 00:00:00 1970 PST ! 539 | 509 | 00539_update9 | Mon Feb 09 00:00:00 1970 PST ! 540 | 0 | 00540 | Tue Feb 10 00:00:00 1970 PST ! 541 | 1 | 00541 | Wed Feb 11 00:00:00 1970 PST ! 543 | 303 | 00543_update3 | Fri Feb 13 00:00:00 1970 PST ! 544 | 4 | 00544 | Sat Feb 14 00:00:00 1970 PST ! 546 | 6 | 00546 | Mon Feb 16 00:00:00 1970 PST ! 547 | 407 | 00547_update7 | Tue Feb 17 00:00:00 1970 PST ! 548 | 8 | 00548 | Wed Feb 18 00:00:00 1970 PST ! 549 | 509 | 00549_update9 | Thu Feb 19 00:00:00 1970 PST ! 550 | 0 | 00550 | Fri Feb 20 00:00:00 1970 PST ! 551 | 1 | 00551 | Sat Feb 21 00:00:00 1970 PST ! 553 | 303 | 00553_update3 | Mon Feb 23 00:00:00 1970 PST ! 554 | 4 | 00554 | Tue Feb 24 00:00:00 1970 PST ! 556 | 6 | 00556 | Thu Feb 26 00:00:00 1970 PST ! 557 | 407 | 00557_update7 | Fri Feb 27 00:00:00 1970 PST ! 558 | 8 | 00558 | Sat Feb 28 00:00:00 1970 PST ! 559 | 509 | 00559_update9 | Sun Mar 01 00:00:00 1970 PST ! 560 | 0 | 00560 | Mon Mar 02 00:00:00 1970 PST ! 561 | 1 | 00561 | Tue Mar 03 00:00:00 1970 PST ! 563 | 303 | 00563_update3 | Thu Mar 05 00:00:00 1970 PST ! 564 | 4 | 00564 | Fri Mar 06 00:00:00 1970 PST ! 566 | 6 | 00566 | Sun Mar 08 00:00:00 1970 PST ! 567 | 407 | 00567_update7 | Mon Mar 09 00:00:00 1970 PST ! 568 | 8 | 00568 | Tue Mar 10 00:00:00 1970 PST ! 569 | 509 | 00569_update9 | Wed Mar 11 00:00:00 1970 PST ! 570 | 0 | 00570 | Thu Mar 12 00:00:00 1970 PST ! 571 | 1 | 00571 | Fri Mar 13 00:00:00 1970 PST ! 573 | 303 | 00573_update3 | Sun Mar 15 00:00:00 1970 PST ! 574 | 4 | 00574 | Mon Mar 16 00:00:00 1970 PST ! 576 | 6 | 00576 | Wed Mar 18 00:00:00 1970 PST ! 577 | 407 | 00577_update7 | Thu Mar 19 00:00:00 1970 PST ! 578 | 8 | 00578 | Fri Mar 20 00:00:00 1970 PST ! 579 | 509 | 00579_update9 | Sat Mar 21 00:00:00 1970 PST ! 580 | 0 | 00580 | Sun Mar 22 00:00:00 1970 PST ! 581 | 1 | 00581 | Mon Mar 23 00:00:00 1970 PST ! 583 | 303 | 00583_update3 | Wed Mar 25 00:00:00 1970 PST ! 584 | 4 | 00584 | Thu Mar 26 00:00:00 1970 PST ! 586 | 6 | 00586 | Sat Mar 28 00:00:00 1970 PST ! 587 | 407 | 00587_update7 | Sun Mar 29 00:00:00 1970 PST ! 588 | 8 | 00588 | Mon Mar 30 00:00:00 1970 PST ! 589 | 509 | 00589_update9 | Tue Mar 31 00:00:00 1970 PST ! 590 | 0 | 00590 | Wed Apr 01 00:00:00 1970 PST ! 591 | 1 | 00591 | Thu Apr 02 00:00:00 1970 PST ! 593 | 303 | 00593_update3 | Sat Apr 04 00:00:00 1970 PST ! 594 | 4 | 00594 | Sun Apr 05 00:00:00 1970 PST ! 596 | 6 | 00596 | Tue Apr 07 00:00:00 1970 PST ! 597 | 407 | 00597_update7 | Wed Apr 08 00:00:00 1970 PST ! 598 | 8 | 00598 | Thu Apr 09 00:00:00 1970 PST ! 599 | 509 | 00599_update9 | Fri Apr 10 00:00:00 1970 PST ! 600 | 0 | 00600 | Thu Jan 01 00:00:00 1970 PST ! 601 | 1 | 00601 | Fri Jan 02 00:00:00 1970 PST ! 603 | 303 | 00603_update3 | Sun Jan 04 00:00:00 1970 PST ! 604 | 4 | 00604 | Mon Jan 05 00:00:00 1970 PST ! 606 | 6 | 00606 | Wed Jan 07 00:00:00 1970 PST ! 607 | 407 | 00607_update7 | Thu Jan 08 00:00:00 1970 PST ! 608 | 8 | 00608 | Fri Jan 09 00:00:00 1970 PST ! 609 | 509 | 00609_update9 | Sat Jan 10 00:00:00 1970 PST ! 610 | 0 | 00610 | Sun Jan 11 00:00:00 1970 PST ! 611 | 1 | 00611 | Mon Jan 12 00:00:00 1970 PST ! 613 | 303 | 00613_update3 | Wed Jan 14 00:00:00 1970 PST ! 614 | 4 | 00614 | Thu Jan 15 00:00:00 1970 PST ! 616 | 6 | 00616 | Sat Jan 17 00:00:00 1970 PST ! 617 | 407 | 00617_update7 | Sun Jan 18 00:00:00 1970 PST ! 618 | 8 | 00618 | Mon Jan 19 00:00:00 1970 PST ! 619 | 509 | 00619_update9 | Tue Jan 20 00:00:00 1970 PST ! 620 | 0 | 00620 | Wed Jan 21 00:00:00 1970 PST ! 621 | 1 | 00621 | Thu Jan 22 00:00:00 1970 PST ! 623 | 303 | 00623_update3 | Sat Jan 24 00:00:00 1970 PST ! 624 | 4 | 00624 | Sun Jan 25 00:00:00 1970 PST ! 626 | 6 | 00626 | Tue Jan 27 00:00:00 1970 PST ! 627 | 407 | 00627_update7 | Wed Jan 28 00:00:00 1970 PST ! 628 | 8 | 00628 | Thu Jan 29 00:00:00 1970 PST ! 629 | 509 | 00629_update9 | Fri Jan 30 00:00:00 1970 PST ! 630 | 0 | 00630 | Sat Jan 31 00:00:00 1970 PST ! 631 | 1 | 00631 | Sun Feb 01 00:00:00 1970 PST ! 633 | 303 | 00633_update3 | Tue Feb 03 00:00:00 1970 PST ! 634 | 4 | 00634 | Wed Feb 04 00:00:00 1970 PST ! 636 | 6 | 00636 | Fri Feb 06 00:00:00 1970 PST ! 637 | 407 | 00637_update7 | Sat Feb 07 00:00:00 1970 PST ! 638 | 8 | 00638 | Sun Feb 08 00:00:00 1970 PST ! 639 | 509 | 00639_update9 | Mon Feb 09 00:00:00 1970 PST ! 640 | 0 | 00640 | Tue Feb 10 00:00:00 1970 PST ! 641 | 1 | 00641 | Wed Feb 11 00:00:00 1970 PST ! 643 | 303 | 00643_update3 | Fri Feb 13 00:00:00 1970 PST ! 644 | 4 | 00644 | Sat Feb 14 00:00:00 1970 PST ! 646 | 6 | 00646 | Mon Feb 16 00:00:00 1970 PST ! 647 | 407 | 00647_update7 | Tue Feb 17 00:00:00 1970 PST ! 648 | 8 | 00648 | Wed Feb 18 00:00:00 1970 PST ! 649 | 509 | 00649_update9 | Thu Feb 19 00:00:00 1970 PST ! 650 | 0 | 00650 | Fri Feb 20 00:00:00 1970 PST ! 651 | 1 | 00651 | Sat Feb 21 00:00:00 1970 PST ! 653 | 303 | 00653_update3 | Mon Feb 23 00:00:00 1970 PST ! 654 | 4 | 00654 | Tue Feb 24 00:00:00 1970 PST ! 656 | 6 | 00656 | Thu Feb 26 00:00:00 1970 PST ! 657 | 407 | 00657_update7 | Fri Feb 27 00:00:00 1970 PST ! 658 | 8 | 00658 | Sat Feb 28 00:00:00 1970 PST ! 659 | 509 | 00659_update9 | Sun Mar 01 00:00:00 1970 PST ! 660 | 0 | 00660 | Mon Mar 02 00:00:00 1970 PST ! 661 | 1 | 00661 | Tue Mar 03 00:00:00 1970 PST ! 663 | 303 | 00663_update3 | Thu Mar 05 00:00:00 1970 PST ! 664 | 4 | 00664 | Fri Mar 06 00:00:00 1970 PST ! 666 | 6 | 00666 | Sun Mar 08 00:00:00 1970 PST ! 667 | 407 | 00667_update7 | Mon Mar 09 00:00:00 1970 PST ! 668 | 8 | 00668 | Tue Mar 10 00:00:00 1970 PST ! 669 | 509 | 00669_update9 | Wed Mar 11 00:00:00 1970 PST ! 670 | 0 | 00670 | Thu Mar 12 00:00:00 1970 PST ! 671 | 1 | 00671 | Fri Mar 13 00:00:00 1970 PST ! 673 | 303 | 00673_update3 | Sun Mar 15 00:00:00 1970 PST ! 674 | 4 | 00674 | Mon Mar 16 00:00:00 1970 PST ! 676 | 6 | 00676 | Wed Mar 18 00:00:00 1970 PST ! 677 | 407 | 00677_update7 | Thu Mar 19 00:00:00 1970 PST ! 678 | 8 | 00678 | Fri Mar 20 00:00:00 1970 PST ! 679 | 509 | 00679_update9 | Sat Mar 21 00:00:00 1970 PST ! 680 | 0 | 00680 | Sun Mar 22 00:00:00 1970 PST ! 681 | 1 | 00681 | Mon Mar 23 00:00:00 1970 PST ! 683 | 303 | 00683_update3 | Wed Mar 25 00:00:00 1970 PST ! 684 | 4 | 00684 | Thu Mar 26 00:00:00 1970 PST ! 686 | 6 | 00686 | Sat Mar 28 00:00:00 1970 PST ! 687 | 407 | 00687_update7 | Sun Mar 29 00:00:00 1970 PST ! 688 | 8 | 00688 | Mon Mar 30 00:00:00 1970 PST ! 689 | 509 | 00689_update9 | Tue Mar 31 00:00:00 1970 PST ! 690 | 0 | 00690 | Wed Apr 01 00:00:00 1970 PST ! 691 | 1 | 00691 | Thu Apr 02 00:00:00 1970 PST ! 693 | 303 | 00693_update3 | Sat Apr 04 00:00:00 1970 PST ! 694 | 4 | 00694 | Sun Apr 05 00:00:00 1970 PST ! 696 | 6 | 00696 | Tue Apr 07 00:00:00 1970 PST ! 697 | 407 | 00697_update7 | Wed Apr 08 00:00:00 1970 PST ! 698 | 8 | 00698 | Thu Apr 09 00:00:00 1970 PST ! 699 | 509 | 00699_update9 | Fri Apr 10 00:00:00 1970 PST ! 700 | 0 | 00700 | Thu Jan 01 00:00:00 1970 PST ! 701 | 1 | 00701 | Fri Jan 02 00:00:00 1970 PST ! 703 | 303 | 00703_update3 | Sun Jan 04 00:00:00 1970 PST ! 704 | 4 | 00704 | Mon Jan 05 00:00:00 1970 PST ! 706 | 6 | 00706 | Wed Jan 07 00:00:00 1970 PST ! 707 | 407 | 00707_update7 | Thu Jan 08 00:00:00 1970 PST ! 708 | 8 | 00708 | Fri Jan 09 00:00:00 1970 PST ! 709 | 509 | 00709_update9 | Sat Jan 10 00:00:00 1970 PST ! 710 | 0 | 00710 | Sun Jan 11 00:00:00 1970 PST ! 711 | 1 | 00711 | Mon Jan 12 00:00:00 1970 PST ! 713 | 303 | 00713_update3 | Wed Jan 14 00:00:00 1970 PST ! 714 | 4 | 00714 | Thu Jan 15 00:00:00 1970 PST ! 716 | 6 | 00716 | Sat Jan 17 00:00:00 1970 PST ! 717 | 407 | 00717_update7 | Sun Jan 18 00:00:00 1970 PST ! 718 | 8 | 00718 | Mon Jan 19 00:00:00 1970 PST ! 719 | 509 | 00719_update9 | Tue Jan 20 00:00:00 1970 PST ! 720 | 0 | 00720 | Wed Jan 21 00:00:00 1970 PST ! 721 | 1 | 00721 | Thu Jan 22 00:00:00 1970 PST ! 723 | 303 | 00723_update3 | Sat Jan 24 00:00:00 1970 PST ! 724 | 4 | 00724 | Sun Jan 25 00:00:00 1970 PST ! 726 | 6 | 00726 | Tue Jan 27 00:00:00 1970 PST ! 727 | 407 | 00727_update7 | Wed Jan 28 00:00:00 1970 PST ! 728 | 8 | 00728 | Thu Jan 29 00:00:00 1970 PST ! 729 | 509 | 00729_update9 | Fri Jan 30 00:00:00 1970 PST ! 730 | 0 | 00730 | Sat Jan 31 00:00:00 1970 PST ! 731 | 1 | 00731 | Sun Feb 01 00:00:00 1970 PST ! 733 | 303 | 00733_update3 | Tue Feb 03 00:00:00 1970 PST ! 734 | 4 | 00734 | Wed Feb 04 00:00:00 1970 PST ! 736 | 6 | 00736 | Fri Feb 06 00:00:00 1970 PST ! 737 | 407 | 00737_update7 | Sat Feb 07 00:00:00 1970 PST ! 738 | 8 | 00738 | Sun Feb 08 00:00:00 1970 PST ! 739 | 509 | 00739_update9 | Mon Feb 09 00:00:00 1970 PST ! 740 | 0 | 00740 | Tue Feb 10 00:00:00 1970 PST ! 741 | 1 | 00741 | Wed Feb 11 00:00:00 1970 PST ! 743 | 303 | 00743_update3 | Fri Feb 13 00:00:00 1970 PST ! 744 | 4 | 00744 | Sat Feb 14 00:00:00 1970 PST ! 746 | 6 | 00746 | Mon Feb 16 00:00:00 1970 PST ! 747 | 407 | 00747_update7 | Tue Feb 17 00:00:00 1970 PST ! 748 | 8 | 00748 | Wed Feb 18 00:00:00 1970 PST ! 749 | 509 | 00749_update9 | Thu Feb 19 00:00:00 1970 PST ! 750 | 0 | 00750 | Fri Feb 20 00:00:00 1970 PST ! 751 | 1 | 00751 | Sat Feb 21 00:00:00 1970 PST ! 753 | 303 | 00753_update3 | Mon Feb 23 00:00:00 1970 PST ! 754 | 4 | 00754 | Tue Feb 24 00:00:00 1970 PST ! 756 | 6 | 00756 | Thu Feb 26 00:00:00 1970 PST ! 757 | 407 | 00757_update7 | Fri Feb 27 00:00:00 1970 PST ! 758 | 8 | 00758 | Sat Feb 28 00:00:00 1970 PST ! 759 | 509 | 00759_update9 | Sun Mar 01 00:00:00 1970 PST ! 760 | 0 | 00760 | Mon Mar 02 00:00:00 1970 PST ! 761 | 1 | 00761 | Tue Mar 03 00:00:00 1970 PST ! 763 | 303 | 00763_update3 | Thu Mar 05 00:00:00 1970 PST ! 764 | 4 | 00764 | Fri Mar 06 00:00:00 1970 PST ! 766 | 6 | 00766 | Sun Mar 08 00:00:00 1970 PST ! 767 | 407 | 00767_update7 | Mon Mar 09 00:00:00 1970 PST ! 768 | 8 | 00768 | Tue Mar 10 00:00:00 1970 PST ! 769 | 509 | 00769_update9 | Wed Mar 11 00:00:00 1970 PST ! 770 | 0 | 00770 | Thu Mar 12 00:00:00 1970 PST ! 771 | 1 | 00771 | Fri Mar 13 00:00:00 1970 PST ! 773 | 303 | 00773_update3 | Sun Mar 15 00:00:00 1970 PST ! 774 | 4 | 00774 | Mon Mar 16 00:00:00 1970 PST ! 776 | 6 | 00776 | Wed Mar 18 00:00:00 1970 PST ! 777 | 407 | 00777_update7 | Thu Mar 19 00:00:00 1970 PST ! 778 | 8 | 00778 | Fri Mar 20 00:00:00 1970 PST ! 779 | 509 | 00779_update9 | Sat Mar 21 00:00:00 1970 PST ! 780 | 0 | 00780 | Sun Mar 22 00:00:00 1970 PST ! 781 | 1 | 00781 | Mon Mar 23 00:00:00 1970 PST ! 783 | 303 | 00783_update3 | Wed Mar 25 00:00:00 1970 PST ! 784 | 4 | 00784 | Thu Mar 26 00:00:00 1970 PST ! 786 | 6 | 00786 | Sat Mar 28 00:00:00 1970 PST ! 787 | 407 | 00787_update7 | Sun Mar 29 00:00:00 1970 PST ! 788 | 8 | 00788 | Mon Mar 30 00:00:00 1970 PST ! 789 | 509 | 00789_update9 | Tue Mar 31 00:00:00 1970 PST ! 790 | 0 | 00790 | Wed Apr 01 00:00:00 1970 PST ! 791 | 1 | 00791 | Thu Apr 02 00:00:00 1970 PST ! 793 | 303 | 00793_update3 | Sat Apr 04 00:00:00 1970 PST ! 794 | 4 | 00794 | Sun Apr 05 00:00:00 1970 PST ! 796 | 6 | 00796 | Tue Apr 07 00:00:00 1970 PST ! 797 | 407 | 00797_update7 | Wed Apr 08 00:00:00 1970 PST ! 798 | 8 | 00798 | Thu Apr 09 00:00:00 1970 PST ! 799 | 509 | 00799_update9 | Fri Apr 10 00:00:00 1970 PST ! 800 | 0 | 00800 | Thu Jan 01 00:00:00 1970 PST ! 801 | 1 | 00801 | Fri Jan 02 00:00:00 1970 PST ! 803 | 303 | 00803_update3 | Sun Jan 04 00:00:00 1970 PST ! 804 | 4 | 00804 | Mon Jan 05 00:00:00 1970 PST ! 806 | 6 | 00806 | Wed Jan 07 00:00:00 1970 PST ! 807 | 407 | 00807_update7 | Thu Jan 08 00:00:00 1970 PST ! 808 | 8 | 00808 | Fri Jan 09 00:00:00 1970 PST ! 809 | 509 | 00809_update9 | Sat Jan 10 00:00:00 1970 PST ! 810 | 0 | 00810 | Sun Jan 11 00:00:00 1970 PST ! 811 | 1 | 00811 | Mon Jan 12 00:00:00 1970 PST ! 813 | 303 | 00813_update3 | Wed Jan 14 00:00:00 1970 PST ! 814 | 4 | 00814 | Thu Jan 15 00:00:00 1970 PST ! 816 | 6 | 00816 | Sat Jan 17 00:00:00 1970 PST ! 817 | 407 | 00817_update7 | Sun Jan 18 00:00:00 1970 PST ! 818 | 8 | 00818 | Mon Jan 19 00:00:00 1970 PST ! 819 | 509 | 00819_update9 | Tue Jan 20 00:00:00 1970 PST ! 820 | 0 | 00820 | Wed Jan 21 00:00:00 1970 PST ! 821 | 1 | 00821 | Thu Jan 22 00:00:00 1970 PST ! 823 | 303 | 00823_update3 | Sat Jan 24 00:00:00 1970 PST ! 824 | 4 | 00824 | Sun Jan 25 00:00:00 1970 PST ! 826 | 6 | 00826 | Tue Jan 27 00:00:00 1970 PST ! 827 | 407 | 00827_update7 | Wed Jan 28 00:00:00 1970 PST ! 828 | 8 | 00828 | Thu Jan 29 00:00:00 1970 PST ! 829 | 509 | 00829_update9 | Fri Jan 30 00:00:00 1970 PST ! 830 | 0 | 00830 | Sat Jan 31 00:00:00 1970 PST ! 831 | 1 | 00831 | Sun Feb 01 00:00:00 1970 PST ! 833 | 303 | 00833_update3 | Tue Feb 03 00:00:00 1970 PST ! 834 | 4 | 00834 | Wed Feb 04 00:00:00 1970 PST ! 836 | 6 | 00836 | Fri Feb 06 00:00:00 1970 PST ! 837 | 407 | 00837_update7 | Sat Feb 07 00:00:00 1970 PST ! 838 | 8 | 00838 | Sun Feb 08 00:00:00 1970 PST ! 839 | 509 | 00839_update9 | Mon Feb 09 00:00:00 1970 PST ! 840 | 0 | 00840 | Tue Feb 10 00:00:00 1970 PST ! 841 | 1 | 00841 | Wed Feb 11 00:00:00 1970 PST ! 843 | 303 | 00843_update3 | Fri Feb 13 00:00:00 1970 PST ! 844 | 4 | 00844 | Sat Feb 14 00:00:00 1970 PST ! 846 | 6 | 00846 | Mon Feb 16 00:00:00 1970 PST ! 847 | 407 | 00847_update7 | Tue Feb 17 00:00:00 1970 PST ! 848 | 8 | 00848 | Wed Feb 18 00:00:00 1970 PST ! 849 | 509 | 00849_update9 | Thu Feb 19 00:00:00 1970 PST ! 850 | 0 | 00850 | Fri Feb 20 00:00:00 1970 PST ! 851 | 1 | 00851 | Sat Feb 21 00:00:00 1970 PST ! 853 | 303 | 00853_update3 | Mon Feb 23 00:00:00 1970 PST ! 854 | 4 | 00854 | Tue Feb 24 00:00:00 1970 PST ! 856 | 6 | 00856 | Thu Feb 26 00:00:00 1970 PST ! 857 | 407 | 00857_update7 | Fri Feb 27 00:00:00 1970 PST ! 858 | 8 | 00858 | Sat Feb 28 00:00:00 1970 PST ! 859 | 509 | 00859_update9 | Sun Mar 01 00:00:00 1970 PST ! 860 | 0 | 00860 | Mon Mar 02 00:00:00 1970 PST ! 861 | 1 | 00861 | Tue Mar 03 00:00:00 1970 PST ! 863 | 303 | 00863_update3 | Thu Mar 05 00:00:00 1970 PST ! 864 | 4 | 00864 | Fri Mar 06 00:00:00 1970 PST ! 866 | 6 | 00866 | Sun Mar 08 00:00:00 1970 PST ! 867 | 407 | 00867_update7 | Mon Mar 09 00:00:00 1970 PST ! 868 | 8 | 00868 | Tue Mar 10 00:00:00 1970 PST ! 869 | 509 | 00869_update9 | Wed Mar 11 00:00:00 1970 PST ! 870 | 0 | 00870 | Thu Mar 12 00:00:00 1970 PST ! 871 | 1 | 00871 | Fri Mar 13 00:00:00 1970 PST ! 873 | 303 | 00873_update3 | Sun Mar 15 00:00:00 1970 PST ! 874 | 4 | 00874 | Mon Mar 16 00:00:00 1970 PST ! 876 | 6 | 00876 | Wed Mar 18 00:00:00 1970 PST ! 877 | 407 | 00877_update7 | Thu Mar 19 00:00:00 1970 PST ! 878 | 8 | 00878 | Fri Mar 20 00:00:00 1970 PST ! 879 | 509 | 00879_update9 | Sat Mar 21 00:00:00 1970 PST ! 880 | 0 | 00880 | Sun Mar 22 00:00:00 1970 PST ! 881 | 1 | 00881 | Mon Mar 23 00:00:00 1970 PST ! 883 | 303 | 00883_update3 | Wed Mar 25 00:00:00 1970 PST ! 884 | 4 | 00884 | Thu Mar 26 00:00:00 1970 PST ! 886 | 6 | 00886 | Sat Mar 28 00:00:00 1970 PST ! 887 | 407 | 00887_update7 | Sun Mar 29 00:00:00 1970 PST ! 888 | 8 | 00888 | Mon Mar 30 00:00:00 1970 PST ! 889 | 509 | 00889_update9 | Tue Mar 31 00:00:00 1970 PST ! 890 | 0 | 00890 | Wed Apr 01 00:00:00 1970 PST ! 891 | 1 | 00891 | Thu Apr 02 00:00:00 1970 PST ! 893 | 303 | 00893_update3 | Sat Apr 04 00:00:00 1970 PST ! 894 | 4 | 00894 | Sun Apr 05 00:00:00 1970 PST ! 896 | 6 | 00896 | Tue Apr 07 00:00:00 1970 PST ! 897 | 407 | 00897_update7 | Wed Apr 08 00:00:00 1970 PST ! 898 | 8 | 00898 | Thu Apr 09 00:00:00 1970 PST ! 899 | 509 | 00899_update9 | Fri Apr 10 00:00:00 1970 PST ! 900 | 0 | 00900 | Thu Jan 01 00:00:00 1970 PST ! 901 | 1 | 00901 | Fri Jan 02 00:00:00 1970 PST ! 903 | 303 | 00903_update3 | Sun Jan 04 00:00:00 1970 PST ! 904 | 4 | 00904 | Mon Jan 05 00:00:00 1970 PST ! 906 | 6 | 00906 | Wed Jan 07 00:00:00 1970 PST ! 907 | 407 | 00907_update7 | Thu Jan 08 00:00:00 1970 PST ! 908 | 8 | 00908 | Fri Jan 09 00:00:00 1970 PST ! 909 | 509 | 00909_update9 | Sat Jan 10 00:00:00 1970 PST ! 910 | 0 | 00910 | Sun Jan 11 00:00:00 1970 PST ! 911 | 1 | 00911 | Mon Jan 12 00:00:00 1970 PST ! 913 | 303 | 00913_update3 | Wed Jan 14 00:00:00 1970 PST ! 914 | 4 | 00914 | Thu Jan 15 00:00:00 1970 PST ! 916 | 6 | 00916 | Sat Jan 17 00:00:00 1970 PST ! 917 | 407 | 00917_update7 | Sun Jan 18 00:00:00 1970 PST ! 918 | 8 | 00918 | Mon Jan 19 00:00:00 1970 PST ! 919 | 509 | 00919_update9 | Tue Jan 20 00:00:00 1970 PST ! 920 | 0 | 00920 | Wed Jan 21 00:00:00 1970 PST ! 921 | 1 | 00921 | Thu Jan 22 00:00:00 1970 PST ! 923 | 303 | 00923_update3 | Sat Jan 24 00:00:00 1970 PST ! 924 | 4 | 00924 | Sun Jan 25 00:00:00 1970 PST ! 926 | 6 | 00926 | Tue Jan 27 00:00:00 1970 PST ! 927 | 407 | 00927_update7 | Wed Jan 28 00:00:00 1970 PST ! 928 | 8 | 00928 | Thu Jan 29 00:00:00 1970 PST ! 929 | 509 | 00929_update9 | Fri Jan 30 00:00:00 1970 PST ! 930 | 0 | 00930 | Sat Jan 31 00:00:00 1970 PST ! 931 | 1 | 00931 | Sun Feb 01 00:00:00 1970 PST ! 933 | 303 | 00933_update3 | Tue Feb 03 00:00:00 1970 PST ! 934 | 4 | 00934 | Wed Feb 04 00:00:00 1970 PST ! 936 | 6 | 00936 | Fri Feb 06 00:00:00 1970 PST ! 937 | 407 | 00937_update7 | Sat Feb 07 00:00:00 1970 PST ! 938 | 8 | 00938 | Sun Feb 08 00:00:00 1970 PST ! 939 | 509 | 00939_update9 | Mon Feb 09 00:00:00 1970 PST ! 940 | 0 | 00940 | Tue Feb 10 00:00:00 1970 PST ! 941 | 1 | 00941 | Wed Feb 11 00:00:00 1970 PST ! 943 | 303 | 00943_update3 | Fri Feb 13 00:00:00 1970 PST ! 944 | 4 | 00944 | Sat Feb 14 00:00:00 1970 PST ! 946 | 6 | 00946 | Mon Feb 16 00:00:00 1970 PST ! 947 | 407 | 00947_update7 | Tue Feb 17 00:00:00 1970 PST ! 948 | 8 | 00948 | Wed Feb 18 00:00:00 1970 PST ! 949 | 509 | 00949_update9 | Thu Feb 19 00:00:00 1970 PST ! 950 | 0 | 00950 | Fri Feb 20 00:00:00 1970 PST ! 951 | 1 | 00951 | Sat Feb 21 00:00:00 1970 PST ! 953 | 303 | 00953_update3 | Mon Feb 23 00:00:00 1970 PST ! 954 | 4 | 00954 | Tue Feb 24 00:00:00 1970 PST ! 956 | 6 | 00956 | Thu Feb 26 00:00:00 1970 PST ! 957 | 407 | 00957_update7 | Fri Feb 27 00:00:00 1970 PST ! 958 | 8 | 00958 | Sat Feb 28 00:00:00 1970 PST ! 959 | 509 | 00959_update9 | Sun Mar 01 00:00:00 1970 PST ! 960 | 0 | 00960 | Mon Mar 02 00:00:00 1970 PST ! 961 | 1 | 00961 | Tue Mar 03 00:00:00 1970 PST ! 963 | 303 | 00963_update3 | Thu Mar 05 00:00:00 1970 PST ! 964 | 4 | 00964 | Fri Mar 06 00:00:00 1970 PST ! 966 | 6 | 00966 | Sun Mar 08 00:00:00 1970 PST ! 967 | 407 | 00967_update7 | Mon Mar 09 00:00:00 1970 PST ! 968 | 8 | 00968 | Tue Mar 10 00:00:00 1970 PST ! 969 | 509 | 00969_update9 | Wed Mar 11 00:00:00 1970 PST ! 970 | 0 | 00970 | Thu Mar 12 00:00:00 1970 PST ! 971 | 1 | 00971 | Fri Mar 13 00:00:00 1970 PST ! 973 | 303 | 00973_update3 | Sun Mar 15 00:00:00 1970 PST ! 974 | 4 | 00974 | Mon Mar 16 00:00:00 1970 PST ! 976 | 6 | 00976 | Wed Mar 18 00:00:00 1970 PST ! 977 | 407 | 00977_update7 | Thu Mar 19 00:00:00 1970 PST ! 978 | 8 | 00978 | Fri Mar 20 00:00:00 1970 PST ! 979 | 509 | 00979_update9 | Sat Mar 21 00:00:00 1970 PST ! 980 | 0 | 00980 | Sun Mar 22 00:00:00 1970 PST ! 981 | 1 | 00981 | Mon Mar 23 00:00:00 1970 PST ! 983 | 303 | 00983_update3 | Wed Mar 25 00:00:00 1970 PST ! 984 | 4 | 00984 | Thu Mar 26 00:00:00 1970 PST ! 986 | 6 | 00986 | Sat Mar 28 00:00:00 1970 PST ! 987 | 407 | 00987_update7 | Sun Mar 29 00:00:00 1970 PST ! 988 | 8 | 00988 | Mon Mar 30 00:00:00 1970 PST ! 989 | 509 | 00989_update9 | Tue Mar 31 00:00:00 1970 PST ! 990 | 0 | 00990 | Wed Apr 01 00:00:00 1970 PST ! 991 | 1 | 00991 | Thu Apr 02 00:00:00 1970 PST ! 993 | 303 | 00993_update3 | Sat Apr 04 00:00:00 1970 PST ! 994 | 4 | 00994 | Sun Apr 05 00:00:00 1970 PST ! 996 | 6 | 00996 | Tue Apr 07 00:00:00 1970 PST ! 997 | 407 | 00997_update7 | Wed Apr 08 00:00:00 1970 PST ! 998 | 8 | 00998 | Thu Apr 09 00:00:00 1970 PST ! 999 | 509 | 00999_update9 | Fri Apr 10 00:00:00 1970 PST ! 1000 | 0 | 01000 | Thu Jan 01 00:00:00 1970 PST ! 1001 | 101 | 0000100001 | ! 1003 | 403 | 0000300003_update3 | ! 1004 | 104 | 0000400004 | ! 1006 | 106 | 0000600006 | ! 1007 | 507 | 0000700007_update7 | ! 1008 | 108 | 0000800008 | ! 1009 | 609 | 0000900009_update9 | ! 1010 | 100 | 0001000010 | ! 1011 | 101 | 0001100011 | ! 1013 | 403 | 0001300013_update3 | ! 1014 | 104 | 0001400014 | ! 1016 | 106 | 0001600016 | ! 1017 | 507 | 0001700017_update7 | ! 1018 | 108 | 0001800018 | ! 1019 | 609 | 0001900019_update9 | ! 1020 | 100 | 0002000020 | ! 1101 | 201 | aaa | ! 1103 | 503 | ccc_update3 | ! 1104 | 204 | ddd | ! (819 rows) ! ! EXPLAIN (verbose, costs off) ! INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ! Insert on public.ft2 ! Output: (tableoid)::regclass ! Remote SQL: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ! -> Result ! Output: 9999, 999, NULL::integer, 'foo'::text, NULL::timestamp with time zone, NULL::timestamp without time zone, NULL::character varying, 'ft2 '::character(10), NULL::user_enum ! (5 rows) ! ! INSERT INTO ft2 (c1,c2,c3) VALUES (9999,999,'foo') RETURNING tableoid::regclass; ! tableoid ! ---------- ! ft2 ! (1 row) ! ! EXPLAIN (verbose, costs off) ! UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; ! QUERY PLAN ! ------------------------------------------------------------------------------------------------------------------- ! Update on public.ft2 ! Output: (tableoid)::regclass ! Remote SQL: UPDATE "S 1"."T 1" SET c3 = $2 WHERE ctid = $1 ! -> Foreign Scan on public.ft2 ! Output: c1, c2, NULL::integer, 'bar'::text, c4, c5, c6, c7, c8, ctid ! Remote SQL: SELECT "C 1", c2, c4, c5, c6, c7, c8, ctid FROM "S 1"."T 1" WHERE (("C 1" = 9999)) FOR UPDATE ! (6 rows) ! ! UPDATE ft2 SET c3 = 'bar' WHERE c1 = 9999 RETURNING tableoid::regclass; ! tableoid ! ---------- ! ft2 ! (1 row) ! ! EXPLAIN (verbose, costs off) ! DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; ! QUERY PLAN ! ------------------------------------------------------------------------------------ ! Delete on public.ft2 ! Output: (tableoid)::regclass ! Remote SQL: DELETE FROM "S 1"."T 1" WHERE ctid = $1 ! -> Foreign Scan on public.ft2 ! Output: ctid ! Remote SQL: SELECT ctid FROM "S 1"."T 1" WHERE (("C 1" = 9999)) FOR UPDATE ! (6 rows) ! ! DELETE FROM ft2 WHERE c1 = 9999 RETURNING tableoid::regclass; ! tableoid ! ---------- ! ft2 ! (1 row) ! ! -- Test that trigger on remote table works as expected ! CREATE OR REPLACE FUNCTION "S 1".F_BRTRIG() RETURNS trigger AS $$ ! BEGIN ! NEW.c3 = NEW.c3 || '_trig_update'; ! RETURN NEW; ! END; ! $$ LANGUAGE plpgsql; ! CREATE TRIGGER t1_br_insert BEFORE INSERT OR UPDATE ! ON "S 1"."T 1" FOR EACH ROW EXECUTE PROCEDURE "S 1".F_BRTRIG(); ! INSERT INTO ft2 (c1,c2,c3) VALUES (1208, 818, 'fff') RETURNING *; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+-----------------+----+----+----+------------+---- ! 1208 | 818 | fff_trig_update | | | | ft2 | ! (1 row) ! ! INSERT INTO ft2 (c1,c2,c3,c6) VALUES (1218, 818, 'ggg', '(--;') RETURNING *; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+-----------------+----+----+------+------------+---- ! 1218 | 818 | ggg_trig_update | | | (--; | ft2 | ! (1 row) ! ! UPDATE ft2 SET c2 = c2 + 600 WHERE c1 % 10 = 8 AND c1 < 1200 RETURNING *; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+------------------------+------------------------------+--------------------------+----+------------+----- ! 8 | 608 | 00008_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 18 | 608 | 00018_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 28 | 608 | 00028_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 38 | 608 | 00038_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 48 | 608 | 00048_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 58 | 608 | 00058_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 68 | 608 | 00068_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 78 | 608 | 00078_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 88 | 608 | 00088_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 98 | 608 | 00098_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 108 | 608 | 00108_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 118 | 608 | 00118_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 128 | 608 | 00128_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 138 | 608 | 00138_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 148 | 608 | 00148_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 158 | 608 | 00158_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 168 | 608 | 00168_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 178 | 608 | 00178_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 188 | 608 | 00188_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 198 | 608 | 00198_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 208 | 608 | 00208_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 218 | 608 | 00218_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 228 | 608 | 00228_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 238 | 608 | 00238_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 248 | 608 | 00248_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 258 | 608 | 00258_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 268 | 608 | 00268_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 278 | 608 | 00278_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 288 | 608 | 00288_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 298 | 608 | 00298_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 308 | 608 | 00308_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 318 | 608 | 00318_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 328 | 608 | 00328_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 338 | 608 | 00338_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 348 | 608 | 00348_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 358 | 608 | 00358_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 368 | 608 | 00368_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 378 | 608 | 00378_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 388 | 608 | 00388_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 398 | 608 | 00398_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 408 | 608 | 00408_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 418 | 608 | 00418_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 428 | 608 | 00428_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 438 | 608 | 00438_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 448 | 608 | 00448_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 458 | 608 | 00458_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 468 | 608 | 00468_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 478 | 608 | 00478_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 488 | 608 | 00488_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 498 | 608 | 00498_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 508 | 608 | 00508_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 518 | 608 | 00518_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 528 | 608 | 00528_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 538 | 608 | 00538_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 548 | 608 | 00548_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 558 | 608 | 00558_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 568 | 608 | 00568_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 578 | 608 | 00578_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 588 | 608 | 00588_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 598 | 608 | 00598_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 608 | 608 | 00608_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 618 | 608 | 00618_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 628 | 608 | 00628_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 638 | 608 | 00638_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 648 | 608 | 00648_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 658 | 608 | 00658_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 668 | 608 | 00668_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 678 | 608 | 00678_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 688 | 608 | 00688_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 698 | 608 | 00698_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 708 | 608 | 00708_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 718 | 608 | 00718_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 728 | 608 | 00728_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 738 | 608 | 00738_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 748 | 608 | 00748_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 758 | 608 | 00758_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 768 | 608 | 00768_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 778 | 608 | 00778_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 788 | 608 | 00788_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 798 | 608 | 00798_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 808 | 608 | 00808_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 818 | 608 | 00818_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 828 | 608 | 00828_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 838 | 608 | 00838_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 848 | 608 | 00848_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 858 | 608 | 00858_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 868 | 608 | 00868_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 878 | 608 | 00878_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 888 | 608 | 00888_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 898 | 608 | 00898_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 908 | 608 | 00908_trig_update | Fri Jan 09 00:00:00 1970 PST | Fri Jan 09 00:00:00 1970 | 8 | 8 | foo ! 918 | 608 | 00918_trig_update | Mon Jan 19 00:00:00 1970 PST | Mon Jan 19 00:00:00 1970 | 8 | 8 | foo ! 928 | 608 | 00928_trig_update | Thu Jan 29 00:00:00 1970 PST | Thu Jan 29 00:00:00 1970 | 8 | 8 | foo ! 938 | 608 | 00938_trig_update | Sun Feb 08 00:00:00 1970 PST | Sun Feb 08 00:00:00 1970 | 8 | 8 | foo ! 948 | 608 | 00948_trig_update | Wed Feb 18 00:00:00 1970 PST | Wed Feb 18 00:00:00 1970 | 8 | 8 | foo ! 958 | 608 | 00958_trig_update | Sat Feb 28 00:00:00 1970 PST | Sat Feb 28 00:00:00 1970 | 8 | 8 | foo ! 968 | 608 | 00968_trig_update | Tue Mar 10 00:00:00 1970 PST | Tue Mar 10 00:00:00 1970 | 8 | 8 | foo ! 978 | 608 | 00978_trig_update | Fri Mar 20 00:00:00 1970 PST | Fri Mar 20 00:00:00 1970 | 8 | 8 | foo ! 988 | 608 | 00988_trig_update | Mon Mar 30 00:00:00 1970 PST | Mon Mar 30 00:00:00 1970 | 8 | 8 | foo ! 998 | 608 | 00998_trig_update | Thu Apr 09 00:00:00 1970 PST | Thu Apr 09 00:00:00 1970 | 8 | 8 | foo ! 1008 | 708 | 0000800008_trig_update | | | | ft2 | ! 1018 | 708 | 0001800018_trig_update | | | | ft2 | ! (102 rows) ! ! -- Test errors thrown on remote side during update ! ALTER TABLE "S 1"."T 1" ADD CONSTRAINT c2positive CHECK (c2 >= 0); ! INSERT INTO ft1(c1, c2) VALUES(11, 12); -- duplicate key ! ERROR: duplicate key value violates unique constraint "t1_pkey" ! DETAIL: Key ("C 1")=(11) already exists. ! CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ! INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT DO NOTHING; -- works ! INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO NOTHING; -- unsupported ! ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ! INSERT INTO ft1(c1, c2) VALUES(11, 12) ON CONFLICT (c1, c2) DO UPDATE SET c3 = 'ffg'; -- unsupported ! ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification ! INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive ! ERROR: new row for relation "T 1" violates check constraint "c2positive" ! DETAIL: Failing row contains (1111, -2, null, null, null, null, ft1 , null). ! CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ! UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive ! ERROR: new row for relation "T 1" violates check constraint "c2positive" ! DETAIL: Failing row contains (1, -1, 00001_trig_update, 1970-01-02 08:00:00+00, 1970-01-02 00:00:00, 1, 1 , foo). ! CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = $2 WHERE ctid = $1 ! -- Test savepoint/rollback behavior ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 0 | 100 ! 1 | 100 ! 4 | 100 ! 6 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 0 | 100 ! 1 | 100 ! 4 | 100 ! 6 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! begin; ! update ft2 set c2 = 42 where c2 = 0; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 4 | 100 ! 6 | 100 ! 42 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! savepoint s1; ! update ft2 set c2 = 44 where c2 = 4; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! release savepoint s1; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! savepoint s2; ! update ft2 set c2 = 46 where c2 = 6; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 42 | 100 ! 44 | 100 ! 46 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! rollback to savepoint s2; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! release savepoint s2; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! savepoint s3; ! update ft2 set c2 = -2 where c2 = 42 and c1 = 10; -- fail on remote side ! ERROR: new row for relation "T 1" violates check constraint "c2positive" ! DETAIL: Failing row contains (10, -2, 00010_trig_update_trig_update, 1970-01-11 08:00:00+00, 1970-01-11 00:00:00, 0, 0 , foo). ! CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = $2 WHERE ctid = $1 ! rollback to savepoint s3; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! release savepoint s3; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! -- none of the above is committed yet remotely ! select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 0 | 100 ! 1 | 100 ! 4 | 100 ! 6 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! commit; ! select c2, count(*) from ft2 where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! select c2, count(*) from "S 1"."T 1" where c2 < 500 group by 1 order by 1; ! c2 | count ! -----+------- ! 1 | 100 ! 6 | 100 ! 42 | 100 ! 44 | 100 ! 100 | 2 ! 101 | 2 ! 104 | 2 ! 106 | 2 ! 201 | 1 ! 204 | 1 ! 303 | 100 ! 403 | 2 ! 407 | 100 ! (13 rows) ! ! -- Above DMLs add data with c6 as NULL in ft1, so test ORDER BY NULLS LAST and NULLs ! -- FIRST behavior here. ! -- ORDER BY DESC NULLS LAST options ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS LAST, "C 1" ASC NULLS LAST ! (5 rows) ! ! SELECT * FROM ft1 ORDER BY c6 DESC NULLS LAST, c1 OFFSET 795 LIMIT 10; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+--------------------+------------------------------+--------------------------+------+------------+----- ! 960 | 42 | 00960_trig_update | Mon Mar 02 00:00:00 1970 PST | Mon Mar 02 00:00:00 1970 | 0 | 0 | foo ! 970 | 42 | 00970_trig_update | Thu Mar 12 00:00:00 1970 PST | Thu Mar 12 00:00:00 1970 | 0 | 0 | foo ! 980 | 42 | 00980_trig_update | Sun Mar 22 00:00:00 1970 PST | Sun Mar 22 00:00:00 1970 | 0 | 0 | foo ! 990 | 42 | 00990_trig_update | Wed Apr 01 00:00:00 1970 PST | Wed Apr 01 00:00:00 1970 | 0 | 0 | foo ! 1000 | 42 | 01000_trig_update | Thu Jan 01 00:00:00 1970 PST | Thu Jan 01 00:00:00 1970 | 0 | 0 | foo ! 1218 | 818 | ggg_trig_update | | | (--; | ft2 | ! 1001 | 101 | 0000100001 | | | | ft2 | ! 1003 | 403 | 0000300003_update3 | | | | ft2 | ! 1004 | 104 | 0000400004 | | | | ft2 | ! 1006 | 106 | 0000600006 | | | | ft2 | ! (10 rows) ! ! -- ORDER BY DESC NULLS FIRST options ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ! QUERY PLAN ! ---------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 DESC NULLS FIRST, "C 1" ASC NULLS LAST ! (5 rows) ! ! SELECT * FROM ft1 ORDER BY c6 DESC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+-----------------+------------------------------+--------------------------+----+------------+----- ! 1020 | 100 | 0002000020 | | | | ft2 | ! 1101 | 201 | aaa | | | | ft2 | ! 1103 | 503 | ccc_update3 | | | | ft2 | ! 1104 | 204 | ddd | | | | ft2 | ! 1208 | 818 | fff_trig_update | | | | ft2 | ! 9 | 509 | 00009_update9 | Sat Jan 10 00:00:00 1970 PST | Sat Jan 10 00:00:00 1970 | 9 | ft2 | foo ! 19 | 509 | 00019_update9 | Tue Jan 20 00:00:00 1970 PST | Tue Jan 20 00:00:00 1970 | 9 | ft2 | foo ! 29 | 509 | 00029_update9 | Fri Jan 30 00:00:00 1970 PST | Fri Jan 30 00:00:00 1970 | 9 | ft2 | foo ! 39 | 509 | 00039_update9 | Mon Feb 09 00:00:00 1970 PST | Mon Feb 09 00:00:00 1970 | 9 | ft2 | foo ! 49 | 509 | 00049_update9 | Thu Feb 19 00:00:00 1970 PST | Thu Feb 19 00:00:00 1970 | 9 | ft2 | foo ! (10 rows) ! ! -- ORDER BY ASC NULLS FIRST options ! EXPLAIN (VERBOSE, COSTS false) SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ! QUERY PLAN ! --------------------------------------------------------------------------------------------------------------------------------- ! Limit ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! -> Foreign Scan on public.ft1 ! Output: c1, c2, c3, c4, c5, c6, c7, c8 ! Remote SQL: SELECT "C 1", c2, c3, c4, c5, c6, c7, c8 FROM "S 1"."T 1" ORDER BY c6 ASC NULLS FIRST, "C 1" ASC NULLS LAST ! (5 rows) ! ! SELECT * FROM ft1 ORDER BY c6 ASC NULLS FIRST, c1 OFFSET 15 LIMIT 10; ! c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 ! ------+-----+-------------------+------------------------------+--------------------------+------+------------+----- ! 1020 | 100 | 0002000020 | | | | ft2 | ! 1101 | 201 | aaa | | | | ft2 | ! 1103 | 503 | ccc_update3 | | | | ft2 | ! 1104 | 204 | ddd | | | | ft2 | ! 1208 | 818 | fff_trig_update | | | | ft2 | ! 1218 | 818 | ggg_trig_update | | | (--; | ft2 | ! 10 | 42 | 00010_trig_update | Sun Jan 11 00:00:00 1970 PST | Sun Jan 11 00:00:00 1970 | 0 | 0 | foo ! 20 | 42 | 00020_trig_update | Wed Jan 21 00:00:00 1970 PST | Wed Jan 21 00:00:00 1970 | 0 | 0 | foo ! 30 | 42 | 00030_trig_update | Sat Jan 31 00:00:00 1970 PST | Sat Jan 31 00:00:00 1970 | 0 | 0 | foo ! 40 | 42 | 00040_trig_update | Tue Feb 10 00:00:00 1970 PST | Tue Feb 10 00:00:00 1970 | 0 | 0 | foo ! (10 rows) ! ! -- =================================================================== ! -- test check constraints ! -- =================================================================== ! -- Consistent check constraints provide consistent results ! ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2positive CHECK (c2 >= 0); ! EXPLAIN (VERBOSE, COSTS false) SELECT count(*) FROM ft1 WHERE c2 < 0; ! QUERY PLAN ! ------------------------------------------------------------------- ! Aggregate ! Output: count(*) ! -> Foreign Scan on public.ft1 ! Remote SQL: SELECT NULL FROM "S 1"."T 1" WHERE ((c2 < 0)) ! (4 rows) ! ! SELECT count(*) FROM ft1 WHERE c2 < 0; ! count ! ------- ! 0 ! (1 row) ! ! SET constraint_exclusion = 'on'; ! EXPLAIN (VERBOSE, COSTS false) SELECT count(*) FROM ft1 WHERE c2 < 0; ! QUERY PLAN ! -------------------------------- ! Aggregate ! Output: count(*) ! -> Result ! One-Time Filter: false ! (4 rows) ! ! SELECT count(*) FROM ft1 WHERE c2 < 0; ! count ! ------- ! 0 ! (1 row) ! ! RESET constraint_exclusion; ! -- check constraint is enforced on the remote side, not locally ! INSERT INTO ft1(c1, c2) VALUES(1111, -2); -- c2positive ! ERROR: new row for relation "T 1" violates check constraint "c2positive" ! DETAIL: Failing row contains (1111, -2, null, null, null, null, ft1 , null). ! CONTEXT: Remote SQL command: INSERT INTO "S 1"."T 1"("C 1", c2, c3, c4, c5, c6, c7, c8) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) ! UPDATE ft1 SET c2 = -c2 WHERE c1 = 1; -- c2positive ! ERROR: new row for relation "T 1" violates check constraint "c2positive" ! DETAIL: Failing row contains (1, -1, 00001_trig_update, 1970-01-02 08:00:00+00, 1970-01-02 00:00:00, 1, 1 , foo). ! CONTEXT: Remote SQL command: UPDATE "S 1"."T 1" SET c2 = $2 WHERE ctid = $1 ! ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2positive; ! -- But inconsistent check constraints provide inconsistent results ! ALTER FOREIGN TABLE ft1 ADD CONSTRAINT ft1_c2negative CHECK (c2 < 0); ! EXPLAIN (VERBOSE, COSTS false) SELECT count(*) FROM ft1 WHERE c2 >= 0; ! QUERY PLAN ! -------------------------------------------------------------------- ! Aggregate ! Output: count(*) ! -> Foreign Scan on public.ft1 ! Remote SQL: SELECT NULL FROM "S 1"."T 1" WHERE ((c2 >= 0)) ! (4 rows) ! ! SELECT count(*) FROM ft1 WHERE c2 >= 0; ! count ! ------- ! 821 ! (1 row) ! ! SET constraint_exclusion = 'on'; ! EXPLAIN (VERBOSE, COSTS false) SELECT count(*) FROM ft1 WHERE c2 >= 0; ! QUERY PLAN ! -------------------------------- ! Aggregate ! Output: count(*) ! -> Result ! One-Time Filter: false ! (4 rows) ! ! SELECT count(*) FROM ft1 WHERE c2 >= 0; ! count ! ------- ! 0 ! (1 row) ! ! RESET constraint_exclusion; ! -- local check constraint is not actually enforced ! INSERT INTO ft1(c1, c2) VALUES(1111, 2); ! UPDATE ft1 SET c2 = c2 + 1 WHERE c1 = 1; ! ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c2negative; ! -- =================================================================== ! -- test serial columns (ie, sequence-based defaults) ! -- =================================================================== ! create table loc1 (f1 serial, f2 text); ! create foreign table rem1 (f1 serial, f2 text) ! server loopback options(table_name 'loc1'); ! select pg_catalog.setval('rem1_f1_seq', 10, false); ! setval ! -------- ! 10 ! (1 row) ! ! insert into loc1(f2) values('hi'); ! insert into rem1(f2) values('hi remote'); ! insert into loc1(f2) values('bye'); ! insert into rem1(f2) values('bye remote'); ! select * from loc1; ! f1 | f2 ! ----+------------ ! 1 | hi ! 10 | hi remote ! 2 | bye ! 11 | bye remote ! (4 rows) ! ! select * from rem1; ! f1 | f2 ! ----+------------ ! 1 | hi ! 10 | hi remote ! 2 | bye ! 11 | bye remote ! (4 rows) ! ! -- =================================================================== ! -- test local triggers ! -- =================================================================== ! -- Trigger functions "borrowed" from triggers regress test. ! CREATE FUNCTION trigger_func() RETURNS trigger LANGUAGE plpgsql AS $$ ! BEGIN ! RAISE NOTICE 'trigger_func(%) called: action = %, when = %, level = %', ! TG_ARGV[0], TG_OP, TG_WHEN, TG_LEVEL; ! RETURN NULL; ! END;$$; ! CREATE TRIGGER trig_stmt_before BEFORE DELETE OR INSERT OR UPDATE ON rem1 ! FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ! CREATE TRIGGER trig_stmt_after AFTER DELETE OR INSERT OR UPDATE ON rem1 ! FOR EACH STATEMENT EXECUTE PROCEDURE trigger_func(); ! CREATE OR REPLACE FUNCTION trigger_data() RETURNS trigger ! LANGUAGE plpgsql AS $$ ! ! declare ! oldnew text[]; ! relid text; ! argstr text; ! begin ! ! relid := TG_relid::regclass; ! argstr := ''; ! for i in 0 .. TG_nargs - 1 loop ! if i > 0 then ! argstr := argstr || ', '; ! end if; ! argstr := argstr || TG_argv[i]; ! end loop; ! ! RAISE NOTICE '%(%) % % % ON %', ! tg_name, argstr, TG_when, TG_level, TG_OP, relid; ! oldnew := '{}'::text[]; ! if TG_OP != 'INSERT' then ! oldnew := array_append(oldnew, format('OLD: %s', OLD)); ! end if; ! ! if TG_OP != 'DELETE' then ! oldnew := array_append(oldnew, format('NEW: %s', NEW)); ! end if; ! ! RAISE NOTICE '%', array_to_string(oldnew, ','); ! ! if TG_OP = 'DELETE' then ! return OLD; ! else ! return NEW; ! end if; ! end; ! $$; ! -- Test basic functionality ! CREATE TRIGGER trig_row_before ! BEFORE INSERT OR UPDATE OR DELETE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! CREATE TRIGGER trig_row_after ! AFTER INSERT OR UPDATE OR DELETE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! delete from rem1; ! NOTICE: trigger_func() called: action = DELETE, when = BEFORE, level = STATEMENT ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 ! NOTICE: OLD: (1,hi) ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 ! NOTICE: OLD: (10,"hi remote") ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 ! NOTICE: OLD: (2,bye) ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW DELETE ON rem1 ! NOTICE: OLD: (11,"bye remote") ! NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 ! NOTICE: OLD: (1,hi) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 ! NOTICE: OLD: (10,"hi remote") ! NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 ! NOTICE: OLD: (2,bye) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW DELETE ON rem1 ! NOTICE: OLD: (11,"bye remote") ! NOTICE: trigger_func() called: action = DELETE, when = AFTER, level = STATEMENT ! insert into rem1 values(1,'insert'); ! NOTICE: trigger_func() called: action = INSERT, when = BEFORE, level = STATEMENT ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 ! NOTICE: NEW: (1,insert) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 ! NOTICE: NEW: (1,insert) ! NOTICE: trigger_func() called: action = INSERT, when = AFTER, level = STATEMENT ! update rem1 set f2 = 'update' where f1 = 1; ! NOTICE: trigger_func() called: action = UPDATE, when = BEFORE, level = STATEMENT ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1 ! NOTICE: OLD: (1,insert),NEW: (1,update) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1 ! NOTICE: OLD: (1,insert),NEW: (1,update) ! NOTICE: trigger_func() called: action = UPDATE, when = AFTER, level = STATEMENT ! update rem1 set f2 = f2 || f2; ! NOTICE: trigger_func() called: action = UPDATE, when = BEFORE, level = STATEMENT ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1 ! NOTICE: OLD: (1,update),NEW: (1,updateupdate) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1 ! NOTICE: OLD: (1,update),NEW: (1,updateupdate) ! NOTICE: trigger_func() called: action = UPDATE, when = AFTER, level = STATEMENT ! -- cleanup ! DROP TRIGGER trig_row_before ON rem1; ! DROP TRIGGER trig_row_after ON rem1; ! DROP TRIGGER trig_stmt_before ON rem1; ! DROP TRIGGER trig_stmt_after ON rem1; ! DELETE from rem1; ! -- Test WHEN conditions ! CREATE TRIGGER trig_row_before_insupd ! BEFORE INSERT OR UPDATE ON rem1 ! FOR EACH ROW ! WHEN (NEW.f2 like '%update%') ! EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! CREATE TRIGGER trig_row_after_insupd ! AFTER INSERT OR UPDATE ON rem1 ! FOR EACH ROW ! WHEN (NEW.f2 like '%update%') ! EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! -- Insert or update not matching: nothing happens ! INSERT INTO rem1 values(1, 'insert'); ! UPDATE rem1 set f2 = 'test'; ! -- Insert or update matching: triggers are fired ! INSERT INTO rem1 values(2, 'update'); ! NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW INSERT ON rem1 ! NOTICE: NEW: (2,update) ! NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW INSERT ON rem1 ! NOTICE: NEW: (2,update) ! UPDATE rem1 set f2 = 'update update' where f1 = '2'; ! NOTICE: trig_row_before_insupd(23, skidoo) BEFORE ROW UPDATE ON rem1 ! NOTICE: OLD: (2,update),NEW: (2,"update update") ! NOTICE: trig_row_after_insupd(23, skidoo) AFTER ROW UPDATE ON rem1 ! NOTICE: OLD: (2,update),NEW: (2,"update update") ! CREATE TRIGGER trig_row_before_delete ! BEFORE DELETE ON rem1 ! FOR EACH ROW ! WHEN (OLD.f2 like '%update%') ! EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! CREATE TRIGGER trig_row_after_delete ! AFTER DELETE ON rem1 ! FOR EACH ROW ! WHEN (OLD.f2 like '%update%') ! EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! -- Trigger is fired for f1=2, not for f1=1 ! DELETE FROM rem1; ! NOTICE: trig_row_before_delete(23, skidoo) BEFORE ROW DELETE ON rem1 ! NOTICE: OLD: (2,"update update") ! NOTICE: trig_row_after_delete(23, skidoo) AFTER ROW DELETE ON rem1 ! NOTICE: OLD: (2,"update update") ! -- cleanup ! DROP TRIGGER trig_row_before_insupd ON rem1; ! DROP TRIGGER trig_row_after_insupd ON rem1; ! DROP TRIGGER trig_row_before_delete ON rem1; ! DROP TRIGGER trig_row_after_delete ON rem1; ! -- Test various RETURN statements in BEFORE triggers. ! CREATE FUNCTION trig_row_before_insupdate() RETURNS TRIGGER AS $$ ! BEGIN ! NEW.f2 := NEW.f2 || ' triggered !'; ! RETURN NEW; ! END ! $$ language plpgsql; ! CREATE TRIGGER trig_row_before_insupd ! BEFORE INSERT OR UPDATE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ! -- The new values should have 'triggered' appended ! INSERT INTO rem1 values(1, 'insert'); ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------- ! 1 | insert triggered ! ! (1 row) ! ! INSERT INTO rem1 values(2, 'insert') RETURNING f2; ! f2 ! -------------------- ! insert triggered ! ! (1 row) ! ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------- ! 1 | insert triggered ! ! 2 | insert triggered ! ! (2 rows) ! ! UPDATE rem1 set f2 = ''; ! SELECT * from loc1; ! f1 | f2 ! ----+-------------- ! 1 | triggered ! ! 2 | triggered ! ! (2 rows) ! ! UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ! f2 ! -------------------- ! skidoo triggered ! ! skidoo triggered ! ! (2 rows) ! ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------- ! 1 | skidoo triggered ! ! 2 | skidoo triggered ! ! (2 rows) ! ! DELETE FROM rem1; ! -- Add a second trigger, to check that the changes are propagated correctly ! -- from trigger to trigger ! CREATE TRIGGER trig_row_before_insupd2 ! BEFORE INSERT OR UPDATE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ! INSERT INTO rem1 values(1, 'insert'); ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------------------- ! 1 | insert triggered ! triggered ! ! (1 row) ! ! INSERT INTO rem1 values(2, 'insert') RETURNING f2; ! f2 ! -------------------------------- ! insert triggered ! triggered ! ! (1 row) ! ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------------------- ! 1 | insert triggered ! triggered ! ! 2 | insert triggered ! triggered ! ! (2 rows) ! ! UPDATE rem1 set f2 = ''; ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------------- ! 1 | triggered ! triggered ! ! 2 | triggered ! triggered ! ! (2 rows) ! ! UPDATE rem1 set f2 = 'skidoo' RETURNING f2; ! f2 ! -------------------------------- ! skidoo triggered ! triggered ! ! skidoo triggered ! triggered ! ! (2 rows) ! ! SELECT * from loc1; ! f1 | f2 ! ----+-------------------------------- ! 1 | skidoo triggered ! triggered ! ! 2 | skidoo triggered ! triggered ! ! (2 rows) ! ! DROP TRIGGER trig_row_before_insupd ON rem1; ! DROP TRIGGER trig_row_before_insupd2 ON rem1; ! DELETE from rem1; ! INSERT INTO rem1 VALUES (1, 'test'); ! -- Test with a trigger returning NULL ! CREATE FUNCTION trig_null() RETURNS TRIGGER AS $$ ! BEGIN ! RETURN NULL; ! END ! $$ language plpgsql; ! CREATE TRIGGER trig_null ! BEFORE INSERT OR UPDATE OR DELETE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trig_null(); ! -- Nothing should have changed. ! INSERT INTO rem1 VALUES (2, 'test2'); ! SELECT * from loc1; ! f1 | f2 ! ----+------ ! 1 | test ! (1 row) ! ! UPDATE rem1 SET f2 = 'test2'; ! SELECT * from loc1; ! f1 | f2 ! ----+------ ! 1 | test ! (1 row) ! ! DELETE from rem1; ! SELECT * from loc1; ! f1 | f2 ! ----+------ ! 1 | test ! (1 row) ! ! DROP TRIGGER trig_null ON rem1; ! DELETE from rem1; ! -- Test a combination of local and remote triggers ! CREATE TRIGGER trig_row_before ! BEFORE INSERT OR UPDATE OR DELETE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! CREATE TRIGGER trig_row_after ! AFTER INSERT OR UPDATE OR DELETE ON rem1 ! FOR EACH ROW EXECUTE PROCEDURE trigger_data(23,'skidoo'); ! CREATE TRIGGER trig_local_before BEFORE INSERT OR UPDATE ON loc1 ! FOR EACH ROW EXECUTE PROCEDURE trig_row_before_insupdate(); ! INSERT INTO rem1(f2) VALUES ('test'); ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 ! NOTICE: NEW: (12,test) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 ! NOTICE: NEW: (12,"test triggered !") ! UPDATE rem1 SET f2 = 'testo'; ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW UPDATE ON rem1 ! NOTICE: OLD: (12,"test triggered !"),NEW: (12,testo) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW UPDATE ON rem1 ! NOTICE: OLD: (12,"test triggered !"),NEW: (12,"testo triggered !") ! -- Test returning a system attribute ! INSERT INTO rem1(f2) VALUES ('test') RETURNING ctid; ! NOTICE: trig_row_before(23, skidoo) BEFORE ROW INSERT ON rem1 ! NOTICE: NEW: (13,test) ! NOTICE: trig_row_after(23, skidoo) AFTER ROW INSERT ON rem1 ! NOTICE: NEW: (13,"test triggered !") ! ctid ! -------- ! (0,27) ! (1 row) ! ! -- =================================================================== ! -- test inheritance features ! -- =================================================================== ! CREATE TABLE a (aa TEXT); ! CREATE TABLE loct (aa TEXT, bb TEXT); ! CREATE FOREIGN TABLE b (bb TEXT) INHERITS (a) ! SERVER loopback OPTIONS (table_name 'loct'); ! INSERT INTO a(aa) VALUES('aaa'); ! INSERT INTO a(aa) VALUES('aaaa'); ! INSERT INTO a(aa) VALUES('aaaaa'); ! INSERT INTO b(aa) VALUES('bbb'); ! INSERT INTO b(aa) VALUES('bbbb'); ! INSERT INTO b(aa) VALUES('bbbbb'); ! SELECT tableoid::regclass, * FROM a; ! tableoid | aa ! ----------+------- ! a | aaa ! a | aaaa ! a | aaaaa ! b | bbb ! b | bbbb ! b | bbbbb ! (6 rows) ! ! SELECT tableoid::regclass, * FROM b; ! tableoid | aa | bb ! ----------+-------+---- ! b | bbb | ! b | bbbb | ! b | bbbbb | ! (3 rows) ! ! SELECT tableoid::regclass, * FROM ONLY a; ! tableoid | aa ! ----------+------- ! a | aaa ! a | aaaa ! a | aaaaa ! (3 rows) ! ! UPDATE a SET aa = 'zzzzzz' WHERE aa LIKE 'aaaa%'; ! SELECT tableoid::regclass, * FROM a; ! tableoid | aa ! ----------+-------- ! a | aaa ! a | zzzzzz ! a | zzzzzz ! b | bbb ! b | bbbb ! b | bbbbb ! (6 rows) ! ! SELECT tableoid::regclass, * FROM b; ! tableoid | aa | bb ! ----------+-------+---- ! b | bbb | ! b | bbbb | ! b | bbbbb | ! (3 rows) ! ! SELECT tableoid::regclass, * FROM ONLY a; ! tableoid | aa ! ----------+-------- ! a | aaa ! a | zzzzzz ! a | zzzzzz ! (3 rows) ! ! UPDATE b SET aa = 'new'; ! SELECT tableoid::regclass, * FROM a; ! tableoid | aa ! ----------+-------- ! a | aaa ! a | zzzzzz ! a | zzzzzz ! b | new ! b | new ! b | new ! (6 rows) ! ! SELECT tableoid::regclass, * FROM b; ! tableoid | aa | bb ! ----------+-----+---- ! b | new | ! b | new | ! b | new | ! (3 rows) ! ! SELECT tableoid::regclass, * FROM ONLY a; ! tableoid | aa ! ----------+-------- ! a | aaa ! a | zzzzzz ! a | zzzzzz ! (3 rows) ! ! UPDATE a SET aa = 'newtoo'; ! SELECT tableoid::regclass, * FROM a; ! tableoid | aa ! ----------+-------- ! a | newtoo ! a | newtoo ! a | newtoo ! b | newtoo ! b | newtoo ! b | newtoo ! (6 rows) ! ! SELECT tableoid::regclass, * FROM b; ! tableoid | aa | bb ! ----------+--------+---- ! b | newtoo | ! b | newtoo | ! b | newtoo | ! (3 rows) ! ! SELECT tableoid::regclass, * FROM ONLY a; ! tableoid | aa ! ----------+-------- ! a | newtoo ! a | newtoo ! a | newtoo ! (3 rows) ! ! DELETE FROM a; ! SELECT tableoid::regclass, * FROM a; ! tableoid | aa ! ----------+---- ! (0 rows) ! ! SELECT tableoid::regclass, * FROM b; ! tableoid | aa | bb ! ----------+----+---- ! (0 rows) ! ! SELECT tableoid::regclass, * FROM ONLY a; ! tableoid | aa ! ----------+---- ! (0 rows) ! ! DROP TABLE a CASCADE; ! NOTICE: drop cascades to foreign table b ! DROP TABLE loct; ! -- Check SELECT FOR UPDATE/SHARE with an inherited source table ! create table loct1 (f1 int, f2 int, f3 int); ! create table loct2 (f1 int, f2 int, f3 int); ! create table foo (f1 int, f2 int); ! create foreign table foo2 (f3 int) inherits (foo) ! server loopback options (table_name 'loct1'); ! create table bar (f1 int, f2 int); ! create foreign table bar2 (f3 int) inherits (bar) ! server loopback options (table_name 'loct2'); ! insert into foo values(1,1); ! insert into foo values(3,3); ! insert into foo2 values(2,2,2); ! insert into foo2 values(4,4,4); ! insert into bar values(1,11); ! insert into bar values(2,22); ! insert into bar values(6,66); ! insert into bar2 values(3,33,33); ! insert into bar2 values(4,44,44); ! insert into bar2 values(7,77,77); ! explain (verbose, costs off) ! select * from bar where f1 in (select f1 from foo) for update; ! QUERY PLAN ! ---------------------------------------------------------------------------------------------- ! LockRows ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid ! -> Hash Join ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid ! Hash Cond: (bar.f1 = foo.f1) ! -> Append ! -> Seq Scan on public.bar ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid ! -> Foreign Scan on public.bar2 ! Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE ! -> Hash ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> HashAggregate ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! Group Key: foo.f1 ! -> Append ! -> Seq Scan on public.foo ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> Foreign Scan on public.foo2 ! Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 ! (22 rows) ! ! select * from bar where f1 in (select f1 from foo) for update; ! f1 | f2 ! ----+---- ! 1 | 11 ! 2 | 22 ! 3 | 33 ! 4 | 44 ! (4 rows) ! ! explain (verbose, costs off) ! select * from bar where f1 in (select f1 from foo) for share; ! QUERY PLAN ! ---------------------------------------------------------------------------------------------- ! LockRows ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid ! -> Hash Join ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid, foo.ctid, foo.*, foo.tableoid ! Hash Cond: (bar.f1 = foo.f1) ! -> Append ! -> Seq Scan on public.bar ! Output: bar.f1, bar.f2, bar.ctid, bar.*, bar.tableoid ! -> Foreign Scan on public.bar2 ! Output: bar2.f1, bar2.f2, bar2.ctid, bar2.*, bar2.tableoid ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR SHARE ! -> Hash ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> HashAggregate ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! Group Key: foo.f1 ! -> Append ! -> Seq Scan on public.foo ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> Foreign Scan on public.foo2 ! Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 ! (22 rows) ! ! select * from bar where f1 in (select f1 from foo) for share; ! f1 | f2 ! ----+---- ! 1 | 11 ! 2 | 22 ! 3 | 33 ! 4 | 44 ! (4 rows) ! ! -- Check UPDATE with inherited target and an inherited source table ! explain (verbose, costs off) ! update bar set f2 = f2 + 100 where f1 in (select f1 from foo); ! QUERY PLAN ! --------------------------------------------------------------------------------------------- ! Update on public.bar ! Update on public.bar ! Foreign Update on public.bar2 ! Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 ! -> Hash Join ! Output: bar.f1, (bar.f2 + 100), bar.ctid, foo.ctid, foo.*, foo.tableoid ! Hash Cond: (bar.f1 = foo.f1) ! -> Seq Scan on public.bar ! Output: bar.f1, bar.f2, bar.ctid ! -> Hash ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> HashAggregate ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! Group Key: foo.f1 ! -> Append ! -> Seq Scan on public.foo ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> Foreign Scan on public.foo2 ! Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 ! -> Hash Join ! Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, foo.ctid, foo.*, foo.tableoid ! Hash Cond: (bar2.f1 = foo.f1) ! -> Foreign Scan on public.bar2 ! Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE ! -> Hash ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> HashAggregate ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! Group Key: foo.f1 ! -> Append ! -> Seq Scan on public.foo ! Output: foo.ctid, foo.*, foo.tableoid, foo.f1 ! -> Foreign Scan on public.foo2 ! Output: foo2.ctid, foo2.*, foo2.tableoid, foo2.f1 ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct1 ! (37 rows) ! ! update bar set f2 = f2 + 100 where f1 in (select f1 from foo); ! select tableoid::regclass, * from bar order by 1,2; ! tableoid | f1 | f2 ! ----------+----+----- ! bar | 1 | 111 ! bar | 2 | 122 ! bar | 6 | 66 ! bar2 | 3 | 133 ! bar2 | 4 | 144 ! bar2 | 7 | 77 ! (6 rows) ! ! -- Check UPDATE with inherited target and an appendrel subquery ! explain (verbose, costs off) ! update bar set f2 = f2 + 100 ! from ! ( select f1 from foo union all select f1+3 from foo ) ss ! where bar.f1 = ss.f1; ! QUERY PLAN ! -------------------------------------------------------------------------------------- ! Update on public.bar ! Update on public.bar ! Foreign Update on public.bar2 ! Remote SQL: UPDATE public.loct2 SET f2 = $2 WHERE ctid = $1 ! -> Hash Join ! Output: bar.f1, (bar.f2 + 100), bar.ctid, (ROW(foo.f1)) ! Hash Cond: (foo.f1 = bar.f1) ! -> Append ! -> Seq Scan on public.foo ! Output: ROW(foo.f1), foo.f1 ! -> Foreign Scan on public.foo2 ! Output: ROW(foo2.f1), foo2.f1 ! Remote SQL: SELECT f1 FROM public.loct1 ! -> Seq Scan on public.foo foo_1 ! Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3) ! -> Foreign Scan on public.foo2 foo2_1 ! Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3) ! Remote SQL: SELECT f1 FROM public.loct1 ! -> Hash ! Output: bar.f1, bar.f2, bar.ctid ! -> Seq Scan on public.bar ! Output: bar.f1, bar.f2, bar.ctid ! -> Merge Join ! Output: bar2.f1, (bar2.f2 + 100), bar2.f3, bar2.ctid, (ROW(foo.f1)) ! Merge Cond: (bar2.f1 = foo.f1) ! -> Sort ! Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid ! Sort Key: bar2.f1 ! -> Foreign Scan on public.bar2 ! Output: bar2.f1, bar2.f2, bar2.f3, bar2.ctid ! Remote SQL: SELECT f1, f2, f3, ctid FROM public.loct2 FOR UPDATE ! -> Sort ! Output: (ROW(foo.f1)), foo.f1 ! Sort Key: foo.f1 ! -> Append ! -> Seq Scan on public.foo ! Output: ROW(foo.f1), foo.f1 ! -> Foreign Scan on public.foo2 ! Output: ROW(foo2.f1), foo2.f1 ! Remote SQL: SELECT f1 FROM public.loct1 ! -> Seq Scan on public.foo foo_1 ! Output: ROW((foo_1.f1 + 3)), (foo_1.f1 + 3) ! -> Foreign Scan on public.foo2 foo2_1 ! Output: ROW((foo2_1.f1 + 3)), (foo2_1.f1 + 3) ! Remote SQL: SELECT f1 FROM public.loct1 ! (45 rows) ! ! update bar set f2 = f2 + 100 ! from ! ( select f1 from foo union all select f1+3 from foo ) ss ! where bar.f1 = ss.f1; ! select tableoid::regclass, * from bar order by 1,2; ! tableoid | f1 | f2 ! ----------+----+----- ! bar | 1 | 211 ! bar | 2 | 222 ! bar | 6 | 166 ! bar2 | 3 | 233 ! bar2 | 4 | 244 ! bar2 | 7 | 177 ! (6 rows) ! ! -- Test forcing the remote server to produce sorted data for a merge join, ! -- but the foreign table is an inheritance child. ! truncate table loct1; ! truncate table only foo; ! \set num_rows_foo 2000 ! insert into loct1 select generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2), generate_series(0, :num_rows_foo, 2); ! insert into foo select generate_series(1, :num_rows_foo, 2), generate_series(1, :num_rows_foo, 2); ! SET enable_hashjoin to false; ! SET enable_nestloop to false; ! alter foreign table foo2 options (use_remote_estimate 'true'); ! create index i_loct1_f1 on loct1(f1); ! create index i_foo_f1 on foo(f1); ! analyze foo; ! analyze loct1; ! -- inner join; expressions in the clauses appear in the equivalence class list ! explain (verbose, costs off) ! select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------- ! Limit ! Output: foo.f1, loct1.f1, foo.f2 ! -> Sort ! Output: foo.f1, loct1.f1, foo.f2 ! Sort Key: foo.f2 ! -> Merge Join ! Output: foo.f1, loct1.f1, foo.f2 ! Merge Cond: (foo.f1 = loct1.f1) ! -> Merge Append ! Sort Key: foo.f1 ! -> Index Scan using i_foo_f1 on public.foo ! Output: foo.f1, foo.f2 ! -> Foreign Scan on public.foo2 ! Output: foo2.f1, foo2.f2 ! Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST ! -> Index Only Scan using i_loct1_f1 on public.loct1 ! Output: loct1.f1 ! (17 rows) ! ! select foo.f1, loct1.f1 from foo join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; ! f1 | f1 ! ----+---- ! 20 | 20 ! 22 | 22 ! 24 | 24 ! 26 | 26 ! 28 | 28 ! 30 | 30 ! 32 | 32 ! 34 | 34 ! 36 | 36 ! 38 | 38 ! (10 rows) ! ! -- outer join; expressions in the clauses do not appear in equivalence class ! -- list but no output change as compared to the previous query ! explain (verbose, costs off) ! select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; ! QUERY PLAN ! -------------------------------------------------------------------------------------------------- ! Limit ! Output: foo.f1, loct1.f1, foo.f2 ! -> Sort ! Output: foo.f1, loct1.f1, foo.f2 ! Sort Key: foo.f2 ! -> Merge Left Join ! Output: foo.f1, loct1.f1, foo.f2 ! Merge Cond: (foo.f1 = loct1.f1) ! -> Merge Append ! Sort Key: foo.f1 ! -> Index Scan using i_foo_f1 on public.foo ! Output: foo.f1, foo.f2 ! -> Foreign Scan on public.foo2 ! Output: foo2.f1, foo2.f2 ! Remote SQL: SELECT f1, f2 FROM public.loct1 ORDER BY f1 ASC NULLS LAST ! -> Index Only Scan using i_loct1_f1 on public.loct1 ! Output: loct1.f1 ! (17 rows) ! ! select foo.f1, loct1.f1 from foo left join loct1 on (foo.f1 = loct1.f1) order by foo.f2 offset 10 limit 10; ! f1 | f1 ! ----+---- ! 10 | 10 ! 11 | ! 12 | 12 ! 13 | ! 14 | 14 ! 15 | ! 16 | 16 ! 17 | ! 18 | 18 ! 19 | ! (10 rows) ! ! RESET enable_hashjoin; ! RESET enable_nestloop; ! -- Test that WHERE CURRENT OF is not supported ! begin; ! declare c cursor for select * from bar where f1 = 7; ! fetch from c; ! f1 | f2 ! ----+----- ! 7 | 177 ! (1 row) ! ! update bar set f2 = null where current of c; ! ERROR: WHERE CURRENT OF is not supported for this table type ! rollback; ! drop table foo cascade; ! NOTICE: drop cascades to foreign table foo2 ! drop table bar cascade; ! NOTICE: drop cascades to foreign table bar2 ! drop table loct1; ! drop table loct2; ! -- =================================================================== ! -- test IMPORT FOREIGN SCHEMA ! -- =================================================================== ! CREATE SCHEMA import_source; ! CREATE TABLE import_source.t1 (c1 int, c2 varchar NOT NULL); ! CREATE TABLE import_source.t2 (c1 int default 42, c2 varchar NULL, c3 text collate "POSIX"); ! CREATE TYPE typ1 AS (m1 int, m2 varchar); ! CREATE TABLE import_source.t3 (c1 timestamptz default now(), c2 typ1); ! CREATE TABLE import_source."x 4" (c1 float8, "C 2" text, c3 varchar(42)); ! CREATE TABLE import_source."x 5" (c1 float8); ! ALTER TABLE import_source."x 5" DROP COLUMN c1; ! CREATE SCHEMA import_dest1; ! IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest1; ! \det+ import_dest1.* ! List of foreign tables ! Schema | Table | Server | FDW Options | Description ! --------------+-------+----------+-------------------------------------------------+------------- ! import_dest1 | t1 | loopback | (schema_name 'import_source', table_name 't1') | ! import_dest1 | t2 | loopback | (schema_name 'import_source', table_name 't2') | ! import_dest1 | t3 | loopback | (schema_name 'import_source', table_name 't3') | ! import_dest1 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | ! import_dest1 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | ! (5 rows) ! ! \d import_dest1.* ! Foreign table "import_dest1.t1" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+-----------+-------------------- ! c1 | integer | | (column_name 'c1') ! c2 | character varying | not null | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't1') ! ! Foreign table "import_dest1.t2" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+---------------+-------------------- ! c1 | integer | | (column_name 'c1') ! c2 | character varying | | (column_name 'c2') ! c3 | text | collate POSIX | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't2') ! ! Foreign table "import_dest1.t3" ! Column | Type | Modifiers | FDW Options ! --------+--------------------------+-----------+-------------------- ! c1 | timestamp with time zone | | (column_name 'c1') ! c2 | typ1 | | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't3') ! ! Foreign table "import_dest1.x 4" ! Column | Type | Modifiers | FDW Options ! --------+-----------------------+-----------+--------------------- ! c1 | double precision | | (column_name 'c1') ! C 2 | text | | (column_name 'C 2') ! c3 | character varying(42) | | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 4') ! ! Foreign table "import_dest1.x 5" ! Column | Type | Modifiers | FDW Options ! --------+------+-----------+------------- ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 5') ! ! -- Options ! CREATE SCHEMA import_dest2; ! IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest2 ! OPTIONS (import_default 'true'); ! \det+ import_dest2.* ! List of foreign tables ! Schema | Table | Server | FDW Options | Description ! --------------+-------+----------+-------------------------------------------------+------------- ! import_dest2 | t1 | loopback | (schema_name 'import_source', table_name 't1') | ! import_dest2 | t2 | loopback | (schema_name 'import_source', table_name 't2') | ! import_dest2 | t3 | loopback | (schema_name 'import_source', table_name 't3') | ! import_dest2 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | ! import_dest2 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | ! (5 rows) ! ! \d import_dest2.* ! Foreign table "import_dest2.t1" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+-----------+-------------------- ! c1 | integer | | (column_name 'c1') ! c2 | character varying | not null | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't1') ! ! Foreign table "import_dest2.t2" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+---------------+-------------------- ! c1 | integer | default 42 | (column_name 'c1') ! c2 | character varying | | (column_name 'c2') ! c3 | text | collate POSIX | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't2') ! ! Foreign table "import_dest2.t3" ! Column | Type | Modifiers | FDW Options ! --------+--------------------------+---------------+-------------------- ! c1 | timestamp with time zone | default now() | (column_name 'c1') ! c2 | typ1 | | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't3') ! ! Foreign table "import_dest2.x 4" ! Column | Type | Modifiers | FDW Options ! --------+-----------------------+-----------+--------------------- ! c1 | double precision | | (column_name 'c1') ! C 2 | text | | (column_name 'C 2') ! c3 | character varying(42) | | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 4') ! ! Foreign table "import_dest2.x 5" ! Column | Type | Modifiers | FDW Options ! --------+------+-----------+------------- ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 5') ! ! CREATE SCHEMA import_dest3; ! IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest3 ! OPTIONS (import_collate 'false', import_not_null 'false'); ! \det+ import_dest3.* ! List of foreign tables ! Schema | Table | Server | FDW Options | Description ! --------------+-------+----------+-------------------------------------------------+------------- ! import_dest3 | t1 | loopback | (schema_name 'import_source', table_name 't1') | ! import_dest3 | t2 | loopback | (schema_name 'import_source', table_name 't2') | ! import_dest3 | t3 | loopback | (schema_name 'import_source', table_name 't3') | ! import_dest3 | x 4 | loopback | (schema_name 'import_source', table_name 'x 4') | ! import_dest3 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | ! (5 rows) ! ! \d import_dest3.* ! Foreign table "import_dest3.t1" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+-----------+-------------------- ! c1 | integer | | (column_name 'c1') ! c2 | character varying | | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't1') ! ! Foreign table "import_dest3.t2" ! Column | Type | Modifiers | FDW Options ! --------+-------------------+-----------+-------------------- ! c1 | integer | | (column_name 'c1') ! c2 | character varying | | (column_name 'c2') ! c3 | text | | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't2') ! ! Foreign table "import_dest3.t3" ! Column | Type | Modifiers | FDW Options ! --------+--------------------------+-----------+-------------------- ! c1 | timestamp with time zone | | (column_name 'c1') ! c2 | typ1 | | (column_name 'c2') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 't3') ! ! Foreign table "import_dest3.x 4" ! Column | Type | Modifiers | FDW Options ! --------+-----------------------+-----------+--------------------- ! c1 | double precision | | (column_name 'c1') ! C 2 | text | | (column_name 'C 2') ! c3 | character varying(42) | | (column_name 'c3') ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 4') ! ! Foreign table "import_dest3.x 5" ! Column | Type | Modifiers | FDW Options ! --------+------+-----------+------------- ! Server: loopback ! FDW Options: (schema_name 'import_source', table_name 'x 5') ! ! -- Check LIMIT TO and EXCEPT ! CREATE SCHEMA import_dest4; ! IMPORT FOREIGN SCHEMA import_source LIMIT TO (t1, nonesuch) ! FROM SERVER loopback INTO import_dest4; ! \det+ import_dest4.* ! List of foreign tables ! Schema | Table | Server | FDW Options | Description ! --------------+-------+----------+------------------------------------------------+------------- ! import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | ! (1 row) ! ! IMPORT FOREIGN SCHEMA import_source EXCEPT (t1, "x 4", nonesuch) ! FROM SERVER loopback INTO import_dest4; ! \det+ import_dest4.* ! List of foreign tables ! Schema | Table | Server | FDW Options | Description ! --------------+-------+----------+-------------------------------------------------+------------- ! import_dest4 | t1 | loopback | (schema_name 'import_source', table_name 't1') | ! import_dest4 | t2 | loopback | (schema_name 'import_source', table_name 't2') | ! import_dest4 | t3 | loopback | (schema_name 'import_source', table_name 't3') | ! import_dest4 | x 5 | loopback | (schema_name 'import_source', table_name 'x 5') | ! (4 rows) ! ! -- Assorted error cases ! IMPORT FOREIGN SCHEMA import_source FROM SERVER loopback INTO import_dest4; ! ERROR: relation "t1" already exists ! CONTEXT: importing foreign table "t1" ! IMPORT FOREIGN SCHEMA nonesuch FROM SERVER loopback INTO import_dest4; ! ERROR: schema "nonesuch" is not present on foreign server "loopback" ! IMPORT FOREIGN SCHEMA nonesuch FROM SERVER loopback INTO notthere; ! ERROR: schema "notthere" does not exist ! IMPORT FOREIGN SCHEMA nonesuch FROM SERVER nowhere INTO notthere; ! ERROR: server "nowhere" does not exist ! -- Check case of a type present only on the remote server. ! -- We can fake this by dropping the type locally in our transaction. ! CREATE TYPE "Colors" AS ENUM ('red', 'green', 'blue'); ! CREATE TABLE import_source.t5 (c1 int, c2 text collate "C", "Col" "Colors"); ! CREATE SCHEMA import_dest5; ! BEGIN; ! DROP TYPE "Colors" CASCADE; ! NOTICE: drop cascades to table import_source.t5 column Col ! IMPORT FOREIGN SCHEMA import_source LIMIT TO (t5) ! FROM SERVER loopback INTO import_dest5; -- ERROR ! ERROR: type "public.Colors" does not exist ! LINE 4: "Col" public."Colors" OPTIONS (column_name 'Col') ! ^ ! QUERY: CREATE FOREIGN TABLE t5 ( ! c1 integer OPTIONS (column_name 'c1'), ! c2 text OPTIONS (column_name 'c2') COLLATE pg_catalog."C", ! "Col" public."Colors" OPTIONS (column_name 'Col') ! ) SERVER loopback ! OPTIONS (schema_name 'import_source', table_name 't5'); ! CONTEXT: importing foreign table "t5" ! ROLLBACK; ! BEGIN; ! CREATE SERVER fetch101 FOREIGN DATA WRAPPER postgres_fdw OPTIONS( fetch_size '101' ); ! SELECT count(*) ! FROM pg_foreign_server ! WHERE srvname = 'fetch101' ! AND srvoptions @> array['fetch_size=101']; ! count ! ------- ! 1 ! (1 row) ! ! ALTER SERVER fetch101 OPTIONS( SET fetch_size '202' ); ! SELECT count(*) ! FROM pg_foreign_server ! WHERE srvname = 'fetch101' ! AND srvoptions @> array['fetch_size=101']; ! count ! ------- ! 0 ! (1 row) ! ! SELECT count(*) ! FROM pg_foreign_server ! WHERE srvname = 'fetch101' ! AND srvoptions @> array['fetch_size=202']; ! count ! ------- ! 1 ! (1 row) ! ! CREATE FOREIGN TABLE table30000 ( x int ) SERVER fetch101 OPTIONS ( fetch_size '30000' ); ! SELECT COUNT(*) ! FROM pg_foreign_table ! WHERE ftrelid = 'table30000'::regclass ! AND ftoptions @> array['fetch_size=30000']; ! count ! ------- ! 1 ! (1 row) ! ! ALTER FOREIGN TABLE table30000 OPTIONS ( SET fetch_size '60000'); ! SELECT COUNT(*) ! FROM pg_foreign_table ! WHERE ftrelid = 'table30000'::regclass ! AND ftoptions @> array['fetch_size=30000']; ! count ! ------- ! 0 ! (1 row) ! ! SELECT COUNT(*) ! FROM pg_foreign_table ! WHERE ftrelid = 'table30000'::regclass ! AND ftoptions @> array['fetch_size=60000']; ! count ! ------- ! 1 ! (1 row) ! ! ROLLBACK; ! -- Cleanup ! DROP OWNED BY view_owner; ! DROP USER view_owner; --- 187,200 ---- -- To exercise multiple code paths, we use local stats on ft1 -- and remote-estimate mode on ft2. ANALYZE ft1; + ERROR: cache lookup failed for foreign server 1609863456 ALTER FOREIGN TABLE ft2 OPTIONS (use_remote_estimate 'true'); -- =================================================================== -- simple queries -- =================================================================== -- single table without alias EXPLAIN (COSTS false) SELECT * FROM ft1 ORDER BY c3, c1 OFFSET 100 LIMIT 10; ! server closed the connection unexpectedly ! This probably means the server terminated abnormally ! before or while processing the request. ! connection to server was lost ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="postgres_fdw.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="postgres_fdw.out" test postgres_fdw ... FAILED (test process exited with exit code 2) --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="tablefunc.diffs" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="tablefunc.diffs" *** /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 ====================================================================== --------------020302030909030204070803 Content-Type: text/plain; charset=UTF-8; name="tablefunc.out" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="tablefunc.out" test tablefunc ... FAILED (test process exited with exit code 2) --------------020302030909030204070803 Content-Type: text/plain Content-Disposition: inline Content-Transfer-Encoding: 8bit MIME-Version: 1.0 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers --------------020302030909030204070803--