Hi,
I believe the behaviour of the choose_custom_plan function should be
adjusted slightly.
The CachedPlanSource can operate in either auto mode or force a specific
plan type. Currently, the force_generic_plan option declares all plans
as generic, except one-shot plans, of course. However, the
CachedPlanSource entry also has a cursor_options field that indicates
the caller's anticipation of a specific plan type for the statement.
This means that the configuration parameter (GUC) currently overrides
any explicit request for a plan type. The documentation does not clearly
explain the rationale behind this, at least to me.
I propose that the declaration of cursor_options should take precedence
over the GUC. This change would alter the interpretation of the GUC from
a 'forced' plan type to a 'default' plan type. By making this
adjustment, users and extensions can be more assured that they will
receive the requested plan type.
If there are no objections, I will add this patch to the next commitfest.
--
regards, Andrei Lepikhov
From 7dd2140fdbdd842f454ac631ca15ec80a2ea1cab Mon Sep 17 00:00:00 2001
From: "Andrei V. Lepikhov" <lepi...@gmail.com>
Date: Mon, 14 Jul 2025 16:25:59 +0200
Subject: [PATCH v0] Make the plan cache forced modes more flexible.
---
src/backend/utils/cache/plancache.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/backend/utils/cache/plancache.c
b/src/backend/utils/cache/plancache.c
index 89a1c79e984..5b357299683 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -1170,18 +1170,18 @@ choose_custom_plan(CachedPlanSource *plansource,
ParamListInfo boundParams)
if (!StmtPlanRequiresRevalidation(plansource))
return false;
- /* Let settings force the decision */
- if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN)
- return false;
- if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN)
- return true;
-
/* See if caller wants to force the decision */
if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN)
return false;
if (plansource->cursor_options & CURSOR_OPT_CUSTOM_PLAN)
return true;
+ /* Let settings force the decision */
+ if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_GENERIC_PLAN)
+ return false;
+ if (plan_cache_mode == PLAN_CACHE_MODE_FORCE_CUSTOM_PLAN)
+ return true;
+
/* Generate custom plans until we have done at least 5 (arbitrary) */
if (plansource->num_custom_plans < 5)
return true;
--
2.50.1