Handle no replica identity index case in RelationGetIdentityKeyBitmap.
authorAmit Kapila <akapila@postgresql.org>
Sat, 19 Jun 2021 06:00:33 +0000 (11:30 +0530)
committerAmit Kapila <akapila@postgresql.org>
Sat, 19 Jun 2021 06:06:33 +0000 (11:36 +0530)
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
src/test/subscription/t/001_rep_changes.pl

index fd05615e7690cb692f50fc769637f77ca2e6ee08..d55ae016d090a37c1847e388cc77ea7eeeb4ab7c 100644 (file)
@@ -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];
index ecfba0af049cc5bd3e7b8bf9d7c4c11c00bf2b1e..ca6cd2c646daf707b16a023dc481d593e0b98424 100644 (file)
@@ -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)");