From 8a0596cb656e357c391cccf12854beb2e05f3901 Mon Sep 17 00:00:00 2001 From: Alvaro Herrera Date: Thu, 21 Dec 2017 14:21:39 -0300 Subject: [PATCH] Get rid of copy_partition_key That function currently exists to avoid leaking memory in CacheMemoryContext in case of trouble while the partition key is being built, but there's a better way: allocate everything in a memcxt that goes away if the current (sub)transaction fails, and once the partition key is built and no further errors can occur, make the memcxt permanent by making it a child of CacheMemoryContext. Reviewed-by: Tom Lane Discussion: https://postgr.es/m/20171027172730.eh2domlkpn4ja62m@alvherre.pgsql --- src/backend/utils/cache/relcache.c | 71 ++++-------------------------- 1 file changed, 9 insertions(+), 62 deletions(-) diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c index 3a9233ef3d..e2760daac4 100644 --- a/src/backend/utils/cache/relcache.c +++ b/src/backend/utils/cache/relcache.c @@ -262,7 +262,6 @@ static Relation AllocateRelationDesc(Form_pg_class relp); static void RelationParseRelOptions(Relation relation, HeapTuple tuple); static void RelationBuildTupleDesc(Relation relation); static void RelationBuildPartitionKey(Relation relation); -static PartitionKey copy_partition_key(PartitionKey fromkey); static Relation RelationBuildDesc(Oid targetRelId, bool insertIt); static void RelationInitPhysicalAddr(Relation relation); static void load_critical_index(Oid indexoid, Oid heapoid); @@ -847,6 +846,12 @@ RelationBuildPartitionKey(Relation relation) if (!HeapTupleIsValid(tuple)) return; + partkeycxt = AllocSetContextCreateExtended(CurTransactionContext, + RelationGetRelationName(relation), + MEMCONTEXT_COPY_NAME, + ALLOCSET_SMALL_SIZES); + oldcxt = MemoryContextSwitchTo(partkeycxt); + key = (PartitionKey) palloc0(sizeof(PartitionKeyData)); /* Fixed-length attributes */ @@ -984,71 +989,13 @@ RelationBuildPartitionKey(Relation relation) ReleaseSysCache(tuple); - /* Success --- now copy to the cache memory */ - partkeycxt = AllocSetContextCreateExtended(CacheMemoryContext, - RelationGetRelationName(relation), - MEMCONTEXT_COPY_NAME, - ALLOCSET_SMALL_SIZES); + /* Success --- make the relcache point to the newly constructed key */ + MemoryContextSetParent(partkeycxt, CacheMemoryContext); relation->rd_partkeycxt = partkeycxt; - oldcxt = MemoryContextSwitchTo(relation->rd_partkeycxt); - relation->rd_partkey = copy_partition_key(key); + relation->rd_partkey = key; MemoryContextSwitchTo(oldcxt); } -/* - * copy_partition_key - * - * The copy is allocated in the current memory context. - */ -static PartitionKey -copy_partition_key(PartitionKey fromkey) -{ - PartitionKey newkey; - int n; - - newkey = (PartitionKey) palloc(sizeof(PartitionKeyData)); - - newkey->strategy = fromkey->strategy; - newkey->partnatts = n = fromkey->partnatts; - - newkey->partattrs = (AttrNumber *) palloc(n * sizeof(AttrNumber)); - memcpy(newkey->partattrs, fromkey->partattrs, n * sizeof(AttrNumber)); - - newkey->partexprs = copyObject(fromkey->partexprs); - - newkey->partopfamily = (Oid *) palloc(n * sizeof(Oid)); - memcpy(newkey->partopfamily, fromkey->partopfamily, n * sizeof(Oid)); - - newkey->partopcintype = (Oid *) palloc(n * sizeof(Oid)); - memcpy(newkey->partopcintype, fromkey->partopcintype, n * sizeof(Oid)); - - newkey->partsupfunc = (FmgrInfo *) palloc(n * sizeof(FmgrInfo)); - memcpy(newkey->partsupfunc, fromkey->partsupfunc, n * sizeof(FmgrInfo)); - - newkey->partcollation = (Oid *) palloc(n * sizeof(Oid)); - memcpy(newkey->partcollation, fromkey->partcollation, n * sizeof(Oid)); - - newkey->parttypid = (Oid *) palloc(n * sizeof(Oid)); - memcpy(newkey->parttypid, fromkey->parttypid, n * sizeof(Oid)); - - newkey->parttypmod = (int32 *) palloc(n * sizeof(int32)); - memcpy(newkey->parttypmod, fromkey->parttypmod, n * sizeof(int32)); - - newkey->parttyplen = (int16 *) palloc(n * sizeof(int16)); - memcpy(newkey->parttyplen, fromkey->parttyplen, n * sizeof(int16)); - - newkey->parttypbyval = (bool *) palloc(n * sizeof(bool)); - memcpy(newkey->parttypbyval, fromkey->parttypbyval, n * sizeof(bool)); - - newkey->parttypalign = (char *) palloc(n * sizeof(bool)); - memcpy(newkey->parttypalign, fromkey->parttypalign, n * sizeof(char)); - - newkey->parttypcoll = (Oid *) palloc(n * sizeof(Oid)); - memcpy(newkey->parttypcoll, fromkey->parttypcoll, n * sizeof(Oid)); - - return newkey; -} - /* * equalRuleLocks *