Skip to content

Commit 447dbf7

Browse files
committed
Fix bogus code for extracting extended-statistics data from syscache.
statext_dependencies_load and statext_ndistinct_load were not up to snuff, in addition to being randomly different from each other. In detail: * Deserialize the fetched bytea value before releasing the syscache entry, not after. This mistake causes visible regression test failures when running with -DCATCACHE_FORCE_RELEASE. Since it's not exposed by -DCLOBBER_CACHE_ALWAYS, I think there may be no production hazard here at present, but it's at least a latent bug. * Use DatumGetByteaPP not DatumGetByteaP to save a detoasting cycle for short stats values; the deserialize function has to be, and is, prepared for short-header values since its other caller uses PP. * Use a test-and-elog for null stats values in both functions, rather than a test-and-elog in one case and an Assert in the other. Perhaps Asserts would be sufficient in both cases, but I don't see a good argument for them being different. * Minor cosmetic changes to make these functions more visibly alike. Backpatch to v10 where this code came in. Amit Langote, minor additional hacking by me Discussion: https://postgr.es/m/1349aabb-3a1f-6675-9fc0-65e2ce7491dd@lab.ntt.co.jp
1 parent bcded26 commit 447dbf7

File tree

2 files changed

+17
-7
lines changed

2 files changed

+17
-7
lines changed

src/backend/statistics/dependencies.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -631,20 +631,27 @@ dependency_implies_attribute(MVDependency *dependency, AttrNumber attnum)
631631
MVDependencies *
632632
statext_dependencies_load(Oid mvoid)
633633
{
634+
MVDependencies *result;
634635
bool isnull;
635636
Datum deps;
636-
HeapTuple htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid));
637+
HeapTuple htup;
637638

639+
htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid));
638640
if (!HeapTupleIsValid(htup))
639641
elog(ERROR, "cache lookup failed for statistics object %u", mvoid);
640642

641643
deps = SysCacheGetAttr(STATEXTOID, htup,
642644
Anum_pg_statistic_ext_stxdependencies, &isnull);
643-
Assert(!isnull);
645+
if (isnull)
646+
elog(ERROR,
647+
"requested statistic kind \"%c\" is not yet built for statistics object %u",
648+
STATS_EXT_DEPENDENCIES, mvoid);
649+
650+
result = statext_dependencies_deserialize(DatumGetByteaPP(deps));
644651

645652
ReleaseSysCache(htup);
646653

647-
return statext_dependencies_deserialize(DatumGetByteaP(deps));
654+
return result;
648655
}
649656

650657
/*

src/backend/statistics/mvdistinct.c

+7-4
Original file line numberDiff line numberDiff line change
@@ -126,24 +126,27 @@ statext_ndistinct_build(double totalrows, int numrows, HeapTuple *rows,
126126
MVNDistinct *
127127
statext_ndistinct_load(Oid mvoid)
128128
{
129-
bool isnull = false;
129+
MVNDistinct *result;
130+
bool isnull;
130131
Datum ndist;
131132
HeapTuple htup;
132133

133134
htup = SearchSysCache1(STATEXTOID, ObjectIdGetDatum(mvoid));
134-
if (!htup)
135+
if (!HeapTupleIsValid(htup))
135136
elog(ERROR, "cache lookup failed for statistics object %u", mvoid);
136137

137138
ndist = SysCacheGetAttr(STATEXTOID, htup,
138139
Anum_pg_statistic_ext_stxndistinct, &isnull);
139140
if (isnull)
140141
elog(ERROR,
141-
"requested statistic kind %c is not yet built for statistics object %u",
142+
"requested statistic kind \"%c\" is not yet built for statistics object %u",
142143
STATS_EXT_NDISTINCT, mvoid);
143144

145+
result = statext_ndistinct_deserialize(DatumGetByteaPP(ndist));
146+
144147
ReleaseSysCache(htup);
145148

146-
return statext_ndistinct_deserialize(DatumGetByteaP(ndist));
149+
return result;
147150
}
148151

149152
/*

0 commit comments

Comments
 (0)