mirror of
https://github.com/postgres/postgres.git
synced 2025-04-27 22:56:53 +03:00
Refactor duplicate code into DeconstructFkConstraintRow
My commit 3de241dba86f 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.
This commit is contained in:
parent
9194c4270b
commit
0080396dad
@ -446,14 +446,11 @@ static void
|
|||||||
clone_fk_constraints(Relation pg_constraint, Relation parentRel,
|
clone_fk_constraints(Relation pg_constraint, Relation parentRel,
|
||||||
Relation partRel, List *clone, List **cloned)
|
Relation partRel, List *clone, List **cloned)
|
||||||
{
|
{
|
||||||
TupleDesc tupdesc;
|
|
||||||
AttrNumber *attmap;
|
AttrNumber *attmap;
|
||||||
List *partFKs;
|
List *partFKs;
|
||||||
List *subclone = NIL;
|
List *subclone = NIL;
|
||||||
ListCell *cell;
|
ListCell *cell;
|
||||||
|
|
||||||
tupdesc = RelationGetDescr(pg_constraint);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The constraint key may differ, if the columns in the partition are
|
* The constraint key may differ, if the columns in the partition are
|
||||||
* different. This map is used to convert them.
|
* different. This map is used to convert them.
|
||||||
@ -483,9 +480,6 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
|
|||||||
int nelem;
|
int nelem;
|
||||||
ListCell *cell;
|
ListCell *cell;
|
||||||
int i;
|
int i;
|
||||||
ArrayType *arr;
|
|
||||||
Datum datum;
|
|
||||||
bool isnull;
|
|
||||||
|
|
||||||
tuple = SearchSysCache1(CONSTROID, parentConstrOid);
|
tuple = SearchSysCache1(CONSTROID, parentConstrOid);
|
||||||
if (!tuple)
|
if (!tuple)
|
||||||
@ -502,93 +496,11 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
|
|||||||
|
|
||||||
ObjectAddressSet(parentAddr, ConstraintRelationId, parentConstrOid);
|
ObjectAddressSet(parentAddr, ConstraintRelationId, parentConstrOid);
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_conkey,
|
DeconstructFkConstraintRow(tuple, &nelem, conkey, confkey,
|
||||||
tupdesc, &isnull);
|
conpfeqop, conppeqop, conffeqop);
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conkey");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "conkey is not a 1-D smallint array");
|
|
||||||
memcpy(conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
|
|
||||||
|
|
||||||
for (i = 0; i < nelem; i++)
|
for (i = 0; i < nelem; i++)
|
||||||
mapped_conkey[i] = attmap[conkey[i] - 1];
|
mapped_conkey[i] = attmap[conkey[i] - 1];
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_confkey,
|
|
||||||
tupdesc, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null confkey");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "confkey is not a 1-D smallint array");
|
|
||||||
memcpy(confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
|
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
|
|
||||||
tupdesc, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conpfeqop");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conpfeqop is not a 1-D OID array");
|
|
||||||
memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
|
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_conpfeqop,
|
|
||||||
tupdesc, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conpfeqop");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conpfeqop is not a 1-D OID array");
|
|
||||||
memcpy(conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
|
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_conppeqop,
|
|
||||||
tupdesc, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conppeqop");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conppeqop is not a 1-D OID array");
|
|
||||||
memcpy(conppeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
|
|
||||||
|
|
||||||
datum = fastgetattr(tuple, Anum_pg_constraint_conffeqop,
|
|
||||||
tupdesc, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conffeqop");
|
|
||||||
arr = DatumGetArrayTypeP(datum);
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conffeqop is not a 1-D OID array");
|
|
||||||
memcpy(conffeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Before creating a new constraint, see whether any existing FKs are
|
* Before creating a new constraint, see whether any existing FKs are
|
||||||
* fit for the purpose. If one is, attach the parent constraint to it,
|
* 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)
|
|||||||
return pkattnos;
|
return pkattnos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Extract data from the pg_constraint tuple of a foreign-key constraint.
|
||||||
|
*
|
||||||
|
* All arguments save the first are output arguments; the last three of them
|
||||||
|
* can be passed as NULL if caller doesn't need them.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
|
||||||
|
AttrNumber *conkey, AttrNumber *confkey,
|
||||||
|
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs)
|
||||||
|
{
|
||||||
|
Oid constrId;
|
||||||
|
Datum adatum;
|
||||||
|
bool isNull;
|
||||||
|
ArrayType *arr;
|
||||||
|
int numkeys;
|
||||||
|
|
||||||
|
constrId = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We expect the arrays to be 1-D arrays of the right types; verify that.
|
||||||
|
* We don't need to use deconstruct_array() since the array data is just
|
||||||
|
* going to look like a C array of values.
|
||||||
|
*/
|
||||||
|
adatum = SysCacheGetAttr(CONSTROID, tuple,
|
||||||
|
Anum_pg_constraint_conkey, &isNull);
|
||||||
|
if (isNull)
|
||||||
|
elog(ERROR, "null conkey for constraint %u", constrId);
|
||||||
|
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
||||||
|
if (ARR_NDIM(arr) != 1 ||
|
||||||
|
ARR_HASNULL(arr) ||
|
||||||
|
ARR_ELEMTYPE(arr) != INT2OID)
|
||||||
|
elog(ERROR, "conkey is not a 1-D smallint array");
|
||||||
|
numkeys = ARR_DIMS(arr)[0];
|
||||||
|
if (numkeys <= 0 || numkeys > INDEX_MAX_KEYS)
|
||||||
|
elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
|
||||||
|
memcpy(conkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
|
||||||
|
if ((Pointer) arr != DatumGetPointer(adatum))
|
||||||
|
pfree(arr); /* free de-toasted copy, if any */
|
||||||
|
|
||||||
|
adatum = SysCacheGetAttr(CONSTROID, tuple,
|
||||||
|
Anum_pg_constraint_confkey, &isNull);
|
||||||
|
if (isNull)
|
||||||
|
elog(ERROR, "null confkey for constraint %u", constrId);
|
||||||
|
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
||||||
|
if (ARR_NDIM(arr) != 1 ||
|
||||||
|
ARR_DIMS(arr)[0] != numkeys ||
|
||||||
|
ARR_HASNULL(arr) ||
|
||||||
|
ARR_ELEMTYPE(arr) != INT2OID)
|
||||||
|
elog(ERROR, "confkey is not a 1-D smallint array");
|
||||||
|
memcpy(confkey, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
|
||||||
|
if ((Pointer) arr != DatumGetPointer(adatum))
|
||||||
|
pfree(arr); /* free de-toasted copy, if any */
|
||||||
|
|
||||||
|
if (pf_eq_oprs)
|
||||||
|
{
|
||||||
|
adatum = SysCacheGetAttr(CONSTROID, tuple,
|
||||||
|
Anum_pg_constraint_conpfeqop, &isNull);
|
||||||
|
if (isNull)
|
||||||
|
elog(ERROR, "null conpfeqop for constraint %u", constrId);
|
||||||
|
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
||||||
|
/* see TryReuseForeignKey if you change the test below */
|
||||||
|
if (ARR_NDIM(arr) != 1 ||
|
||||||
|
ARR_DIMS(arr)[0] != numkeys ||
|
||||||
|
ARR_HASNULL(arr) ||
|
||||||
|
ARR_ELEMTYPE(arr) != OIDOID)
|
||||||
|
elog(ERROR, "conpfeqop is not a 1-D Oid array");
|
||||||
|
memcpy(pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
||||||
|
if ((Pointer) arr != DatumGetPointer(adatum))
|
||||||
|
pfree(arr); /* free de-toasted copy, if any */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pp_eq_oprs)
|
||||||
|
{
|
||||||
|
adatum = SysCacheGetAttr(CONSTROID, tuple,
|
||||||
|
Anum_pg_constraint_conppeqop, &isNull);
|
||||||
|
if (isNull)
|
||||||
|
elog(ERROR, "null conppeqop for constraint %u", constrId);
|
||||||
|
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
||||||
|
if (ARR_NDIM(arr) != 1 ||
|
||||||
|
ARR_DIMS(arr)[0] != numkeys ||
|
||||||
|
ARR_HASNULL(arr) ||
|
||||||
|
ARR_ELEMTYPE(arr) != OIDOID)
|
||||||
|
elog(ERROR, "conppeqop is not a 1-D Oid array");
|
||||||
|
memcpy(pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
||||||
|
if ((Pointer) arr != DatumGetPointer(adatum))
|
||||||
|
pfree(arr); /* free de-toasted copy, if any */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ff_eq_oprs)
|
||||||
|
{
|
||||||
|
adatum = SysCacheGetAttr(CONSTROID, tuple,
|
||||||
|
Anum_pg_constraint_conffeqop, &isNull);
|
||||||
|
if (isNull)
|
||||||
|
elog(ERROR, "null conffeqop for constraint %u", constrId);
|
||||||
|
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
||||||
|
if (ARR_NDIM(arr) != 1 ||
|
||||||
|
ARR_DIMS(arr)[0] != numkeys ||
|
||||||
|
ARR_HASNULL(arr) ||
|
||||||
|
ARR_ELEMTYPE(arr) != OIDOID)
|
||||||
|
elog(ERROR, "conffeqop is not a 1-D Oid array");
|
||||||
|
memcpy(ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
||||||
|
if ((Pointer) arr != DatumGetPointer(adatum))
|
||||||
|
pfree(arr); /* free de-toasted copy, if any */
|
||||||
|
}
|
||||||
|
|
||||||
|
*numfks = numkeys;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Determine whether a relation can be proven functionally dependent on
|
* Determine whether a relation can be proven functionally dependent on
|
||||||
* a set of grouping columns. If so, return true and add the pg_constraint
|
* a set of grouping columns. If so, return true and add the pg_constraint
|
||||||
|
@ -2189,10 +2189,6 @@ ri_LoadConstraintInfo(Oid constraintOid)
|
|||||||
bool found;
|
bool found;
|
||||||
HeapTuple tup;
|
HeapTuple tup;
|
||||||
Form_pg_constraint conForm;
|
Form_pg_constraint conForm;
|
||||||
Datum adatum;
|
|
||||||
bool isNull;
|
|
||||||
ArrayType *arr;
|
|
||||||
int numkeys;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On the first call initialize the hashtable
|
* On the first call initialize the hashtable
|
||||||
@ -2234,84 +2230,13 @@ ri_LoadConstraintInfo(Oid constraintOid)
|
|||||||
riinfo->confdeltype = conForm->confdeltype;
|
riinfo->confdeltype = conForm->confdeltype;
|
||||||
riinfo->confmatchtype = conForm->confmatchtype;
|
riinfo->confmatchtype = conForm->confmatchtype;
|
||||||
|
|
||||||
/*
|
DeconstructFkConstraintRow(tup,
|
||||||
* We expect the arrays to be 1-D arrays of the right types; verify that.
|
&riinfo->nkeys,
|
||||||
* We don't need to use deconstruct_array() since the array data is just
|
riinfo->fk_attnums,
|
||||||
* going to look like a C array of values.
|
riinfo->pk_attnums,
|
||||||
*/
|
riinfo->pf_eq_oprs,
|
||||||
adatum = SysCacheGetAttr(CONSTROID, tup,
|
riinfo->pp_eq_oprs,
|
||||||
Anum_pg_constraint_conkey, &isNull);
|
riinfo->ff_eq_oprs);
|
||||||
if (isNull)
|
|
||||||
elog(ERROR, "null conkey for constraint %u", constraintOid);
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "conkey is not a 1-D smallint array");
|
|
||||||
numkeys = ARR_DIMS(arr)[0];
|
|
||||||
if (numkeys <= 0 || numkeys > RI_MAX_NUMKEYS)
|
|
||||||
elog(ERROR, "foreign key constraint cannot have %d columns", numkeys);
|
|
||||||
riinfo->nkeys = numkeys;
|
|
||||||
memcpy(riinfo->fk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
|
|
||||||
if ((Pointer) arr != DatumGetPointer(adatum))
|
|
||||||
pfree(arr); /* free de-toasted copy, if any */
|
|
||||||
|
|
||||||
adatum = SysCacheGetAttr(CONSTROID, tup,
|
|
||||||
Anum_pg_constraint_confkey, &isNull);
|
|
||||||
if (isNull)
|
|
||||||
elog(ERROR, "null confkey for constraint %u", constraintOid);
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
ARR_DIMS(arr)[0] != numkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "confkey is not a 1-D smallint array");
|
|
||||||
memcpy(riinfo->pk_attnums, ARR_DATA_PTR(arr), numkeys * sizeof(int16));
|
|
||||||
if ((Pointer) arr != DatumGetPointer(adatum))
|
|
||||||
pfree(arr); /* free de-toasted copy, if any */
|
|
||||||
|
|
||||||
adatum = SysCacheGetAttr(CONSTROID, tup,
|
|
||||||
Anum_pg_constraint_conpfeqop, &isNull);
|
|
||||||
if (isNull)
|
|
||||||
elog(ERROR, "null conpfeqop for constraint %u", constraintOid);
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
/* see TryReuseForeignKey if you change the test below */
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
ARR_DIMS(arr)[0] != numkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conpfeqop is not a 1-D Oid array");
|
|
||||||
memcpy(riinfo->pf_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
|
||||||
if ((Pointer) arr != DatumGetPointer(adatum))
|
|
||||||
pfree(arr); /* free de-toasted copy, if any */
|
|
||||||
|
|
||||||
adatum = SysCacheGetAttr(CONSTROID, tup,
|
|
||||||
Anum_pg_constraint_conppeqop, &isNull);
|
|
||||||
if (isNull)
|
|
||||||
elog(ERROR, "null conppeqop for constraint %u", constraintOid);
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
ARR_DIMS(arr)[0] != numkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conppeqop is not a 1-D Oid array");
|
|
||||||
memcpy(riinfo->pp_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
|
||||||
if ((Pointer) arr != DatumGetPointer(adatum))
|
|
||||||
pfree(arr); /* free de-toasted copy, if any */
|
|
||||||
|
|
||||||
adatum = SysCacheGetAttr(CONSTROID, tup,
|
|
||||||
Anum_pg_constraint_conffeqop, &isNull);
|
|
||||||
if (isNull)
|
|
||||||
elog(ERROR, "null conffeqop for constraint %u", constraintOid);
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
ARR_DIMS(arr)[0] != numkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conffeqop is not a 1-D Oid array");
|
|
||||||
memcpy(riinfo->ff_eq_oprs, ARR_DATA_PTR(arr), numkeys * sizeof(Oid));
|
|
||||||
if ((Pointer) arr != DatumGetPointer(adatum))
|
|
||||||
pfree(arr); /* free de-toasted copy, if any */
|
|
||||||
|
|
||||||
ReleaseSysCache(tup);
|
ReleaseSysCache(tup);
|
||||||
|
|
||||||
|
61
src/backend/utils/cache/relcache.c
vendored
61
src/backend/utils/cache/relcache.c
vendored
@ -4125,10 +4125,6 @@ RelationGetFKeyList(Relation relation)
|
|||||||
{
|
{
|
||||||
Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup);
|
Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup);
|
||||||
ForeignKeyCacheInfo *info;
|
ForeignKeyCacheInfo *info;
|
||||||
Datum adatum;
|
|
||||||
bool isnull;
|
|
||||||
ArrayType *arr;
|
|
||||||
int nelem;
|
|
||||||
|
|
||||||
/* consider only foreign keys */
|
/* consider only foreign keys */
|
||||||
if (constraint->contype != CONSTRAINT_FOREIGN)
|
if (constraint->contype != CONSTRAINT_FOREIGN)
|
||||||
@ -4139,58 +4135,11 @@ RelationGetFKeyList(Relation relation)
|
|||||||
info->conrelid = constraint->conrelid;
|
info->conrelid = constraint->conrelid;
|
||||||
info->confrelid = constraint->confrelid;
|
info->confrelid = constraint->confrelid;
|
||||||
|
|
||||||
/* Extract data from conkey field */
|
DeconstructFkConstraintRow(htup, &info->nkeys,
|
||||||
adatum = fastgetattr(htup, Anum_pg_constraint_conkey,
|
info->conkey,
|
||||||
conrel->rd_att, &isnull);
|
info->confkey,
|
||||||
if (isnull)
|
info->conpfeqop,
|
||||||
elog(ERROR, "null conkey for rel %s",
|
NULL, NULL);
|
||||||
RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem < 1 ||
|
|
||||||
nelem > INDEX_MAX_KEYS ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "conkey is not a 1-D smallint array");
|
|
||||||
|
|
||||||
info->nkeys = nelem;
|
|
||||||
memcpy(info->conkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
|
|
||||||
|
|
||||||
/* Likewise for confkey */
|
|
||||||
adatum = fastgetattr(htup, Anum_pg_constraint_confkey,
|
|
||||||
conrel->rd_att, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null confkey for rel %s",
|
|
||||||
RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem != info->nkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != INT2OID)
|
|
||||||
elog(ERROR, "confkey is not a 1-D smallint array");
|
|
||||||
|
|
||||||
memcpy(info->confkey, ARR_DATA_PTR(arr), nelem * sizeof(AttrNumber));
|
|
||||||
|
|
||||||
/* Likewise for conpfeqop */
|
|
||||||
adatum = fastgetattr(htup, Anum_pg_constraint_conpfeqop,
|
|
||||||
conrel->rd_att, &isnull);
|
|
||||||
if (isnull)
|
|
||||||
elog(ERROR, "null conpfeqop for rel %s",
|
|
||||||
RelationGetRelationName(relation));
|
|
||||||
|
|
||||||
arr = DatumGetArrayTypeP(adatum); /* ensure not toasted */
|
|
||||||
nelem = ARR_DIMS(arr)[0];
|
|
||||||
if (ARR_NDIM(arr) != 1 ||
|
|
||||||
nelem != info->nkeys ||
|
|
||||||
ARR_HASNULL(arr) ||
|
|
||||||
ARR_ELEMTYPE(arr) != OIDOID)
|
|
||||||
elog(ERROR, "conpfeqop is not a 1-D OID array");
|
|
||||||
|
|
||||||
memcpy(info->conpfeqop, ARR_DATA_PTR(arr), nelem * sizeof(Oid));
|
|
||||||
|
|
||||||
/* Add FK's node to the result list */
|
/* Add FK's node to the result list */
|
||||||
result = lappend(result, info);
|
result = lappend(result, info);
|
||||||
|
@ -251,6 +251,9 @@ extern Oid get_relation_idx_constraint_oid(Oid relationId, Oid indexId);
|
|||||||
|
|
||||||
extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk,
|
extern Bitmapset *get_primary_key_attnos(Oid relid, bool deferrableOk,
|
||||||
Oid *constraintOid);
|
Oid *constraintOid);
|
||||||
|
extern void DeconstructFkConstraintRow(HeapTuple tuple, int *numfks,
|
||||||
|
AttrNumber *conkey, AttrNumber *confkey,
|
||||||
|
Oid *pf_eq_oprs, Oid *pp_eq_oprs, Oid *ff_eq_oprs);
|
||||||
|
|
||||||
extern bool check_functional_grouping(Oid relid,
|
extern bool check_functional_grouping(Oid relid,
|
||||||
Index varno, Index varlevelsup,
|
Index varno, Index varlevelsup,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user