Pgtk::Stash caches non-deterministic queries (CURRENT_TIMESTAMP, RANDOM, etc.)
#378 opened on Jun 6, 2026
Repository metrics
- Stars
- (8 stars)
- PR merge metrics
- (PR metrics pending)
Description
Description
Pgtk::Stash#select skips caching only for queries containing NOW() (with spaces):
cache(pure, key, params, result, ret, tables, marks) unless pure.include?(" NOW() ")
This misses many other non-deterministic SQL functions, which get cached with incorrect (stale) results:
| Expression | Cached? | Correct? |
|---|---|---|
NOW() (with spaces) |
No | Yes |
CURRENT_TIMESTAMP |
Yes | No — bug |
CURRENT_DATE |
Yes | No — bug |
CURRENT_TIME |
Yes | No — bug |
LOCALTIMESTAMP |
Yes | No — bug |
RANDOM() |
Yes | No — bug |
GEN_RANDOM_UUID() |
Yes | No — bug |
CLOCK_TIMESTAMP() |
Yes | No — bug |
NOW() (no spaces: NOW()) |
Yes | No — bug |
The check is also whitespace-sensitive: SELECT NOW() is skipped, but SELECT NOW() with exactly no space before the paren passes through.
Impact
- Queries using any non-deterministic function besides
NOW()return stale cached data - Example:
SELECT CURRENT_TIMESTAMPreturns the same timestamp on every call - Example:
SELECT RANDOM() FROM generate_series(1,10)returns the same values every call - The cache silently serves incorrect data with no indication of staleness
Suggested fix
Replace the single NOW() check with a regex covering the common non-deterministic expressions:
NONDETERMINISTIC = /\b(NOW|CURRENT_TIMESTAMP|CURRENT_DATE|CURRENT_TIME|LOCALTIMESTAMP|LOCALTIME|RANDOM|GEN_RANDOM_UUID|CLOCK_TIMESTAMP|TIMEZONE)\s*\(/i
def select(pure, params, result)
# ...
cache(pure, key, params, result, ret, tables, marks) unless pure.match?(NONDETERMINISTIC)
# ...
end
Related previous work
This is a continuation of the same caching-correctness theme addressed in earlier issues:
- #368 — Stash table_mod non-monotonic stamp
- #364 — Stash skips invalidation for tables with underscores/digits
- #336 — Stash persistently-stale empty SELECT
Unlike those issues (which were about cache invalidation), this one is about cache prevention — queries that should never be cached in the first place because they are non-deterministic by nature.