The attached fixes an error message which is incorrectly using an
unsigned format specifier instead of a signed one.

# create table t ();
# create unique index t_idx on t (ctid);
# alter table t replica identity using index t_idx;
ERROR:  internal column 4294967295 in unique index "t_idx"

I was just going to submit a patch to change the %u to a %d, but this
error message should use ereport() instead of elog(), so I fixed that
up too and added the missing regression test.

I picked ERRCODE_INVALID_COLUMN_REFERENCE as I thought it was the most
suitable. I'm not sure if it's correct though.

-- 
 David Rowley                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 96dc923..36b5448 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -11052,8 +11052,10 @@ ATExecReplicaIdentity(Relation rel, 
ReplicaIdentityStmt *stmt, LOCKMODE lockmode
 
                /* Of the system columns, only oid is indexable. */
                if (attno <= 0 && attno != ObjectIdAttributeNumber)
-                       elog(ERROR, "internal column %u in unique index \"%s\"",
-                                attno, RelationGetRelationName(indexRel));
+                       ereport(ERROR,
+                                       
(errcode(ERRCODE_INVALID_COLUMN_REFERENCE),
+                                        errmsg("index \"%s\" cannot be used as 
replica identity because column %d is a system column",
+                                                       
RelationGetRelationName(indexRel), attno)));
 
                attr = rel->rd_att->attrs[attno - 1];
                if (!attr->attnotnull)
diff --git a/src/test/regress/expected/replica_identity.out 
b/src/test/regress/expected/replica_identity.out
index 60d9a42..47678db 100644
--- a/src/test/regress/expected/replica_identity.out
+++ b/src/test/regress/expected/replica_identity.out
@@ -9,6 +9,7 @@ CREATE TABLE test_replica_identity (
 CREATE TABLE test_replica_identity_othertable (id serial primary key);
 CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb);
 CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity 
(keya, keyb);
+CREATE UNIQUE INDEX test_replica_indentity_syscol ON test_replica_identity 
(ctid);
 CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity 
(keya, nonkey);
 CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash 
(nonkey);
 WARNING:  hash indexes are not WAL-logged and their use is discouraged
@@ -40,6 +41,9 @@ SELECT relreplident FROM pg_class WHERE oid = 
'pg_constraint'::regclass;
 -- fail, not unique
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_identity_keyab;
 ERROR:  cannot use non-unique index "test_replica_identity_keyab" as replica 
identity
+-- fail, index can't contain system columns
+ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_indentity_syscol;
+ERROR:  index "test_replica_indentity_syscol" cannot be used as replica 
identity because column -1 is a system column
 -- fail, not a candidate key, nullable column
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_identity_nonkey;
 ERROR:  index "test_replica_identity_nonkey" cannot be used as replica 
identity because column "nonkey" is nullable
@@ -91,6 +95,7 @@ Indexes:
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> 
'3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) 
DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, 
keyb)
+    "test_replica_indentity_syscol" UNIQUE, btree (ctid)
     "test_replica_identity_hash" hash (nonkey)
     "test_replica_identity_keyab" btree (keya, keyb)
 
@@ -121,6 +126,7 @@ Indexes:
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> 
'3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) 
DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, 
keyb)
+    "test_replica_indentity_syscol" UNIQUE, btree (ctid)
     "test_replica_identity_hash" hash (nonkey)
     "test_replica_identity_keyab" btree (keya, keyb)
 
@@ -169,6 +175,7 @@ Indexes:
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> 
'3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) 
DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, 
keyb)
+    "test_replica_indentity_syscol" UNIQUE, btree (ctid)
     "test_replica_identity_hash" hash (nonkey)
     "test_replica_identity_keyab" btree (keya, keyb)
 Replica Identity: FULL
diff --git a/src/test/regress/sql/replica_identity.sql 
b/src/test/regress/sql/replica_identity.sql
index 20b6826..436851c 100644
--- a/src/test/regress/sql/replica_identity.sql
+++ b/src/test/regress/sql/replica_identity.sql
@@ -11,6 +11,7 @@ CREATE TABLE test_replica_identity_othertable (id serial 
primary key);
 
 CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb);
 CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity 
(keya, keyb);
+CREATE UNIQUE INDEX test_replica_indentity_syscol ON test_replica_identity 
(ctid);
 CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity 
(keya, nonkey);
 CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash 
(nonkey);
 CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, 
keyb, (3));
@@ -28,6 +29,8 @@ SELECT relreplident FROM pg_class WHERE oid = 
'pg_constraint'::regclass;
 
 -- fail, not unique
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_identity_keyab;
+-- fail, index can't contain system columns
+ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_indentity_syscol;
 -- fail, not a candidate key, nullable column
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX 
test_replica_identity_nonkey;
 -- fail, hash indexes cannot do uniqueness
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to