From 2731ce1bd550d08f3fdd7bcb1497af4b95170976 Mon Sep 17 00:00:00 2001 From: Amit Kapila Date: Sat, 19 Jun 2021 11:30:33 +0530 Subject: [PATCH] Handle no replica identity index case in RelationGetIdentityKeyBitmap. Commit e7eea52b2d has introduced a new function RelationGetIdentityKeyBitmap which omits to handle the case where there is no replica identity index on a relation. Author: Mark Dilger Reviewed-by: Takamichi Osumi, Amit Kapila Discussion: https://www.postgresql.org/message-id/4C99A862-69C8-431F-960A-81B1151F1B89@enterprisedb.com --- src/backend/utils/cache/relcache.c | 12 +++++++++++- src/test/subscription/t/001_rep_changes.pl | 17 +++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index fd05615e76..d55ae016d0 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -5266,8 +5266,18 @@ RelationGetIdentityKeyBitmap(Relation relation) if (indexoidlist == NIL) return NULL; - /* Add referenced attributes to idindexattrs */ + /* Fall out if there is no replica identity index */ + if (!OidIsValid(relation->rd_replidindex)) + return NULL; + + /* Look up the description for the replica identity index */ indexDesc = RelationIdGetRelation(relation->rd_replidindex); + + if (!RelationIsValid(indexDesc)) + elog(ERROR, "could not open relation with OID %u", + relation->rd_replidindex); + + /* Add referenced attributes to idindexattrs */ for (i = 0; i < indexDesc->rd_index->indnatts; i++) { int attrnum = indexDesc->rd_index->indkey.values[i]; diff --git a/src/test/subscription/t/001_rep_changes.pl b/src/test/subscription/t/001_rep_changes.pl index ecfba0af04..ca6cd2c646 100644 --- a/src/test/subscription/t/001_rep_changes.pl +++ b/src/test/subscription/t/001_rep_changes.pl @@ -6,7 +6,7 @@ use strict; use warnings; use PostgresNode; use TestLib; -use Test::More tests => 31; +use Test::More tests => 32; # Initialize publisher node my $node_publisher = get_new_node('publisher'); @@ -50,6 +50,10 @@ $node_publisher->safe_psql('postgres', "CREATE TABLE tab_nothing (a int)"); $node_publisher->safe_psql('postgres', "ALTER TABLE tab_nothing REPLICA IDENTITY NOTHING"); +# Replicate the changes without replica identity index +$node_publisher->safe_psql('postgres', "CREATE TABLE tab_no_replidentity_index(c1 int)"); +$node_publisher->safe_psql('postgres', "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)"); + # Setup structure on subscriber $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_notrep (a int)"); $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_ins (a int)"); @@ -73,13 +77,17 @@ $node_subscriber->safe_psql('postgres', "CREATE TABLE tab_include (a int, b text, CONSTRAINT covering PRIMARY KEY(a) INCLUDE(b))" ); +# replication of the table without replica identity index +$node_subscriber->safe_psql('postgres', "CREATE TABLE tab_no_replidentity_index(c1 int)"); +$node_subscriber->safe_psql('postgres', "CREATE INDEX idx_no_replidentity_index ON tab_no_replidentity_index(c1)"); + # Setup logical replication my $publisher_connstr = $node_publisher->connstr . ' dbname=postgres'; $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub"); $node_publisher->safe_psql('postgres', "CREATE PUBLICATION tap_pub_ins_only WITH (publish = insert)"); $node_publisher->safe_psql('postgres', - "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk" + "ALTER PUBLICATION tap_pub ADD TABLE tab_rep, tab_full, tab_full2, tab_mixed, tab_include, tab_nothing, tab_full_pk, tab_no_replidentity_index" ); $node_publisher->safe_psql('postgres', "ALTER PUBLICATION tap_pub_ins_only ADD TABLE tab_ins"); @@ -129,6 +137,8 @@ $node_publisher->safe_psql('postgres', "DELETE FROM tab_include WHERE a > 20"); $node_publisher->safe_psql('postgres', "UPDATE tab_include SET a = -a"); +$node_publisher->safe_psql('postgres', "INSERT INTO tab_no_replidentity_index VALUES(1)"); + $node_publisher->wait_for_catchup('tap_sub'); $result = $node_subscriber->safe_psql('postgres', @@ -152,6 +162,9 @@ $result = $node_subscriber->safe_psql('postgres', is($result, qq(20|-20|-1), 'check replicated changes with primary key index with included columns'); +is($node_subscriber->safe_psql('postgres', q(SELECT c1 FROM tab_no_replidentity_index)), + 1, "value replicated to subscriber without replica identity index"); + # insert some duplicate rows $node_publisher->safe_psql('postgres', "INSERT INTO tab_full SELECT generate_series(1,10)");