@ -6,7 +6,7 @@ use strict;
use warnings ;
use PostgreSQL::Test::Cluster ;
use PostgreSQL::Test::Utils ;
use Test::More tests = > 5 ;
use Test::More tests = > 7 ;
# Bug #15114
@ -224,3 +224,85 @@ $node_sub->safe_psql('postgres', "DROP TABLE tab1");
$ node_pub - > stop ( 'fast' ) ;
$ node_pub_sub - > stop ( 'fast' ) ;
$ node_sub - > stop ( 'fast' ) ;
# https://postgr.es/m/OS0PR01MB61133CA11630DAE45BC6AD95FB939%40OS0PR01MB6113.jpnprd01.prod.outlook.com
# The bug was that when changing the REPLICA IDENTITY INDEX to another one, the
# target table's relcache was not being invalidated. This leads to skipping
# UPDATE/DELETE operations during apply on the subscriber side as the columns
# required to search corresponding rows won't get logged.
$ node_publisher = PostgreSQL::Test::Cluster - > new ( 'publisher3' ) ;
$ node_publisher - > init ( allows_streaming = > 'logical' ) ;
$ node_publisher - > start ;
$ node_subscriber = PostgreSQL::Test::Cluster - > new ( 'subscriber3' ) ;
$ node_subscriber - > init ( allows_streaming = > 'logical' ) ;
$ node_subscriber - > start ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE TABLE tab_replidentity_index(a int not null, b int not null)" ) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE UNIQUE INDEX idx_replidentity_index_a ON tab_replidentity_index(a)"
) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)"
) ;
# use index idx_replidentity_index_a as REPLICA IDENTITY on publisher.
$ node_publisher - > safe_psql ( 'postgres' ,
"ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_a"
) ;
$ node_publisher - > safe_psql ( 'postgres' ,
"INSERT INTO tab_replidentity_index VALUES(1, 1),(2, 2)" ) ;
$ node_subscriber - > safe_psql ( 'postgres' ,
"CREATE TABLE tab_replidentity_index(a int not null, b int not null)" ) ;
$ node_subscriber - > safe_psql ( 'postgres' ,
"CREATE UNIQUE INDEX idx_replidentity_index_a ON tab_replidentity_index(a)"
) ;
$ node_subscriber - > safe_psql ( 'postgres' ,
"CREATE UNIQUE INDEX idx_replidentity_index_b ON tab_replidentity_index(b)"
) ;
# use index idx_replidentity_index_b as REPLICA IDENTITY on subscriber because
# it reflects the future scenario we are testing: changing REPLICA IDENTITY
# INDEX.
$ node_subscriber - > safe_psql ( 'postgres' ,
"ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b"
) ;
$ publisher_connstr = $ node_publisher - > connstr . ' dbname=postgres' ;
$ node_publisher - > safe_psql ( 'postgres' ,
"CREATE PUBLICATION tap_pub FOR TABLE tab_replidentity_index" ) ;
$ node_subscriber - > safe_psql ( 'postgres' ,
"CREATE SUBSCRIPTION tap_sub CONNECTION '$publisher_connstr' PUBLICATION tap_pub"
) ;
$ node_publisher - > wait_for_catchup ( 'tap_sub' ) ;
# Also wait for initial table sync to finish
$ node_subscriber - > poll_query_until ( 'postgres' , $ synced_query )
or die "Timed out while waiting for subscriber to synchronize data" ;
is ( $ node_subscriber - > safe_psql (
'postgres' , "SELECT * FROM tab_replidentity_index" ) ,
qq( 1|1
2 | 2 ) ,
"check initial data on subscriber" ) ;
# Set REPLICA IDENTITY to idx_replidentity_index_b on publisher, then run UPDATE and DELETE.
$ node_publisher - > safe_psql (
'postgres' , qq[
ALTER TABLE tab_replidentity_index REPLICA IDENTITY USING INDEX idx_replidentity_index_b ;
UPDATE tab_replidentity_index SET a = - a WHERE a = 1 ;
DELETE FROM tab_replidentity_index WHERE a = 2 ;
] ) ;
$ node_publisher - > wait_for_catchup ( 'tap_sub' ) ;
is ( $ node_subscriber - > safe_psql (
'postgres' , "SELECT * FROM tab_replidentity_index" ) ,
qq( -1|1 ) ,
"update works with REPLICA IDENTITY" ) ;
$ node_publisher - > stop ( 'fast' ) ;
$ node_subscriber - > stop ( 'fast' ) ;