Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit02530da

Browse files
committed
Preserve replica identity index across ALTER TABLE rewrite
If an index was explicitly set as replica identity index, this settingwas lost when a table was rewritten by ALTER TABLE. Because thissetting is part of pg_index but actually controlled by ALTERTABLE (not part of CREATE INDEX, say), we have to do some extra workto restore it.Based-on-patch-by: Quan Zongliang <quanzongliang@gmail.com>Reviewed-by: Euler Taveira <euler.taveira@2ndquadrant.com>Discussion:https://www.postgresql.org/message-id/flat/c70fcab2-4866-0d9f-1d01-e75e189db342@gmail.com
1 parent05e0aff commit02530da

File tree

5 files changed

+135
-0
lines changed

5 files changed

+135
-0
lines changed

‎src/backend/commands/tablecmds.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ typedef struct AlteredTableInfo
173173
List*changedConstraintDefs;/* string definitions of same */
174174
List*changedIndexOids;/* OIDs of indexes to rebuild */
175175
List*changedIndexDefs;/* string definitions of same */
176+
char*replicaIdentityIndex;/* index to reset as REPLICA IDENTITY */
176177
}AlteredTableInfo;
177178

178179
/* Struct describing one new constraint to check in Phase 3 scan */
@@ -9420,6 +9421,22 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
94209421
returnaddress;
94219422
}
94229423

9424+
/*
9425+
* Subroutine for ATExecAlterColumnType: remember that a replica identity
9426+
* needs to be reset.
9427+
*/
9428+
staticvoid
9429+
RememberReplicaIdentityForRebuilding(Oidindoid,AlteredTableInfo*tab)
9430+
{
9431+
if (!get_index_isreplident(indoid))
9432+
return;
9433+
9434+
if (tab->replicaIdentityIndex)
9435+
elog(ERROR,"relation %u has multiple indexes marked as replica identity",tab->relid);
9436+
9437+
tab->replicaIdentityIndex=get_rel_name(indoid);
9438+
}
9439+
94239440
/*
94249441
* Subroutine for ATExecAlterColumnType: remember that a constraint needs
94259442
* to be rebuilt (which we might already know).
@@ -9439,6 +9456,7 @@ RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab,
94399456
{
94409457
/* OK, capture the constraint's existing definition string */
94419458
char*defstring=pg_get_constraintdef_command(conoid);
9459+
Oidindoid;
94429460

94439461
/*
94449462
* Put NORMAL dependencies at the front of the list and AUTO
@@ -9462,6 +9480,10 @@ RememberConstraintForRebuilding(Oid conoid, AlteredTableInfo *tab,
94629480
tab->changedConstraintDefs=lappend(tab->changedConstraintDefs,
94639481
defstring);
94649482
}
9483+
9484+
indoid=get_constraint_index(conoid);
9485+
if (OidIsValid(indoid))
9486+
RememberReplicaIdentityForRebuilding(indoid,tab);
94659487
}
94669488
}
94679489

@@ -9505,6 +9527,8 @@ RememberIndexForRebuilding(Oid indoid, AlteredTableInfo *tab)
95059527
indoid);
95069528
tab->changedIndexDefs=lappend(tab->changedIndexDefs,
95079529
defstring);
9530+
9531+
RememberReplicaIdentityForRebuilding(indoid,tab);
95089532
}
95099533
}
95109534
}
@@ -9697,6 +9721,24 @@ ATPostAlterTypeCleanup(List **wqueue, AlteredTableInfo *tab, LOCKMODE lockmode)
96979721
wqueue,lockmode,tab->rewrite);
96989722
}
96999723

9724+
/*
9725+
* Queue up command to restore replica identity index marking
9726+
*/
9727+
if (tab->replicaIdentityIndex)
9728+
{
9729+
AlterTableCmd*cmd=makeNode(AlterTableCmd);
9730+
ReplicaIdentityStmt*subcmd=makeNode(ReplicaIdentityStmt);
9731+
9732+
subcmd->identity_type=REPLICA_IDENTITY_INDEX;
9733+
subcmd->name=tab->replicaIdentityIndex;
9734+
cmd->subtype=AT_ReplicaIdentity;
9735+
cmd->def= (Node*)subcmd;
9736+
9737+
/* do it after indexes and constraints */
9738+
tab->subcmds[AT_PASS_OLD_CONSTR]=
9739+
lappend(tab->subcmds[AT_PASS_OLD_CONSTR],cmd);
9740+
}
9741+
97009742
/*
97019743
* Now we can drop the existing constraints and indexes --- constraints
97029744
* first, since some of them might depend on the indexes. In fact, we

‎src/backend/utils/cache/lsyscache.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3138,3 +3138,28 @@ get_range_collation(Oid rangeOid)
31383138
else
31393139
returnInvalidOid;
31403140
}
3141+
3142+
/*---------- PG_INDEX CACHE ---------- */
3143+
3144+
/*
3145+
* get_index_isreplident
3146+
*
3147+
*Given the index OID, return pg_index.indisreplident.
3148+
*/
3149+
bool
3150+
get_index_isreplident(Oidindex_oid)
3151+
{
3152+
HeapTupletuple;
3153+
Form_pg_indexrd_index;
3154+
boolresult;
3155+
3156+
tuple=SearchSysCache1(INDEXRELID,ObjectIdGetDatum(index_oid));
3157+
if (!HeapTupleIsValid(tuple))
3158+
return false;
3159+
3160+
rd_index= (Form_pg_index)GETSTRUCT(tuple);
3161+
result=rd_index->indisreplident;
3162+
ReleaseSysCache(tuple);
3163+
3164+
returnresult;
3165+
}

