Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 807ae41

Browse files
committed
Don't create relfilenode for relations without storage
Some relation kinds had relfilenode set to some non-zero value, but apparently the actual files did not really exist because creation was prevented elsewhere. Get rid of the phony pg_class.relfilenode values. Catversion bumped, but only because the sanity_test check will fail if run in a system initdb'd with the previous version. Reviewed-by: Kyotaro HORIGUCHI, Michael Paquier Discussion: https://postgr.es/m/[email protected]
1 parent df5be63 commit 807ae41

File tree

6 files changed

+36
-26
lines changed

6 files changed

+36
-26
lines changed

src/backend/catalog/heap.c

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -324,35 +324,25 @@ heap_create(const char *relname,
324324
get_namespace_name(relnamespace), relname),
325325
errdetail("System catalog modifications are currently disallowed.")));
326326

327-
/*
328-
* Decide if we need storage or not, and handle a couple other special
329-
* cases for particular relkinds.
330-
*/
327+
/* Handle reltablespace for specific relkinds. */
331328
switch (relkind)
332329
{
333330
case RELKIND_VIEW:
334331
case RELKIND_COMPOSITE_TYPE:
335332
case RELKIND_FOREIGN_TABLE:
336-
create_storage = false;
337333

338334
/*
339335
* Force reltablespace to zero if the relation has no physical
340336
* storage. This is mainly just for cleanliness' sake.
337+
*
338+
* Partitioned tables and indexes don't have physical storage
339+
* either, but we want to keep their tablespace settings so that
340+
* their children can inherit it.
341341
*/
342342
reltablespace = InvalidOid;
343343
break;
344344

345-
case RELKIND_PARTITIONED_TABLE:
346-
case RELKIND_PARTITIONED_INDEX:
347-
/*
348-
* For partitioned tables and indexes, preserve tablespace so that
349-
* it's used as the tablespace for future partitions.
350-
*/
351-
create_storage = false;
352-
break;
353-
354345
case RELKIND_SEQUENCE:
355-
create_storage = true;
356346

357347
/*
358348
* Force reltablespace to zero for sequences, since we don't
@@ -361,19 +351,21 @@ heap_create(const char *relname,
361351
reltablespace = InvalidOid;
362352
break;
363353
default:
364-
create_storage = true;
365354
break;
366355
}
367356

368357
/*
369-
* Unless otherwise requested, the physical ID (relfilenode) is initially
370-
* the same as the logical ID (OID). When the caller did specify a
371-
* relfilenode, it already exists; do not attempt to create it.
358+
* Decide whether to create storage. If caller passed a valid relfilenode,
359+
* storage is already created, so don't do it here. Also don't create it
360+
* for relkinds without physical storage.
372361
*/
373-
if (OidIsValid(relfilenode))
362+
if (!RELKIND_HAS_STORAGE(relkind) || OidIsValid(relfilenode))
374363
create_storage = false;
375364
else
365+
{
366+
create_storage = true;
376367
relfilenode = relid;
368+
}
377369

378370
/*
379371
* Never allow a pg_class entry to explicitly specify the database's

src/backend/utils/cache/relcache.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,10 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
12531253
static void
12541254
RelationInitPhysicalAddr(Relation relation)
12551255
{
1256+
/* these relations kinds never have storage */
1257+
if (!RELKIND_HAS_STORAGE(relation->rd_rel->relkind))
1258+
return;
1259+
12561260
if (relation->rd_rel->reltablespace)
12571261
relation->rd_node.spcNode = relation->rd_rel->reltablespace;
12581262
else

src/include/catalog/catversion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 201901031
56+
#define CATALOG_VERSION_NO 201901041
5757

5858
#endif

src/include/utils/rel.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -450,13 +450,12 @@ typedef struct ViewOptions
450450

451451
/*
452452
* RelationIsMapped
453-
* True if the relation uses the relfilenode map.
454-
*
455-
* NB: this is only meaningful for relkinds that have storage, else it
456-
* will misleadingly say "true".
453+
* True if the relation uses the relfilenode map. Note multiple eval
454+
* of argument!
457455
*/
458456
#define RelationIsMapped(relation) \
459-
((relation)->rd_rel->relfilenode == InvalidOid)
457+
(RELKIND_HAS_STORAGE((relation)->rd_rel->relkind) && \
458+
((relation)->rd_rel->relfilenode == InvalidOid))
460459

461460
/*
462461
* RelationOpenSmgr

src/test/regress/expected/sanity_check.out

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,3 +224,12 @@ SELECT relname, nspname
224224
---------+---------
225225
(0 rows)
226226

227+
-- check that relations without storage don't have relfilenode
228+
SELECT relname, relkind
229+
FROM pg_class
230+
WHERE relkind IN ('v', 'c', 'f', 'p', 'I')
231+
AND relfilenode <> 0;
232+
relname | relkind
233+
---------+---------
234+
(0 rows)
235+

src/test/regress/sql/sanity_check.sql

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,9 @@ SELECT relname, nspname
3131
AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid
3232
AND indkey[0] = a.attnum AND indnatts = 1
3333
AND indisunique AND indimmediate);
34+
35+
-- check that relations without storage don't have relfilenode
36+
SELECT relname, relkind
37+
FROM pg_class
38+
WHERE relkind IN ('v', 'c', 'f', 'p', 'I')
39+
AND relfilenode <> 0;

0 commit comments

Comments
 (0)