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

Reply via email to