Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+111-90
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

+7-82
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)