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

Skip to content

Commit e974f22

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 3daac78 commit e974f22

File tree

4 files changed

+124
-228
lines changed

4 files changed

+124
-228
lines changed

src/backend/catalog/pg_constraint.c

Lines changed: 109 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -450,14 +450,11 @@ static void
450450
clone_fk_constraints(Relation pg_constraint, Relation parentRel,
451451
Relation partRel, List *clone, List **cloned)
452452
{
453-
TupleDesc tupdesc;
454453
AttrNumber *attmap;
455454
List *partFKs;
456455
List *subclone = NIL;
457456
ListCell *cell;
458457

459-
tupdesc = RelationGetDescr(pg_constraint);
460-
461458
/*
462459
* The constraint key may differ, if the columns in the partition are
463460
* different. This map is used to convert them.
@@ -487,9 +484,6 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
487484
int nelem;
488485
ListCell *cell;
489486
int i;
490-
ArrayType *arr;
491-
Datum datum;
492-
bool isnull;
493487

494488
tuple = SearchSysCache1(CONSTROID, parentConstrOid);
495489
if (!tuple)
@@ -506,93 +500,11 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
506500

507501
ObjectAddressSet(parentAddr, ConstraintRelationId, parentConstrOid);
508502

509-
datum = fastgetattr(tuple, Anum_pg_constraint_conkey,
510-
tupdesc, &isnull);
511-
if (isnull)
512-
elog(ERROR, "null conkey");
513-
arr = DatumGetArrayTypeP(datum);
514-
nelem = ARR_DIMS(arr)[0];
515-
if (ARR_NDIM(arr) != 1 ||
516-
nelem < 1 ||
517-
nelem > INDEX_MAX_KEYS ||
518-
ARR_HASNULL(arr) ||
519-
ARR_ELEMTYPE(arr) != INT2OID)
520-
elog(ERROR, "conkey is not a 1-D smallint array");
521-
memcpy(conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
522-
503+
DeconstructFkConstraintRow(tuple, &nelem, conkey, confkey,
504+
conpfeqop, conppeqop, conffeqop);
523505
for (i = 0; i < nelem; i++)
524506
mapped_conkey[i] = attmap[conkey[i] - 1];
525507

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

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

23422338
/*
23432339
* On the first call initialize the hashtable
@@ -2379,84 +2375,13 @@ ri_LoadConstraintInfo(Oid constraintOid)
23792375
riinfo->confdeltype = conForm->confdeltype;
23802376
riinfo->confmatchtype = conForm->confmatchtype;
23812377

2382-
/*
2383-
* We expect the arrays to be 1-D arrays of the right types; verify that.
2384-
* We don't need to use deconstruct_array() since the array data is just
2385-
* going to look like a C array of values.
2386-
*/
2387-
adatum = SysCacheGetAttr(CONSTROID, tup,
2388-
Anum_pg_constraint_conkey, &isNull);
2389-
if (isNull)
2390-
elog(ERROR, "null conkey for constraint %u", constraintOid);
2391-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2392-
if (ARR_NDIM(arr) != 1 ||
2393-
ARR_HASNULL(arr) ||
2394-
ARR_ELEMTYPE(arr) != INT2OID)
2395-
elog(ERROR, "conkey is not a 1-D smallint array");
2396-
numkeys = ARR_DIMS(arr)[0];
2397-
if (numkeys <= 0 || numkeys > RI_MAX_NUMKEYS)
2398-
elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
2399-
riinfo->nkeys = numkeys;
2400-
memcpy(riinfo->fk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
2401-
if ((Pointer) arr != DatumGetPointer(adatum))
2402-
pfree(arr); /* free de-toasted copy, if any */
2403-
2404-
adatum = SysCacheGetAttr(CONSTROID, tup,
2405-
Anum_pg_constraint_confkey, &isNull);
2406-
if (isNull)
2407-
elog(ERROR, "null confkey for constraint %u", constraintOid);
2408-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2409-
if (ARR_NDIM(arr) != 1 ||
2410-
ARR_DIMS(arr)[0] != numkeys ||
2411-
ARR_HASNULL(arr) ||
2412-
ARR_ELEMTYPE(arr) != INT2OID)
2413-
elog(ERROR, "confkey is not a 1-D smallint array");
2414-
memcpy(riinfo->pk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
2415-
if ((Pointer) arr != DatumGetPointer(adatum))
2416-
pfree(arr); /* free de-toasted copy, if any */
2417-
2418-
adatum = SysCacheGetAttr(CONSTROID, tup,
2419-
Anum_pg_constraint_conpfeqop, &isNull);
2420-
if (isNull)
2421-
elog(ERROR, "null conpfeqop for constraint %u", constraintOid);
2422-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2423-
/* see TryReuseForeignKey if you change the test below */
2424-
if (ARR_NDIM(arr) != 1 ||
2425-
ARR_DIMS(arr)[0] != numkeys ||
2426-
ARR_HASNULL(arr) ||
2427-
ARR_ELEMTYPE(arr) != OIDOID)
2428-
elog(ERROR, "conpfeqop is not a 1-D Oid array");
2429-
memcpy(riinfo->pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2430-
if ((Pointer) arr != DatumGetPointer(adatum))
2431-
pfree(arr); /* free de-toasted copy, if any */
2432-
2433-
adatum = SysCacheGetAttr(CONSTROID, tup,
2434-
Anum_pg_constraint_conppeqop, &isNull);
2435-
if (isNull)
2436-
elog(ERROR, "null conppeqop for constraint %u", constraintOid);
2437-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2438-
if (ARR_NDIM(arr) != 1 ||
2439-
ARR_DIMS(arr)[0] != numkeys ||
2440-
ARR_HASNULL(arr) ||
2441-
ARR_ELEMTYPE(arr) != OIDOID)
2442-
elog(ERROR, "conppeqop is not a 1-D Oid array");
2443-
memcpy(riinfo->pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2444-
if ((Pointer) arr != DatumGetPointer(adatum))
2445-
pfree(arr); /* free de-toasted copy, if any */
2446-
2447-
adatum = SysCacheGetAttr(CONSTROID, tup,
2448-
Anum_pg_constraint_conffeqop, &isNull);
2449-
if (isNull)
2450-
elog(ERROR, "null conffeqop for constraint %u", constraintOid);
2451-
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
2452-
if (ARR_NDIM(arr) != 1 ||
2453-
ARR_DIMS(arr)[0] != numkeys ||
2454-
ARR_HASNULL(arr) ||
2455-
ARR_ELEMTYPE(arr) != OIDOID)
2456-
elog(ERROR, "conffeqop is not a 1-D Oid array");
2457-
memcpy(riinfo->ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
2458-
if ((Pointer) arr != DatumGetPointer(adatum))
2459-
pfree(arr); /* free de-toasted copy, if any */
2378+
DeconstructFkConstraintRow(tup,
2379+
&riinfo->nkeys,
2380+
riinfo->fk_attnums,
2381+
riinfo->pk_attnums,
2382+
riinfo->pf_eq_oprs,
2383+
riinfo->pp_eq_oprs,
2384+
riinfo->ff_eq_oprs);
24602385

24612386
ReleaseSysCache(tup);
24622387

0 commit comments

Comments
 (0)