diff --git a/CHANGELOG.md b/CHANGELOG.md index 59c077291..79373713a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ accidentally triggering the load of a previous DB version.** * #3979 Fix deparsing of index predicates * #4015 Eliminate float rounding instabilities in interpolate * #4020 Fix ALTER TABLE EventTrigger initialization +* #4024 Fix premature cache release call **Thanks** * @erikhh for reporting an issue with time_bucket_gapfill diff --git a/src/hypertable_cache.h b/src/hypertable_cache.h index 3d97243bb..5b526dde9 100644 --- a/src/hypertable_cache.h +++ b/src/hypertable_cache.h @@ -13,6 +13,34 @@ #include "hypertable.h" #include "export.h" +/* When a hypertable entry ht is fetched using the cache + * i.e. ts_hypertable_cache_get_entry and variants, all related information such as + * hyperspaces, dimensions etc are also fetched into the cache. These are allocated in + * the cache's memory context. + * If the cache pin is released by calling ts_cache_release or variants, the memory + * associated with hypertable, its space dimensions etc. have also been released. + * As a best practice, call ts_cache_release right before returning from the function + * where the cache entry was acquired. This prevents inadvertent errors if someone + * modifies this function later and uses an indirectly linked object from the cache. + * Example: + * void my_func(...) + * { + * + * Hypertable * ht = ts_hypertable_cache_get_xxx(...) + * ...... + * + * if ( error ) + * { + * elog(ERROR, ... ); <----- ts_cache_release not needed here. + * } + * + * ..... + * ts_cache_release(); + * return ..; + * } + * Note that any exceptions/errors i.e. elog/ereport etc. will trigger an automatic + * cache release. So there is no need for additional ts_cache_release() calls. + */ extern TSDLLEXPORT Hypertable *ts_hypertable_cache_get_entry(Cache *const cache, const Oid relid, const unsigned int flags); extern TSDLLEXPORT Hypertable *ts_hypertable_cache_get_cache_and_entry(const Oid relid, diff --git a/src/utils.c b/src/utils.c index 4ac48335d..f290b09f5 100644 --- a/src/utils.c +++ b/src/utils.c @@ -886,7 +886,6 @@ ts_subtract_integer_from_now(PG_FUNCTION_ARGS) Cache *hcache; Hypertable *ht = ts_hypertable_cache_get_cache_and_entry(ht_relid, CACHE_FLAG_NONE, &hcache); const Dimension *dim = hyperspace_get_open_dimension(ht->space, 0); - ts_cache_release(hcache); if (!dim) elog(ERROR, "hypertable has no open partitioning dimension"); @@ -901,5 +900,6 @@ ts_subtract_integer_from_now(PG_FUNCTION_ARGS) elog(ERROR, "could not find valid integer_now function for hypertable"); int64 res = ts_sub_integer_from_now(lag, partitioning_type, now_func); + ts_cache_release(hcache); return Int64GetDatum(res); }