Invalid parent's relcache after CREATE TABLE .. PARTITION OF.

Otherwise, subsequent commands in the same transaction see the wrong
partition descriptor.

Amit Langote.  Reported by Tomas Vondra and David Fetter.  Reviewed
by me.

Discussion: http://postgr.es/m/22dd313b-d7fd-22b5-0787-654845c8f849%402ndquadrant.com
Discussion: http://postgr.es/m/20161215090916.GB20659%40fetter.org
This commit is contained in:
Robert Haas 2016-12-19 22:53:30 -05:00
parent e13029a5ce
commit 7cd0fd655d
3 changed files with 11 additions and 11 deletions

View File

@ -3230,9 +3230,12 @@ RemovePartitionKeyByRelId(Oid relid)
* StorePartitionBound
* Update pg_class tuple of rel to store the partition bound and set
* relispartition to true
*
* Also, invalidate the parent's relcache, so that the next rebuild will load
* the new partition's info into its partition descriptor.
*/
void
StorePartitionBound(Relation rel, Node *bound)
StorePartitionBound(Relation rel, Relation parent, Node *bound)
{
Relation classRel;
HeapTuple tuple,
@ -3273,4 +3276,6 @@ StorePartitionBound(Relation rel, Node *bound)
CatalogUpdateIndexes(classRel, newtuple);
heap_freetuple(newtuple);
heap_close(classRel, RowExclusiveLock);
CacheInvalidateRelcache(parent);
}

View File

@ -777,10 +777,11 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
* it does not return on error.
*/
check_new_partition_bound(relname, parent, bound);
heap_close(parent, NoLock);
/* Update the pg_class entry. */
StorePartitionBound(rel, bound);
StorePartitionBound(rel, parent, bound);
heap_close(parent, NoLock);
/*
* The code that follows may also update the pg_class tuple to update
@ -13141,7 +13142,7 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
cmd->bound);
/* Update the pg_class entry. */
StorePartitionBound(attachRel, cmd->bound);
StorePartitionBound(attachRel, rel, cmd->bound);
/*
* Generate partition constraint from the partition bound specification.
@ -13352,12 +13353,6 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
}
}
/*
* Invalidate the parent's relcache so that the new partition is now
* included its partition descriptor.
*/
CacheInvalidateRelcache(rel);
ObjectAddressSet(address, RelationRelationId, RelationGetRelid(attachRel));
/* keep our lock until commit */

View File

@ -143,6 +143,6 @@ extern void StorePartitionKey(Relation rel,
Oid *partopclass,
Oid *partcollation);
extern void RemovePartitionKeyByRelId(Oid relid);
extern void StorePartitionBound(Relation rel, Node *bound);
extern void StorePartitionBound(Relation rel, Relation parent, Node *bound);
#endif /* HEAP_H */