diff --git a/pg_hint_plan.c b/pg_hint_plan.c index 580001d1..6bf23ccb 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -574,6 +574,7 @@ static join_search_hook_type prev_join_search = NULL; static set_rel_pathlist_hook_type prev_set_rel_pathlist = NULL; static needs_fmgr_hook_type prev_needs_fmgr_hook = NULL; static fmgr_hook_type prev_fmgr_hook = NULL; +static ExecutorEnd_hook_type prev_ExecutorEnd = NULL; /* Hold reference to currently active hint */ static HintState *current_hint_state = NULL; @@ -687,6 +688,26 @@ pg_hint_plan_fmgr_hook(FmgrHookEventType event, return; } +/* + * pg_hint_ExecutorEnd + * + * Force a hint to be retrieved when we are at the top of a PL recursion + * level. This can become necessary to handle hints in queries executed + * in the extended protocol, where the executor can be executed multiple + * times in a portal, but it could be possible to fail the hint retrieval. + */ +static void +pg_hint_ExecutorEnd(QueryDesc *queryDesc) +{ + if (plpgsql_recurse_level == 0) + current_hint_retrieved = false; + + if (prev_ExecutorEnd) + prev_ExecutorEnd(queryDesc); + else + standard_ExecutorEnd(queryDesc); +} + /* * Module load callbacks */ @@ -778,6 +799,8 @@ _PG_init(void) fmgr_hook = pg_hint_plan_fmgr_hook; prev_needs_fmgr_hook = needs_fmgr_hook; needs_fmgr_hook = pg_hint_plan_needs_fmgr_hook; + prev_ExecutorEnd = ExecutorEnd_hook; + ExecutorEnd_hook = pg_hint_ExecutorEnd; } /* @@ -795,6 +818,7 @@ _PG_fini(void) set_rel_pathlist_hook = prev_set_rel_pathlist; needs_fmgr_hook = prev_needs_fmgr_hook; fmgr_hook = prev_fmgr_hook; + ExecutorEnd_hook = prev_ExecutorEnd; /* uninstall PL/pgSQL plugin hook */ var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");