agora inbox for [email protected]  
help / color / mirror / Atom feed
From: Kyotaro Horiguchi <[email protected]>
Subject: [PATCH 2/2] share param part of riinfo
Date: Fri, 4 Dec 2020 12:01:26 +0900

---
 src/backend/utils/adt/ri_triggers.c | 66 +++++++++++++++++++++++++++--
 1 file changed, 62 insertions(+), 4 deletions(-)

diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 0306bf7739..187884f622 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -2043,9 +2043,11 @@ static const RI_ConstraintInfo *
 ri_LoadConstraintInfo(Oid constraintOid)
 {
 	RI_ConstraintInfo *riinfo;
+	RI_ConstraintParam tmpparam;
 	bool		found;
 	HeapTuple	tup;
 	Form_pg_constraint conForm;
+	Oid			conparentid;
 
 	/*
 	 * On the first call initialize the hashtable
@@ -2063,10 +2065,10 @@ ri_LoadConstraintInfo(Oid constraintOid)
 	if (!found)
 	{
 		riinfo->valid = false;
-		riinfo->param = (RI_ConstraintParam *)
-			MemoryContextAlloc(ri_constraint_cache_cxt,
-							   sizeof(RI_ConstraintParam));
-		riinfo->param->ownerinfo = riinfo;
+
+		/* tentatively link the tmp parameter area to the riinfo */
+		riinfo->param = &tmpparam;
+		riinfo->param->ownerinfo = NULL;
 	}
 	else if (riinfo->valid)
 		return riinfo;
@@ -2103,8 +2105,64 @@ ri_LoadConstraintInfo(Oid constraintOid)
 							   riinfo->param->pp_eq_oprs,
 							   riinfo->param->ff_eq_oprs);
 
+	conparentid = conForm->conparentid;
 	ReleaseSysCache(tup);
 
+	Assert(riinfo->param);
+
+	/* check if this relation can share the parameter part with the parent. */
+	if (OidIsValid(conparentid))
+	{
+		const RI_ConstraintInfo *priinfo;
+		RI_ConstraintParam		*pparam;
+		RI_ConstraintParam		*param = riinfo->param;
+
+		/* load parent's riinfo (recurses to the topmost parent) */
+		priinfo = ri_LoadConstraintInfo(conparentid);
+		pparam = priinfo->param;
+
+		/* check if the parameter is identical with the parent */
+		if (memcmp(param, pparam,
+				   offsetof(RI_ConstraintParam, pk_attnums)) == 0)
+		{
+			int i;
+
+			/*
+			 * The unused elements of the arrays are not guaranteed to be
+			 * zero-filled. Check only the used elements.
+			 */
+			for (i = 0 ; i < param->nkeys ; i++)
+			{
+				if (param->pk_attnums[i] != pparam->pk_attnums[i] ||
+					param->fk_attnums[i] != pparam->fk_attnums[i] ||
+					param->pf_eq_oprs[i] != pparam->pf_eq_oprs[i] ||
+					param->pp_eq_oprs[i] != pparam->pp_eq_oprs[i] ||
+					param->ff_eq_oprs[i] != pparam->ff_eq_oprs[i])
+					break;
+			}
+
+			if (i == param->nkeys)
+			{
+				/* all parameters match. share the parameters with the parent */
+				if (riinfo->param->ownerinfo == riinfo)
+					pfree(riinfo->param);
+				riinfo->param = pparam;
+			}
+		}
+	}
+
+	/* make a permanent copy if the parameter area is tentative */
+	if (riinfo->param == &tmpparam)
+	{
+		riinfo->param = (RI_ConstraintParam *)
+			MemoryContextAlloc(ri_constraint_cache_cxt,
+							   sizeof(RI_ConstraintParam));
+		/* copy parameter values */
+		memcpy(riinfo->param, &tmpparam,
+			   offsetof(RI_ConstraintParam, ownerinfo));
+		riinfo->param->ownerinfo = riinfo;
+	}
+
 	/*
 	 * For efficient processing of invalidation messages below, we keep a
 	 * doubly-linked list, and a count, of all currently valid entries.
-- 
2.18.4


----Next_Part(Fri_Dec__4_12_05_22_2020_384)----





view thread (3+ messages)  latest in thread

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: [email protected]
  Cc: [email protected]
  Subject: Re: [PATCH 2/2] share param part of riinfo
  In-Reply-To: <no-message-id-174337@localhost>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox