diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c index 7e2b2e3..7139c8b 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); /* @@ -366,6 +368,14 @@ RI_FKey_check(TriggerData *trigdata) querysep = "WHERE"; for (int i = 0; i < riinfo->nkeys; i++) { + + /* + * We share the same plan among all relations in a partition + * hierarchy. The plan is guaranteed to be compatible since all of + * the member relations are guaranteed to have the equivalent set + * of foreign keys in fk_attnums[]. + */ + Oid pk_type = RIAttType(pk_rel, riinfo->pk_attnums[i]); Oid fk_type = RIAttType(fk_rel, riinfo->fk_attnums[i]); @@ -1904,7 +1914,16 @@ 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. + * Consider sub-partitioning and get the top comparentid. */ + + while (riinfo->conparentid != InvalidOid) { + riinfo = ri_LoadConstraintInfo(riinfo->conparentid); + } + key->constr_id = riinfo->constraint_id; key->constr_queryno = constr_queryno; } @@ -2059,6 +2078,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,