From: Tom Lane Date: Mon, 11 Apr 2016 03:47:30 +0000 (-0400) Subject: Clean up foreign-key caching code in planner. X-Git-Tag: REL9_6_BETA1~202 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5306df2831ab012d8008691f833457bc299962aa;p=postgresql Clean up foreign-key caching code in planner. Coverity complained that the code added by 015e88942aa50f0d 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. --- diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c index 86cc640cf2..9c11b09cbc 100644 --- a/src/backend/optimizer/util/plancat.c +++ b/src/backend/optimizer/util/plancat.c @@ -408,17 +408,20 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, foreach(l, fkoidlist) { - int i; - ArrayType *arr; + Oid fkoid = lfirst_oid(l); + HeapTuple htup; + Form_pg_constraint constraint; + ForeignKeyOptInfo *info; Datum adatum; bool isnull; + ArrayType *arr; int numkeys; - Oid fkoid = lfirst_oid(l); - - HeapTuple htup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fkoid)); - Form_pg_constraint constraint = (Form_pg_constraint) GETSTRUCT(htup); + int i; - ForeignKeyOptInfo *info; + htup = SearchSysCache1(CONSTROID, ObjectIdGetDatum(fkoid)); + if (!HeapTupleIsValid(htup)) /* should not happen */ + elog(ERROR, "cache lookup failed for constraint %u", fkoid); + constraint = (Form_pg_constraint) GETSTRUCT(htup); Assert(constraint->contype == CONSTRAINT_FOREIGN); @@ -434,8 +437,7 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, arr = DatumGetArrayTypeP(adatum); 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++) info->conkeys[i] = ((int16 *) ARR_DATA_PTR(arr))[i]; @@ -445,9 +447,8 @@ get_relation_info(PlannerInfo *root, Oid relationObjectId, bool inhparent, Assert(!isnull); arr = DatumGetArrayTypeP(adatum); - numkeys = ARR_DIMS(arr)[0]; - info->confkeys = (int*)palloc0(numkeys * sizeof(int)); - + Assert(numkeys == ARR_DIMS(arr)[0]); + info->confkeys = (int*)palloc(numkeys * sizeof(int)); for (i = 0; i < numkeys; 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); arr = DatumGetArrayTypeP(adatum); - numkeys = ARR_DIMS(arr)[0]; - info->conpfeqop = (Oid*)palloc0(numkeys * sizeof(Oid)); - + Assert(numkeys == ARR_DIMS(arr)[0]); + info->conpfeqop = (Oid*)palloc(numkeys * sizeof(Oid)); for (i = 0; i < numkeys; 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); - fkinfos = lcons(info, fkinfos); + fkinfos = lappend(fkinfos, info); } list_free(fkoidlist);