@ -3,7 +3,7 @@ use strict;
use warnings ;
use PostgresNode ;
use TestLib ;
use Test::More tests = > 24 ;
use Test::More tests = > 51 ;
# setup
@ -48,7 +48,6 @@ $node_subscriber1->safe_psql('postgres',
"CREATE TABLE tab1 (c text, a int PRIMARY KEY, b text) PARTITION BY LIST (a)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab1_1 (b text, c text DEFAULT 'sub1_tab1', a int NOT NULL)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"ALTER TABLE tab1 ATTACH PARTITION tab1_1 FOR VALUES IN (1, 2, 3)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
@ -87,6 +86,8 @@ $node_subscriber1->poll_query_until('postgres', $synced_query)
$ node_subscriber2 - > poll_query_until ( 'postgres' , $ synced_query )
or die "Timed out while waiting for subscriber to synchronize data" ;
# Tests for replication using leaf partition identity and schema
# insert
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab1 VALUES (1)" ) ;
@ -260,3 +261,296 @@ is($result, qq(), 'truncate of tab1_1 replicated');
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab1 ORDER BY 1" ) ;
is ( $ result , qq( ) , 'truncate of tab1 replicated' ) ;
# Tests for replication using root table identity and schema
# publisher
$ node_publisher - > safe_psql ( 'postgres' ,
"DROP PUBLICATION pub1" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2 (a int PRIMARY KEY, b text) PARTITION BY LIST (a)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2_1 (b text, a int NOT NULL)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"ALTER TABLE tab2 ATTACH PARTITION tab2_1 FOR VALUES IN (0, 1, 2, 3)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2_2 PARTITION OF tab2 FOR VALUES IN (5, 6)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab3 (a int PRIMARY KEY, b text) PARTITION BY LIST (a)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab3_1 PARTITION OF tab3 FOR VALUES IN (0, 1, 2, 3, 5, 6)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"ALTER PUBLICATION pub_all SET (publish_via_partition_root = true)" ) ;
# Note: tab3_1's parent is not in the publication, in which case its
# changes are published using own identity.
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE PUBLICATION pub_viaroot FOR TABLE tab2, tab3_1 WITH (publish_via_partition_root = true)" ) ;
# subscriber 1
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"DROP SUBSCRIPTION sub1" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2 (a int PRIMARY KEY, c text DEFAULT 'sub1_tab2', b text) PARTITION BY RANGE (a)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2_1 (c text DEFAULT 'sub1_tab2', b text, a int NOT NULL)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"ALTER TABLE tab2 ATTACH PARTITION tab2_1 FOR VALUES FROM (0) TO (10)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab3_1 (c text DEFAULT 'sub1_tab3_1', b text, a int NOT NULL PRIMARY KEY)" ) ;
$ node_subscriber1 - > safe_psql ( 'postgres' ,
"CREATE SUBSCRIPTION sub_viaroot CONNECTION '$publisher_connstr' PUBLICATION pub_viaroot" ) ;
# subscriber 2
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"DROP TABLE tab1" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab1 (a int PRIMARY KEY, c text DEFAULT 'sub2_tab1', b text) PARTITION BY HASH (a)" ) ;
# Note: tab1's partitions are named tab1_1 and tab1_2 on the publisher.
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab1_part1 (b text, c text, a int NOT NULL)" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"ALTER TABLE tab1 ATTACH PARTITION tab1_part1 FOR VALUES WITH (MODULUS 2, REMAINDER 0)" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab1_part2 PARTITION OF tab1 FOR VALUES WITH (MODULUS 2, REMAINDER 1)" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab2 (a int PRIMARY KEY, c text DEFAULT 'sub2_tab2', b text)" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab3 (a int PRIMARY KEY, c text DEFAULT 'sub2_tab3', b text)" ) ;
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"CREATE TABLE tab3_1 (a int PRIMARY KEY, c text DEFAULT 'sub2_tab3_1', b text)" ) ;
# Publication that sub2 points to now publishes via root, so must update
# subscription target relations.
$ node_subscriber2 - > safe_psql ( 'postgres' ,
"ALTER SUBSCRIPTION sub2 REFRESH PUBLICATION" ) ;
# Wait for initial sync of all subscriptions
$ node_subscriber1 - > poll_query_until ( 'postgres' , $ synced_query )
or die "Timed out while waiting for subscriber to synchronize data" ;
$ node_subscriber2 - > poll_query_until ( 'postgres' , $ synced_query )
or die "Timed out while waiting for subscriber to synchronize data" ;
# insert
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab1 VALUES (1), (0)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab1_1 (a) VALUES (3)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab1_2 VALUES (5)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab2 VALUES (1), (0), (3), (5)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab3 VALUES (1), (0), (3), (5)" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab2|0
sub1_tab2 | 1
sub1_tab2 | 3
sub1_tab2 | 5 ) , 'inserts into tab2 replicated' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3_1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab3_1|0
sub1_tab3_1 | 1
sub1_tab3_1 | 3
sub1_tab3_1 | 5 ) , 'inserts into tab3_1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab1|0
sub2_tab1 | 1
sub2_tab1 | 3
sub2_tab1 | 5 ) , 'inserts into tab1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab2|0
sub2_tab2 | 1
sub2_tab2 | 3
sub2_tab2 | 5 ) , 'inserts into tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab3|0
sub2_tab3 | 1
sub2_tab3 | 3
sub2_tab3 | 5 ) , 'inserts into tab3 replicated' ) ;
# update (replicated as update)
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab1 SET a = 6 WHERE a = 5" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab2 SET a = 6 WHERE a = 5" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab3 SET a = 6 WHERE a = 5" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab2|0
sub1_tab2 | 1
sub1_tab2 | 3
sub1_tab2 | 6 ) , 'update of tab2 replicated' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3_1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab3_1|0
sub1_tab3_1 | 1
sub1_tab3_1 | 3
sub1_tab3_1 | 6 ) , 'update of tab3_1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab1|0
sub2_tab1 | 1
sub2_tab1 | 3
sub2_tab1 | 6 ) , 'inserts into tab1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab2|0
sub2_tab2 | 1
sub2_tab2 | 3
sub2_tab2 | 6 ) , 'inserts into tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab3|0
sub2_tab3 | 1
sub2_tab3 | 3
sub2_tab3 | 6 ) , 'inserts into tab3 replicated' ) ;
# update (replicated as delete+insert)
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab1 SET a = 2 WHERE a = 6" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab2 SET a = 2 WHERE a = 6" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"UPDATE tab3 SET a = 2 WHERE a = 6" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab2|0
sub1_tab2 | 1
sub1_tab2 | 2
sub1_tab2 | 3 ) , 'update of tab2 replicated' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3_1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub1_tab3_1|0
sub1_tab3_1 | 1
sub1_tab3_1 | 2
sub1_tab3_1 | 3 ) , 'update of tab3_1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab1 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab1|0
sub2_tab1 | 1
sub2_tab1 | 2
sub2_tab1 | 3 ) , 'update of tab1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab2 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab2|0
sub2_tab2 | 1
sub2_tab2 | 2
sub2_tab2 | 3 ) , 'update of tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT c, a FROM tab3 ORDER BY 1, 2" ) ;
is ( $ result , qq( sub2_tab3|0
sub2_tab3 | 1
sub2_tab3 | 2
sub2_tab3 | 3 ) , 'update of tab3 replicated' ) ;
# delete
$ node_publisher - > safe_psql ( 'postgres' ,
"DELETE FROM tab1" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"DELETE FROM tab2" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"DELETE FROM tab3" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2" ) ;
is ( $ result , qq( ) , 'delete tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab1" ) ;
is ( $ result , qq( ) , 'delete from tab1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2" ) ;
is ( $ result , qq( ) , 'delete from tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab3" ) ;
is ( $ result , qq( ) , 'delete from tab3 replicated' ) ;
# truncate
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab1 VALUES (1), (2), (5)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab2 VALUES (1), (2), (5)" ) ;
# these will NOT be replicated
$ node_publisher - > safe_psql ( 'postgres' ,
"TRUNCATE tab1_2, tab2_1, tab3_1" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2 ORDER BY 1" ) ;
is ( $ result , qq( 1
2
5 ) , 'truncate of tab2_1 NOT replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab1 ORDER BY 1" ) ;
is ( $ result , qq( 1
2
5 ) , 'truncate of tab1_2 NOT replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2 ORDER BY 1" ) ;
is ( $ result , qq( 1
2
5 ) , 'truncate of tab2_1 NOT replicated' ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"TRUNCATE tab1, tab2, tab3" ) ;
$ node_publisher - > wait_for_catchup ( 'sub_viaroot' ) ;
$ node_publisher - > wait_for_catchup ( 'sub2' ) ;
$ result = $ node_subscriber1 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2" ) ;
is ( $ result , qq( ) , 'truncate of tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab1" ) ;
is ( $ result , qq( ) , 'truncate of tab1 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab2" ) ;
is ( $ result , qq( ) , 'truncate of tab2 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab3" ) ;
is ( $ result , qq( ) , 'truncate of tab3 replicated' ) ;
$ result = $ node_subscriber2 - > safe_psql ( 'postgres' ,
"SELECT a FROM tab3_1" ) ;
is ( $ result , qq( ) , 'truncate of tab3_1 replicated' ) ;