From: Kyotaro Horiguchi Date: Fri, 4 Dec 2020 12:01:26 +0900 Subject: [PATCH 2/2] share param part of riinfo --- 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)----