diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c index ad8a82f1e3..cc99cf6dcc 100644 --- a/src/backend/utils/cache/plancache.c +++ b/src/backend/utils/cache/plancache.c @@ -106,6 +106,8 @@ static void PlanCacheRelCallback(Datum arg, Oid relid); static void PlanCacheFuncCallback(Datum arg, int cacheid, uint32 hashvalue); static void PlanCacheSysCallback(Datum arg, int cacheid, uint32 hashvalue); +/* GUC parameter */ +int plancache_mode; /* * InitPlanCache: initialize module during InitPostgres. @@ -1031,6 +1033,12 @@ choose_custom_plan(CachedPlanSource *plansource, ParamListInfo boundParams) if (IsTransactionStmtPlan(plansource)) return false; + /* See if settings wants to force the decision */ + if (plancache_mode & PLANCACHE_FORCE_GENERIC_PLAN) + return false; + if (plancache_mode & PLANCACHE_FORCE_CUSTOM_PLAN) + return true; + /* See if caller wants to force the decision */ if (plansource->cursor_options & CURSOR_OPT_GENERIC_PLAN) return false; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index ae22185fbd..4ce275e39d 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -403,6 +403,13 @@ static const struct config_enum_entry force_parallel_mode_options[] = { {NULL, 0, false} }; +static const struct config_enum_entry plancache_mode_options[] = { + {"default", PLANCACHE_DEFAULT, false}, + {"force_generic_plan", PLANCACHE_FORCE_GENERIC_PLAN, false}, + {"force_custom_plan", PLANCACHE_FORCE_CUSTOM_PLAN, false}, + {NULL, 0, false} +}; + /* * password_encryption used to be a boolean, so accept all the likely * variants of "on", too. "off" used to store passwords in plaintext, @@ -3916,6 +3923,16 @@ static struct config_enum ConfigureNamesEnum[] = NULL, NULL, NULL }, + { + {"plancache_mode", PGC_USERSET, QUERY_TUNING_OTHER, + gettext_noop("Forces use of custom or generic plans."), + gettext_noop("It can control query plan cache.") + }, + &plancache_mode, + PLANCACHE_DEFAULT, plancache_mode_options, + NULL, NULL, NULL + }, + /* End-of-list marker */ { {NULL, 0, 0, NULL, NULL}, NULL, 0, NULL, NULL, NULL, NULL diff --git a/src/include/utils/plancache.h b/src/include/utils/plancache.h index 87fab19f3c..962895cc1a 100644 --- a/src/include/utils/plancache.h +++ b/src/include/utils/plancache.h @@ -143,7 +143,6 @@ typedef struct CachedPlan MemoryContext context; /* context containing this CachedPlan */ } CachedPlan; - extern void InitPlanCache(void); extern void ResetPlanCache(void); @@ -182,4 +181,16 @@ extern CachedPlan *GetCachedPlan(CachedPlanSource *plansource, QueryEnvironment *queryEnv); extern void ReleaseCachedPlan(CachedPlan *plan, bool useResOwner); +/* possible values for plancache_mode */ +typedef enum +{ + PLANCACHE_DEFAULT, + PLANCACHE_FORCE_GENERIC_PLAN, + PLANCACHE_FORCE_CUSTOM_PLAN +} PlanCacheMode; + + +/* GUC parameter */ +extern int plancache_mode; + #endif /* PLANCACHE_H */