Clean up foreign-key caching code in planner.

Coverity complained that the code added by 015e88942a lacked an
error check for SearchSysCache1 failures, which it should have.  But
the code was pretty duff in other ways too, including failure to think
about whether it could really cope with arrays of different lengths.
This commit is contained in:
Tom Lane 2016-04-10 23:47:30 -04:00
parent 7e3bb08038
commit 5306df2831

View File

@ -408,17 +408,20 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
foreach(l, fkoidlist) foreach(l, fkoidlist)
{ {
int i; Oid fkoid = lfirst_oid(l);
ArrayType *arr; HeapTuple htup;
Form_pg_constraint constraint;
ForeignKeyOptInfo *info;
Datum adatum; Datum adatum;
bool isnull; bool isnull;
ArrayType *arr;
int numkeys; int numkeys;
Oid fkoid = lfirst_oid(l); int i;
HeapTuple htup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fkoid)); htup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fkoid));
Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup); if (!HeapTupleIsValid(htup)) /* should not happen */
elog(ERROR, "cache lookup failed for constraint %u", fkoid);
ForeignKeyOptInfo *info; constraint = (Form_pg_constraint) GETSTRUCT(htup);
Assert(constraint->contype == CONSTRAINT_FOREIGN); Assert(constraint->contype == CONSTRAINT_FOREIGN);
@ -434,8 +437,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
arr = DatumGetArrayTypeP(adatum); arr = DatumGetArrayTypeP(adatum);
numkeys = ARR_DIMS(arr)[0]; numkeys = ARR_DIMS(arr)[0];
info->conkeys = (int*)palloc0(numkeys * sizeof(int)); info->conkeys = (int*)palloc(numkeys * sizeof(int));
for (i = 0; i < numkeys; i++) for (i = 0; i < numkeys; i++)
info->conkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i]; info->conkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i];
@ -445,9 +447,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
Assert(!isnull); Assert(!isnull);
arr = DatumGetArrayTypeP(adatum); arr = DatumGetArrayTypeP(adatum);
numkeys = ARR_DIMS(arr)[0]; Assert(numkeys == ARR_DIMS(arr)[0]);
info->confkeys = (int*)palloc0(numkeys * sizeof(int)); info->confkeys = (int*)palloc(numkeys * sizeof(int));
for (i = 0; i < numkeys; i++) for (i = 0; i < numkeys; i++)
info->confkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i]; info->confkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i];
@ -457,9 +458,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
Assert(!isnull); Assert(!isnull);
arr = DatumGetArrayTypeP(adatum); arr = DatumGetArrayTypeP(adatum);
numkeys = ARR_DIMS(arr)[0]; Assert(numkeys == ARR_DIMS(arr)[0]);
info->conpfeqop = (Oid*)palloc0(numkeys * sizeof(Oid)); info->conpfeqop = (Oid*)palloc(numkeys * sizeof(Oid));
for (i = 0; i < numkeys; i++) for (i = 0; i < numkeys; i++)
info->conpfeqop[i] = ((Oid *) ARR_DATA_PTR(arr))[i]; info->conpfeqop[i] = ((Oid *) ARR_DATA_PTR(arr))[i];
@ -467,7 +467,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent,
ReleaseSysCache(htup); ReleaseSysCache(htup);
fkinfos = lcons(info, fkinfos); fkinfos = lappend(fkinfos, info);
} }
list_free(fkoidlist); list_free(fkoidlist);