2017-09-19 20:49 GMT+02:00 Merlin Moncure <mmonc...@gmail.com>: > On Tue, Sep 19, 2017 at 1:37 PM, Robert Haas <robertmh...@gmail.com> > wrote: > > On Tue, Sep 19, 2017 at 12:45 PM, Pavel Stehule <pavel.steh...@gmail.com> > wrote: > >>> You can already set a GUC with function scope. I'm not getting your > >>> point. > >> > >> yes, it is true. But implementation of #option is limited to PLpgSQL - > so > >> there is not any too much questions - GUC is global - there is lot of > >> points: > >> > >> * what is correct impact on PREPARE > >> * what is correct impact on EXECUTE > >> * what should be done if this GUC is changed .. > > > > For better or for worse, as a project we've settled on GUCs as a way > > to control behavior. I think it makes more sense to try to apply that > > option to new behaviors we want to control than to invent some new > > system. > > This seems very sensible. > > We also have infrastructure at the SQL level (SET) to manage the GUC. > Tom upthread (for pretty good reasons) extending SET to pl/pgsql > specific scoping but TBH I'm struggling as to why we need to implement > new syntax for this; the only thing missing is being able to scope SET > statements to a code block FWICT. > > here is a GUC based patch for plancache controlling. Looks so this code is working.
It is hard to create regress tests. Any ideas? Regards Pavel > merlin >
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 */
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers