Skip to content

Commit 2fbdf1b

Browse files
committed
Simplify partitioned table creation vs. relcache
In the original code, we were storing the pg_inherits row for a partitioned table too early: enough that we had a hack for relcache to avoid falling flat on its face while reading such a partial entry. If we finish the pg_class creation first and *then* store the pg_inherits entry, we don't need that hack. Also recognize that pg_class.relpartbound is not marked NOT NULL and therefore it's entirely possible to read null values, so having only Assert() protection isn't enough. Change those to if/elog tests instead. This qualifies as a robustness fix, so backpatch to pg11. In passing, remove one access that wasn't actually needed, and reword one message to be like all the others that check for the same thing. Reviewed-by: Amit Langote Discussion: https://postgr.es/m/[email protected]
1 parent f5a6509 commit 2fbdf1b

File tree

3 files changed

+9
-25
lines changed

3 files changed

+9
-25
lines changed

src/backend/commands/tablecmds.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -773,9 +773,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
773773
InvalidOid,
774774
typaddress);
775775

776-
/* Store inheritance information for new rel. */
777-
StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL);
778-
779776
/*
780777
* We must bump the command counter to make the newly-created relation
781778
* tuple visible for opening.
@@ -869,6 +866,9 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
869866
heap_close(parent, NoLock);
870867
}
871868

869+
/* Store inheritance information for new rel. */
870+
StoreCatalogInheritance(relationId, inheritOids, stmt->partbound != NULL);
871+
872872
/*
873873
* Process the partitioning specification (if any) and store the partition
874874
* key information into the catalog.
@@ -14703,10 +14703,6 @@ ATExecDetachPartition(Relation rel, RangeVar *name)
1470314703
RelationGetRelid(partRel));
1470414704
Assert(((Form_pg_class) GETSTRUCT(tuple))->relispartition);
1470514705

14706-
(void) SysCacheGetAttr(RELOID, tuple, Anum_pg_class_relpartbound,
14707-
&isnull);
14708-
Assert(!isnull);
14709-
1471014706
/* Clear relpartbound and reset relispartition */
1471114707
memset(new_val, 0, sizeof(new_val));
1471214708
memset(new_null, false, sizeof(new_null));

src/backend/partitioning/partbounds.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1641,8 +1641,9 @@ get_qual_for_range(Relation parent, PartitionBoundSpec *spec,
16411641
datum = SysCacheGetAttr(RELOID, tuple,
16421642
Anum_pg_class_relpartbound,
16431643
&isnull);
1644+
if (isnull)
1645+
elog(ERROR, "null relpartbound for relation %u", inhrelid);
16441646

1645-
Assert(!isnull);
16461647
bspec = (PartitionBoundSpec *)
16471648
stringToNode(TextDatumGetCString(datum));
16481649
if (!IsA(bspec, PartitionBoundSpec))

src/backend/utils/cache/partcache.c

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -302,23 +302,11 @@ RelationBuildPartitionDesc(Relation rel)
302302
if (!HeapTupleIsValid(tuple))
303303
elog(ERROR, "cache lookup failed for relation %u", inhrelid);
304304

305-
/*
306-
* It is possible that the pg_class tuple of a partition has not been
307-
* updated yet to set its relpartbound field. The only case where
308-
* this happens is when we open the parent relation to check using its
309-
* partition descriptor that a new partition's bound does not overlap
310-
* some existing partition.
311-
*/
312-
if (!((Form_pg_class) GETSTRUCT(tuple))->relispartition)
313-
{
314-
ReleaseSysCache(tuple);
315-
continue;
316-
}
317-
318305
datum = SysCacheGetAttr(RELOID, tuple,
319306
Anum_pg_class_relpartbound,
320307
&isnull);
321-
Assert(!isnull);
308+
if (isnull)
309+
elog(ERROR, "null relpartbound for relation %u", inhrelid);
322310
boundspec = (Node *) stringToNode(TextDatumGetCString(datum));
323311

324312
/*
@@ -883,9 +871,8 @@ generate_partition_qual(Relation rel)
883871
boundDatum = SysCacheGetAttr(RELOID, tuple,
884872
Anum_pg_class_relpartbound,
885873
&isnull);
886-
if (isnull) /* should not happen */
887-
elog(ERROR, "relation \"%s\" has relpartbound = null",
888-
RelationGetRelationName(rel));
874+
if (isnull)
875+
elog(ERROR, "null relpartbound for relation %u", RelationGetRelid(rel));
889876
bound = castNode(PartitionBoundSpec,
890877
stringToNode(TextDatumGetCString(boundDatum)));
891878
ReleaseSysCache(tuple);

0 commit comments

Comments
 (0)