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;
 }
 
 /*

Reply via email to