Skip to content

Commit 610abfd

Browse files
committed
Do table renaming in a sane order: physical file rename must happen
*last*, after all updating of system catalogs. In old code, an error detected during TypeRename left the relation hosed. Also, add a call to flush the relation's relcache entry, rather than trusting to shared cache invalidation to flush it for us.
1 parent 445f1ac commit 610abfd

File tree

1 file changed

+36
-28
lines changed

1 file changed

+36
-28
lines changed

src/backend/commands/rename.c

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.44 2000/05/19 03:22:29 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.45 2000/05/25 21:30:20 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -19,7 +19,6 @@
1919
#include "access/heapam.h"
2020
#include "catalog/catname.h"
2121
#include "catalog/pg_type.h"
22-
#include "utils/syscache.h"
2322
#include "catalog/heap.h"
2423
#include "catalog/indexing.h"
2524
#include "catalog/catalog.h"
@@ -29,6 +28,7 @@
2928
#include "optimizer/prep.h"
3029
#include "utils/acl.h"
3130
#include "utils/relcache.h"
31+
#include "utils/syscache.h"
3232

3333

3434
/*
@@ -183,6 +183,7 @@ renamerel(const char *oldrelname, const char *newrelname)
183183
Relation targetrelation;
184184
Relation relrelation; /* for RELATION relation */
185185
HeapTuple oldreltup;
186+
Oid reloid;
186187
char relkind;
187188
char oldpath[MAXPGPATH],
188189
newpath[MAXPGPATH],
@@ -228,6 +229,7 @@ renamerel(const char *oldrelname, const char *newrelname)
228229
if (IsTransactionBlock() && !targetrelation->rd_myxactonly)
229230
elog(NOTICE, "Caution: RENAME TABLE cannot be rolled back, so don't abort now");
230231

232+
reloid = RelationGetRelid(targetrelation);
231233
relkind = targetrelation->rd_rel->relkind;
232234

233235
/*
@@ -254,13 +256,18 @@ renamerel(const char *oldrelname, const char *newrelname)
254256

255257
/*
256258
* Close rel, but keep exclusive lock!
257-
*
258-
* Note: we don't do anything about updating the relcache entry; we
259-
* assume it will be flushed by shared cache invalidate. XXX is this
260-
* good enough? What if relation is myxactonly?
261259
*/
262260
heap_close(targetrelation, NoLock);
263261

262+
/*
263+
* Flush the relcache entry (easier than trying to change it at exactly
264+
* the right instant). It'll get rebuilt on next access to relation.
265+
*
266+
* XXX What if relation is myxactonly?
267+
*/
268+
targetrelation = NULL; /* make sure I don't touch it again */
269+
RelationIdInvalidateRelationCacheByRelationId(reloid);
270+
264271
/*
265272
* Find relation's pg_class tuple, and make sure newrelname isn't in
266273
* use.
@@ -276,9 +283,31 @@ renamerel(const char *oldrelname, const char *newrelname)
276283
if (RelnameFindRelid(newrelname) != InvalidOid)
277284
elog(ERROR, "renamerel: relation \"%s\" exists", newrelname);
278285

286+
/*
287+
* Update pg_class tuple with new relname.
288+
*/
289+
StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(oldreltup))->relname),
290+
newrelname, NAMEDATALEN);
291+
292+
heap_update(relrelation, &oldreltup->t_self, oldreltup, NULL);
293+
294+
/* keep the system catalog indices current */
295+
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
296+
CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, oldreltup);
297+
CatalogCloseIndices(Num_pg_class_indices, irelations);
298+
299+
heap_close(relrelation, NoLock);
300+
301+
/*
302+
* Also rename the associated type, if any.
303+
*/
304+
if (relkind != RELKIND_INDEX)
305+
TypeRename(oldrelname, newrelname);
306+
279307
/*
280308
* Perform physical rename of files. If this fails, we haven't yet
281-
* done anything irreversible.
309+
* done anything irreversible. NOTE that this MUST be the last step;
310+
* an error occurring afterwards would leave the relation hosed!
282311
*
283312
* XXX smgr.c ought to provide an interface for this; doing it directly
284313
* is bletcherous.
@@ -304,25 +333,4 @@ renamerel(const char *oldrelname, const char *newrelname)
304333
toldpath, tnewpath);
305334
}
306335
}
307-
308-
/*
309-
* Update pg_class tuple with new relname.
310-
*/
311-
StrNCpy(NameStr(((Form_pg_class) GETSTRUCT(oldreltup))->relname),
312-
newrelname, NAMEDATALEN);
313-
314-
heap_update(relrelation, &oldreltup->t_self, oldreltup, NULL);
315-
316-
/* keep the system catalog indices current */
317-
CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, irelations);
318-
CatalogIndexInsert(irelations, Num_pg_class_indices, relrelation, oldreltup);
319-
CatalogCloseIndices(Num_pg_class_indices, irelations);
320-
321-
heap_close(relrelation, RowExclusiveLock);
322-
323-
/*
324-
* Also rename the associated type, if any.
325-
*/
326-
if (relkind != RELKIND_INDEX)
327-
TypeRename(oldrelname, newrelname);
328336
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy