postgresql/src/backend/utils/cache
Tom Lane 27566bcf3c Avoid unnecessary plancache revalidation of utility statements.
Revalidation of a plancache entry (after a cache invalidation event)
requires acquiring a snapshot.  Normally that is harmless, but not
if the cached statement is one that needs to run without acquiring a
snapshot.  We were already aware of that for TransactionStmts,
but for some reason hadn't extrapolated to the other statements that
PlannedStmtRequiresSnapshot() knows mustn't set a snapshot.  This can
lead to unexpected failures of commands such as SET TRANSACTION
ISOLATION LEVEL.  We can fix it in the same way, by excluding those
command types from revalidation.

However, we can do even better than that: there is no need to
revalidate for any statement type for which parse analysis, rewrite,
and plan steps do nothing interesting, which is nearly all utility
commands.  To mechanize this, invent a parser function
stmt_requires_parse_analysis() that tells whether parse analysis does
anything beyond wrapping a CMD_UTILITY Query around the raw parse
tree.  If that's what it does, then rewrite and plan will just
skip the Query, so that it is not possible for the same raw parse
tree to produce a different plan tree after cache invalidation.

stmt_requires_parse_analysis() is basically equivalent to the
existing function analyze_requires_snapshot(), except that for
obscure reasons that function omits ReturnStmt and CallStmt.
It is unclear whether those were oversights or intentional.
I have not been able to demonstrate a bug from not acquiring a
snapshot while analyzing these commands, but at best it seems mighty
fragile.  It seems safer to acquire a snapshot for parse analysis of
these commands too, which allows making stmt_requires_parse_analysis
and analyze_requires_snapshot equivalent.

In passing this fixes a second bug, which is that ResetPlanCache
would exclude ReturnStmts and CallStmts from revalidation.
That's surely *not* safe, since they contain parsable expressions.

Per bug #18059 from Pavel Kulakov.  Back-patch to all supported
branches.

Discussion: https://postgr.es/m/18059-79c692f036b25346@postgresql.org
2023-08-24 12:02:40 -04:00
..
attoptcache.c Update copyrights for 2020 2020-01-01 12:21:45 -05:00
catcache.c Fix omissions in support for the "regcollation" type. 2022-07-17 17:43:28 -04:00
evtcache.c Introduce macros for typalign and typstorage constants. 2020-03-04 10:34:25 -05:00
inval.c Fix back-patch of "Avoid race in RelationBuildDesc() ..." 2022-02-09 18:16:56 -08:00
lsyscache.c Preserve pg_attribute.attstattarget across REINDEX CONCURRENTLY 2021-02-10 13:09:09 +09:00
Makefile Split all OBJS style lines in makefiles into one-line-per-entry style. 2019-11-05 14:41:07 -08:00
partcache.c Update copyrights for 2020 2020-01-01 12:21:45 -05:00
plancache.c Avoid unnecessary plancache revalidation of utility statements. 2023-08-24 12:02:40 -04:00
relcache.c Add indisreplident to fields refreshed by RelationReloadIndexInfo() 2023-07-14 11:16:10 +09:00
relfilenodemap.c Spelling adjustments 2020-06-07 15:06:51 +02:00
relmapper.c Another fix to relmapper race condition. 2021-06-24 11:19:31 +03:00
spccache.c Introduce a maintenance_io_concurrency setting. 2020-03-16 17:14:26 +13:00
syscache.c Update copyrights for 2020 2020-01-01 12:21:45 -05:00
ts_cache.c Update copyrights for 2020 2020-01-01 12:21:45 -05:00
typcache.c Fix assign_record_type_typmod(). 2021-07-10 10:27:27 -07:00