Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 0080396

Browse files
committed
Refactor duplicate code into DeconstructFkConstraintRow
My commit 3de241d introduced some code (in tablecmds.c) to obtain data from a pg_constraint row for a foreign key, that already existed in ri_triggers.c. Split it out into its own routine in pg_constraint.c, where it naturally belongs. No functional code changes, only code movement. Backpatch to pg11, because a future bugfix is simpler after this.
1 parent 9194c42 commit 0080396

File tree

4 files changed

+126
-228
lines changed

4 files changed

+126
-228
lines changed

src/backend/catalog/pg_constraint.c

Lines changed: 111 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -446,14 +446,11 @@ static void
446446
clone_fk_constraints(Relation pg_constraint, Relation parentRel,
447447
Relation partRel, List *clone, List **cloned)
448448
{
449-
TupleDesc tupdesc;
450449
AttrNumber *attmap;
451450
List *partFKs;
452451
List *subclone = NIL;
453452
ListCell *cell;
454453

455-
tupdesc = RelationGetDescr(pg_constraint);
456-
457454
/*
458455
* The constraint key may differ, if the columns in the partition are
459456
* different. This map is used to convert them.
@@ -483,9 +480,6 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
483480
int nelem;
484481
ListCell *cell;
485482
int i;
486-
ArrayType *arr;
487-
Datum datum;
488-
bool isnull;
489483

490484
tuple = SearchSysCache1(CONSTROID, parentConstrOid);
491485
if (!tuple)
@@ -502,93 +496,11 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
502496

503497
ObjectAddressSet(parentAddr, ConstraintRelationId, parentConstrOid);
504498

505-
datum = fastgetattr(tuple, Anum_pg_constraint_conkey,
506-
tupdesc, &isnull);
507-
if (isnull)
508-
elog(ERROR, "null conkey");
509-
arr = DatumGetArrayTypeP(datum);
510-
nelem = ARR_DIMS(arr)[0];
511-
if (ARR_NDIM(arr) != 1 ||
512-
nelem < 1 ||
513-
nelem > INDEX_MAX_KEYS ||
514-
ARR_HASNULL(arr) ||
515-
ARR_ELEMTYPE(arr) != INT2OID)
516-
elog(ERROR, "conkey is not a 1-D smallint array");
517-
memcpy(conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
518-
499+
DeconstructFkConstraintRow(tuple, &nelem, conkey, confkey,
500+
conpfeqop, conppeqop, conffeqop);
519501
for (i = 0; i < nelem; i++)
520502
mapped_conkey[i] = attmap[conkey[i] - 1];
521503

522-
datum = fastgetattr(tuple, Anum_pg_constraint_confkey,
523-
tupdesc, &isnull);
524-
if (isnull)
525-
elog(ERROR, "null confkey");
526-
arr = DatumGetArrayTypeP(datum);
527-
nelem = ARR_DIMS(arr)[0];
528-
if (ARR_NDIM(arr) != 1 ||
529-
nelem < 1 ||
530-
nelem > INDEX_MAX_KEYS ||
531-
ARR_HASNULL(arr) ||
532-
ARR_ELEMTYPE(arr) != INT2OID)
533-
elog(ERROR, "confkey is not a 1-D smallint array");
534-
memcpy(confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
535-
536-
datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
537-
tupdesc, &isnull);
538-
if (isnull)
539-
elog(ERROR, "null conpfeqop");
540-
arr = DatumGetArrayTypeP(datum);
541-
nelem = ARR_DIMS(arr)[0];
542-
if (ARR_NDIM(arr) != 1 ||
543-
nelem < 1 ||
544-
nelem > INDEX_MAX_KEYS ||
545-
ARR_HASNULL(arr) ||
546-
ARR_ELEMTYPE(arr) != OIDOID)
547-
elog(ERROR, "conpfeqop is not a 1-D OID array");
548-
memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
549-
550-
datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
551-
tupdesc, &isnull);
552-
if (isnull)
553-
elog(ERROR, "null conpfeqop");
554-
arr = DatumGetArrayTypeP(datum);
555-
nelem = ARR_DIMS(arr)[0];
556-
if (ARR_NDIM(arr) != 1 ||
557-
nelem < 1 ||
558-
nelem > INDEX_MAX_KEYS ||
559-
ARR_HASNULL(arr) ||
560-
ARR_ELEMTYPE(arr) != OIDOID)
561-
elog(ERROR, "conpfeqop is not a 1-D OID array");
562-
memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
563-
564-
datum = fastgetattr(tuple, Anum_pg_constraint_conppeqop,
565-
tupdesc, &isnull);
566-
if (isnull)
567-
elog(ERROR, "null conppeqop");
568-
arr = DatumGetArrayTypeP(datum);
569-
nelem = ARR_DIMS(arr)[0];
570-
if (ARR_NDIM(arr) != 1 ||
571-
nelem < 1 ||
572-
nelem > INDEX_MAX_KEYS ||
573-
ARR_HASNULL(arr) ||
574-
ARR_ELEMTYPE(arr) != OIDOID)
575-
elog(ERROR, "conppeqop is not a 1-D OID array");
576-
memcpy(conppeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
577-
578-
datum = fastgetattr(tuple, Anum_pg_constraint_conffeqop,
579-
tupdesc, &isnull);
580-
if (isnull)
581-
elog(ERROR, "null conffeqop");
582-
arr = DatumGetArrayTypeP(datum);
583-
nelem = ARR_DIMS(arr)[0];
584-
if (ARR_NDIM(arr) != 1 ||
585-
nelem < 1 ||
586-
nelem > INDEX_MAX_KEYS ||
587-
ARR_HASNULL(arr) ||
588-
ARR_ELEMTYPE(arr) != OIDOID)
589-
elog(ERROR, "conffeqop is not a 1-D OID array");
590-
memcpy(conffeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
591-
592504
/*
593505
* Before creating a new constraint, see whether any existing FKs are
594506
* fit for the purpose. If one is, attach the parent constraint to it,
@@ -1530,6 +1442,115 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
15301442
return pkattnos;
15311443
}
15321444

1445+
/*
1446+
* Extract data from the pg_constraint tuple of a foreign-key constraint.
1447+
*
1448+
* All arguments save the first are output arguments; the last three of them
1449+
* can be passed as NULL if caller doesn't need them.
1450+
*/
1451+
void
1452+
DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
1453+
AttrNumber *conkey, AttrNumber *confkey,
1454+
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs)
1455+
{
1456+
Oid constrId;
1457+
Datum adatum;
1458+
bool isNull;
1459+
ArrayType *arr;
1460+
int numkeys;
1461+
1462+
constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
1463+
1464+
/*
1465+
* We expect the arrays to be 1-D arrays of the right types; verify that.
1466+
* We don't need to use deconstruct_array() since the array data is just
1467+
* going to look like a C array of values.
1468+
*/
1469+
adatum = SysCacheGetAttr(CONSTROID, tuple,
1470+
Anum_pg_constraint_conkey, &isNull);
1471+
if (isNull)
1472+
elog(ERROR, "null conkey for constraint %u", constrId);
1473+
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1474+
if (ARR_NDIM(arr) != 1 ||
1475+
ARR_HASNULL(arr) ||
1476+
ARR_ELEMTYPE(arr) != INT2OID)
1477+
elog(ERROR, "conkey is not a 1-D smallint array");
1478+
numkeys = ARR_DIMS(arr)[0];
1479+
if (numkeys <= 0 || numkeys > INDEX_MAX_KEYS)
1480+
elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
1481+
memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1482+
if ((Pointer) arr != DatumGetPointer(adatum))
1483+
pfree(arr); /* free de-toasted copy, if any */
1484+
1485+
adatum = SysCacheGetAttr(CONSTROID, tuple,
1486+
Anum_pg_constraint_confkey, &isNull);
1487+
if (isNull)
1488+
elog(ERROR, "null confkey for constraint %u", constrId);
1489+
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1490+
if (ARR_NDIM(arr) != 1 ||
1491+
ARR_DIMS(arr)[0] != numkeys ||
1492+
ARR_HASNULL(arr) ||
1493+
ARR_ELEMTYPE(arr) != INT2OID)
1494+
elog(ERROR, "confkey is not a 1-D smallint array");
1495+
memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
1496+
if ((Pointer) arr != DatumGetPointer(adatum))
1497+
pfree(arr); /* free de-toasted copy, if any */
1498+
1499+
if (pf_eq_oprs)
1500+
{
1501+
adatum = SysCacheGetAttr(CONSTROID, tuple,
1502+
Anum_pg_constraint_conpfeqop, &isNull);
1503+
if (isNull)
1504+
elog(ERROR, "null conpfeqop for constraint %u", constrId);
1505+
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1506+
/* see TryReuseForeignKey if you change the test below */
1507+
if (ARR_NDIM(arr) != 1 ||
1508+
ARR_DIMS(arr)[0] != numkeys ||
1509+
ARR_HASNULL(arr) ||
1510+
ARR_ELEMTYPE(arr) != OIDOID)
1511+
elog(ERROR, "conpfeqop is not a 1-D Oid array");
1512+
memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1513+
if ((Pointer) arr != DatumGetPointer(adatum))
1514+
pfree(arr); /* free de-toasted copy, if any */
1515+
}
1516+
1517+
if (pp_eq_oprs)
1518+
{
1519+
adatum = SysCacheGetAttr(CONSTROID, tuple,
1520+
Anum_pg_constraint_conppeqop, &isNull);
1521+
if (isNull)
1522+
elog(ERROR, "null conppeqop for constraint %u", constrId);
1523+
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1524+
if (ARR_NDIM(arr) != 1 ||
1525+
ARR_DIMS(arr)[0] != numkeys ||
1526+
ARR_HASNULL(arr) ||
1527+
ARR_ELEMTYPE(arr) != OIDOID)
1528+
elog(ERROR, "conppeqop is not a 1-D Oid array");
1529+
memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1530+
if ((Pointer) arr != DatumGetPointer(adatum))
1531+
pfree(arr); /* free de-toasted copy, if any */
1532+
}
1533+
1534+
if (ff_eq_oprs)
1535+
{
1536+
adatum = SysCacheGetAttr(CONSTROID, tuple,
1537+
Anum_pg_constraint_conffeqop, &isNull);
1538+
if (isNull)
1539+
elog(ERROR, "null conffeqop for constraint %u", constrId);
1540+
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
1541+
if (ARR_NDIM(arr) != 1 ||
1542+
ARR_DIMS(arr)[0] != numkeys ||
1543+
ARR_HASNULL(arr) ||
1544+
ARR_ELEMTYPE(arr) != OIDOID)
1545+
elog(ERROR, "conffeqop is not a 1-D Oid array");
1546+
memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
1547+
if ((Pointer) arr != DatumGetPointer(adatum))
1548+
pfree(arr); /* free de-toasted copy, if any */
1549+
}
1550+
1551+
*numfks = numkeys;
1552+
}
1553+
15331554
/*
15341555
* Determine whether a relation can be proven functionally dependent on
15351556
* a set of grouping columns. If so, return true and add the pg_constraint

src/backend/utils/adt/ri_triggers.c

Lines changed: 7 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -2189,10 +2189,6 @@ ri_LoadConstraintInfo(Oid constraintOid)
21892189
bool found;
21902190
HeapTuple tup;
21912191
Form_pg_constraint conForm;
2192-
Datum adatum;
2193-
bool isNull;
2194-
ArrayType *arr;
2195-
int numkeys;
21962192

21972193
/*
21982194
* On the first call initialize the hashtable
@@ -2234,84 +2230,13 @@ ri_LoadConstraintInfo(Oid constraintOid)
22342230
riinfo->confdeltype = conForm->confdeltype;
22352231
riinfo->confmatchtype = conForm->confmatchtype;
22362232

2237-
/*
2238-
* We expect the arrays to be 1-D arrays of the right types; verify that.
2239-
* We don't need to use deconstruct_array() since the array data is just
2240-
* going to look like a C array of values.
2241-
*/
2242-
adatum = SysCacheGetAttr(CONSTROID, tup,
2243-
Anum_pg_constraint_conkey, &isNull);
2244-
if (isNull)
2245-
elog(ERROR, "null conkey for constraint %u", constraintOid);
2246-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2247-
if (ARR_NDIM(arr) != 1 ||
2248-
ARR_HASNULL(arr) ||
2249-
ARR_ELEMTYPE(arr) != INT2OID)
2250-
elog(ERROR, "conkey is not a 1-D smallint array");
2251-
numkeys = ARR_DIMS(arr)[0];
2252-
if (numkeys <= 0 || numkeys > RI_MAX_NUMKEYS)
2253-
elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
2254-
riinfo->nkeys = numkeys;
2255-
memcpy(riinfo->fk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
2256-
if ((Pointer) arr != DatumGetPointer(adatum))
2257-
pfree(arr); /* free de-toasted copy, if any */
2258-
2259-
adatum = SysCacheGetAttr(CONSTROID, tup,
2260-
Anum_pg_constraint_confkey, &isNull);
2261-
if (isNull)
2262-
elog(ERROR, "null confkey for constraint %u", constraintOid);
2263-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2264-
if (ARR_NDIM(arr) != 1 ||
2265-
ARR_DIMS(arr)[0] != numkeys ||
2266-
ARR_HASNULL(arr) ||
2267-
ARR_ELEMTYPE(arr) != INT2OID)
2268-
elog(ERROR, "confkey is not a 1-D smallint array");
2269-
memcpy(riinfo->pk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
2270-
if ((Pointer) arr != DatumGetPointer(adatum))
2271-
pfree(arr); /* free de-toasted copy, if any */
2272-
2273-
adatum = SysCacheGetAttr(CONSTROID, tup,
2274-
Anum_pg_constraint_conpfeqop, &isNull);
2275-
if (isNull)
2276-
elog(ERROR, "null conpfeqop for constraint %u", constraintOid);
2277-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2278-
/* see TryReuseForeignKey if you change the test below */
2279-
if (ARR_NDIM(arr) != 1 ||
2280-
ARR_DIMS(arr)[0] != numkeys ||
2281-
ARR_HASNULL(arr) ||
2282-
ARR_ELEMTYPE(arr) != OIDOID)
2283-
elog(ERROR, "conpfeqop is not a 1-D Oid array");
2284-
memcpy(riinfo->pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2285-
if ((Pointer) arr != DatumGetPointer(adatum))
2286-
pfree(arr); /* free de-toasted copy, if any */
2287-
2288-
adatum = SysCacheGetAttr(CONSTROID, tup,
2289-
Anum_pg_constraint_conppeqop, &isNull);
2290-
if (isNull)
2291-
elog(ERROR, "null conppeqop for constraint %u", constraintOid);
2292-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2293-
if (ARR_NDIM(arr) != 1 ||
2294-
ARR_DIMS(arr)[0] != numkeys ||
2295-
ARR_HASNULL(arr) ||
2296-
ARR_ELEMTYPE(arr) != OIDOID)
2297-
elog(ERROR, "conppeqop is not a 1-D Oid array");
2298-
memcpy(riinfo->pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2299-
if ((Pointer) arr != DatumGetPointer(adatum))
2300-
pfree(arr); /* free de-toasted copy, if any */
2301-
2302-
adatum = SysCacheGetAttr(CONSTROID, tup,
2303-
Anum_pg_constraint_conffeqop, &isNull);
2304-
if (isNull)
2305-
elog(ERROR, "null conffeqop for constraint %u", constraintOid);
2306-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2307-
if (ARR_NDIM(arr) != 1 ||
2308-
ARR_DIMS(arr)[0] != numkeys ||
2309-
ARR_HASNULL(arr) ||
2310-
ARR_ELEMTYPE(arr) != OIDOID)
2311-
elog(ERROR, "conffeqop is not a 1-D Oid array");
2312-
memcpy(riinfo->ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2313-
if ((Pointer) arr != DatumGetPointer(adatum))
2314-
pfree(arr); /* free de-toasted copy, if any */
2233+
DeconstructFkConstraintRow(tup,
2234+
&riinfo->nkeys,
2235+
riinfo->fk_attnums,
2236+
riinfo->pk_attnums,
2237+
riinfo->pf_eq_oprs,
2238+
riinfo->pp_eq_oprs,
2239+
riinfo->ff_eq_oprs);
23152240

23162241
ReleaseSysCache(tup);
23172242

0 commit comments

Comments
 (0)