Skip to content

Commit

Permalink
Reset more aggressively hints for queries executed via extended query…
Browse files Browse the repository at this point in the history
… protocol

A query executed with the extended query protocol may entirely ignore
hints defined in it, as the only moment where a hint is reset is when a
query is restarted.  This commit introduces a hook for ExecutorEnd(),
which is a code path taken at the end of each individual execution
happening through a Portal when using the extended query protocol.

After this patch, it should be possible to make the reset of
current_hint_retrieved less optimistic, but the current logic does not
hurt as well as the end of executor would match with the next query to
come in for most users.

Per report and patch #12741 in yugabyte-db, also reported as #145 in
pg_hint_plan.

Reported-by: Furutani-san (kfuru)
Author: tanujnay112
Backpatch-through: 11
  • Loading branch information
michaelpq committed Sep 6, 2023
1 parent b750e84 commit df651c7
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions pg_hint_plan.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ static post_parse_analyze_hook_type prev_post_parse_analyze_hook = NULL;
static planner_hook_type prev_planner = NULL;
static join_search_hook_type prev_join_search = NULL;
static set_rel_pathlist_hook_type prev_set_rel_pathlist = NULL;
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;

/* Hold reference to currently active hint */
static HintState *current_hint_state = NULL;
Expand Down Expand Up @@ -639,6 +640,26 @@ PLpgSQL_plugin plugin_funcs = {
NULL,
};

/*
* 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
*/
Expand Down Expand Up @@ -728,6 +749,8 @@ _PG_init(void)
join_search_hook = pg_hint_plan_join_search;
prev_set_rel_pathlist = set_rel_pathlist_hook;
set_rel_pathlist_hook = pg_hint_plan_set_rel_pathlist;
prev_ExecutorEnd = ExecutorEnd_hook;
ExecutorEnd_hook = pg_hint_ExecutorEnd;

/* setup PL/pgSQL plugin hook */
var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");
Expand All @@ -749,6 +772,7 @@ _PG_fini(void)
planner_hook = prev_planner;
join_search_hook = prev_join_search;
set_rel_pathlist_hook = prev_set_rel_pathlist;
ExecutorEnd_hook = prev_ExecutorEnd;

/* uninstall PL/pgSQL plugin hook */
var_ptr = (PLpgSQL_plugin **) find_rendezvous_variable("PLpgSQL_plugin");
Expand Down

0 comments on commit df651c7

Please sign in to comment.