aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2008-01-25 04:46:07 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2008-01-25 04:46:07 +0000
commit353a1cca9f9bc1aea895627087e77807a83915e8 (patch)
treee84cb9c4046371b5cfd00445f6c125a46a9dd3bf
parent79a323ab49138c119231609554ae5aa7f6285d38 (diff)
downloadpostgresql-353a1cca9f9bc1aea895627087e77807a83915e8.tar.gz
postgresql-353a1cca9f9bc1aea895627087e77807a83915e8.zip
Release any detoasted copies of arrays that are made temporarily in
ri_FetchConstraintInfo, to avoid a query-duration memory leak when that routine is called by RI_FKey_keyequal_upd_fk (which isn't executed in a short-lived context). This problem was latent when the routine was added in February, but it didn't become serious until the varvarlena patch made it quite likely that the fields being examined would be "toasted" (ie, have short headers). Per report from Stephen Denne.
-rw-r--r--src/backend/utils/adt/ri_triggers.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 50f4b4cbc8f..7b7f49688ed 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -15,7 +15,7 @@
*
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.101 2008/01/03 21:23:15 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/utils/adt/ri_triggers.c,v 1.102 2008/01/25 04:46:07 tgl Exp $
*
* ----------
*/
@@ -3099,6 +3099,8 @@ ri_FetchConstraintInfo(RI_ConstraintInfo *riinfo,
elog(ERROR, "conkey is not a 1-D smallint array");
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);
@@ -3113,6 +3115,8 @@ ri_FetchConstraintInfo(RI_ConstraintInfo *riinfo,
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);
@@ -3127,6 +3131,8 @@ ri_FetchConstraintInfo(RI_ConstraintInfo *riinfo,
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);
@@ -3141,6 +3147,8 @@ ri_FetchConstraintInfo(RI_ConstraintInfo *riinfo,
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);
@@ -3155,6 +3163,8 @@ ri_FetchConstraintInfo(RI_ConstraintInfo *riinfo,
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);
}