‎src/include/utils/lsyscache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ extern char *get_namespace_name(Oid nspid);
178178
externchar*get_namespace_name_or_temp(Oidnspid);
179179
externOidget_range_subtype(OidrangeOid);
180180
externOidget_range_collation(OidrangeOid);
181+
externboolget_index_isreplident(Oidindex_oid);
181182

182183
#definetype_is_array(typid) (get_element_type(typid) != InvalidOid)
183184
/* type_is_array_domain accepts both plain arrays and domains over arrays */

‎src/test/regress/expected/replica_identity.out

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,5 +186,51 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
186186
n
187187
(1 row)
188188

189+
---
190+
-- Test that ALTER TABLE rewrite preserves nondefault replica identity
191+
---
192+
-- constraint variant
193+
CREATE TABLE test_replica_identity2 (id int UNIQUE NOT NULL);
194+
ALTER TABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key;
195+
\d test_replica_identity2
196+
Table "public.test_replica_identity2"
197+
Column | Type | Collation | Nullable | Default
198+
--------+---------+-----------+----------+---------
199+
id | integer | | not null |
200+
Indexes:
201+
"test_replica_identity2_id_key" UNIQUE CONSTRAINT, btree (id) REPLICA IDENTITY
202+
203+
ALTER TABLE test_replica_identity2 ALTER COLUMN id TYPE bigint;
204+
\d test_replica_identity2
205+
Table "public.test_replica_identity2"
206+
Column | Type | Collation | Nullable | Default
207+
--------+--------+-----------+----------+---------
208+
id | bigint | | not null |
209+
Indexes:
210+
"test_replica_identity2_id_key" UNIQUE CONSTRAINT, btree (id) REPLICA IDENTITY
211+
212+
-- straight index variant
213+
CREATE TABLE test_replica_identity3 (id int NOT NULL);
214+
CREATE UNIQUE INDEX test_replica_identity3_id_key ON test_replica_identity3 (id);
215+
ALTER TABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key;
216+
\d test_replica_identity3
217+
Table "public.test_replica_identity3"
218+
Column | Type | Collation | Nullable | Default
219+
--------+---------+-----------+----------+---------
220+
id | integer | | not null |
221+
Indexes:
222+
"test_replica_identity3_id_key" UNIQUE, btree (id) REPLICA IDENTITY
223+
224+
ALTER TABLE test_replica_identity3 ALTER COLUMN id TYPE bigint;
225+
\d test_replica_identity3
226+
Table "public.test_replica_identity3"
227+
Column | Type | Collation | Nullable | Default
228+
--------+--------+-----------+----------+---------
229+
id | bigint | | not null |
230+
Indexes:
231+
"test_replica_identity3_id_key" UNIQUE, btree (id) REPLICA IDENTITY
232+
189233
DROP TABLE test_replica_identity;
234+
DROP TABLE test_replica_identity2;
235+
DROP TABLE test_replica_identity3;
190236
DROP TABLE test_replica_identity_othertable;

‎src/test/regress/sql/replica_identity.sql

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,26 @@ SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
7979
ALTERTABLE test_replica_identity REPLICA IDENTITY NOTHING;
8080
SELECT relreplidentFROM pg_classWHEREoid='test_replica_identity'::regclass;
8181

82+
---
83+
-- Test that ALTER TABLE rewrite preserves nondefault replica identity
84+
---
85+
86+
-- constraint variant
87+
CREATETABLEtest_replica_identity2 (idint UNIQUENOT NULL);
88+
ALTERTABLE test_replica_identity2 REPLICA IDENTITY USING INDEX test_replica_identity2_id_key;
89+
\d test_replica_identity2
90+
ALTERTABLE test_replica_identity2 ALTER COLUMN id TYPEbigint;
91+
\d test_replica_identity2
92+
93+
-- straight index variant
94+
CREATETABLEtest_replica_identity3 (idintNOT NULL);
95+
CREATEUNIQUE INDEXtest_replica_identity3_id_keyON test_replica_identity3 (id);
96+
ALTERTABLE test_replica_identity3 REPLICA IDENTITY USING INDEX test_replica_identity3_id_key;
97+
\d test_replica_identity3
98+
ALTERTABLE test_replica_identity3 ALTER COLUMN id TYPEbigint;
99+
\d test_replica_identity3
100+
82101
DROPTABLE test_replica_identity;
102+
DROPTABLE test_replica_identity2;
103+
DROPTABLE test_replica_identity3;
83104
DROPTABLE test_replica_identity_othertable;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp