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