Hi.
While playing around with a -DCATCACHE_FORCE_RELEASE build, I noticed that
stats_ext test failed with errors for multiple statements that looked like
this:
ERROR: invalid ndistinct magic 7f7f7f7f (expected a352bfa4)
I figured it's because statext_dependencies_load() and
statext_ndistinct_build() both return a pointer that points directly into
a pg_statistics_ext tuple obtained by using SearchSysCache1 that has
uncertain lifetime after subsequent call to ReleaseSysCache before returning.
I think we should be calling statext_dependencies_deserialize() and
statext_ndistinct_deserialize(), respectively, *before* we perform
ReleaseSysCache on the tuple. Attached patch does that.
Thanks,
Amit
diff --git a/src/backend/statistics/dependencies.c
b/src/backend/statistics/dependencies.c
index d7305b7ab3..cbf3221ce9 100644
--- a/src/backend/statistics/dependencies.c
+++ b/src/backend/statistics/dependencies.c
@@ -631,6 +631,7 @@ dependency_implies_attribute(MVDependency *dependency,
AttrNumber attnum)
MVDependencies *
statext_dependencies_load(Oid mvoid)
{
+ MVDependencies *result;
bool isnull;
Datum deps;
HeapTuple htup = SearchSysCache1(STATEXTOID,
ObjectIdGetDatum(mvoid));
@@ -642,9 +643,11 @@ statext_dependencies_load(Oid mvoid)
Anum_pg_statistic_ext_stxdependencies, &isnull);
Assert(!isnull);
+ result = statext_dependencies_deserialize(DatumGetByteaP(deps));
+
ReleaseSysCache(htup);
- return statext_dependencies_deserialize(DatumGetByteaP(deps));
+ return result;
}
/*
diff --git a/src/backend/statistics/mvdistinct.c
b/src/backend/statistics/mvdistinct.c
index 24e74d7a1b..069d3cd6ff 100644
--- a/src/backend/statistics/mvdistinct.c
+++ b/src/backend/statistics/mvdistinct.c
@@ -126,6 +126,7 @@ statext_ndistinct_build(double totalrows, int numrows,
HeapTuple *rows,
MVNDistinct *
statext_ndistinct_load(Oid mvoid)
{
+ MVNDistinct *result;
bool isnull = false;
Datum ndist;
HeapTuple htup;
@@ -141,9 +142,11 @@ statext_ndistinct_load(Oid mvoid)
"requested statistic kind %c is not yet built for
statistics object %u",
STATS_EXT_NDISTINCT, mvoid);
+ result = statext_ndistinct_deserialize(DatumGetByteaP(ndist));
+
ReleaseSysCache(htup);
- return statext_ndistinct_deserialize(DatumGetByteaP(ndist));
+ return result;
}
/*