diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 7e2b2e3..b0c7f18 100644 --- a/src/backend/utils/adt/ri_triggers.c +++ b/src/backend/utils/adt/ri_triggers.c @@ -105,6 +105,7 @@ typedef struct RI_ConstraintInfo NameData conname; /* name of the FK constraint */ Oid pk_relid; /* referenced relation */ Oid fk_relid; /* referencing relation */ + Oid conparentid; /* parent constraint */ char confupdtype; /* foreign key's ON UPDATE action */ char confdeltype; /* foreign key's ON DELETE action */ char confmatchtype; /* foreign key's match type */ @@ -221,6 +222,7 @@ static void ri_ReportViolation(const RI_ConstraintInfo *riinfo, Relation pk_rel, Relation fk_rel, TupleTableSlot *violatorslot, TupleDesc tupdesc, int queryno, bool partgone) pg_attribute_noreturn(); +static Oid ri_GetParentConstOid(Oid constraintOid); /* @@ -1904,8 +1906,12 @@ ri_BuildQueryKey(RI_QueryKey *key, const RI_ConstraintInfo *riinfo, /* * We assume struct RI_QueryKey contains no padding bytes, else we'd need * to use memset to clear them. + * If this constraint has conparentid, we use it instead of constraint_id. + * Because constraints which has same conparentid are able to share SPI + * Plan, so this is useful to reduce hashtable size.. */ - key->constr_id = riinfo->constraint_id; + key->constr_id = (riinfo->conparentid == InvalidOid) ? + riinfo->constraint_id : ri_GetParentConstOid(riinfo->conparentid); key->constr_queryno = constr_queryno; } @@ -2059,6 +2065,7 @@ ri_LoadConstraintInfo(Oid constraintOid) riinfo->confupdtype = conForm->confupdtype; riinfo->confdeltype = conForm->confdeltype; riinfo->confmatchtype = conForm->confmatchtype; + riinfo->conparentid = conForm->conparentid; DeconstructFkConstraintRow(tup, &riinfo->nkeys, @@ -2864,6 +2871,22 @@ ri_HashCompareOp(Oid eq_opr, Oid typeid) return entry; } +/* + * Find top of parent constraint oid. + */ +static Oid +ri_GetParentConstOid(Oid constraintOid) +{ + const RI_ConstraintInfo *riinfo; + Oid result; + + riinfo = ri_LoadConstraintInfo(constraintOid); + + result = (riinfo->conparentid == InvalidOid) ? + constraintOid : ri_GetParentConstOid(riinfo->conparentid); + + return result; +} /* * Given a trigger function OID, determine whether it is an RI trigger,