X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=pg_hint_plan.c;h=a625896c5e3ed9bebe60e214a76d1accf2a22d31;hb=c945c7b021b593a7ba86aea0f4bc9dbcd5d80ae8;hp=794aac40959a30227434a9276864881280ca137e;hpb=63570f9d7be2db5f503f6c928e2b0e74dcc9eb93;p=pghintplan%2Fpg_hint_plan.git diff --git a/pg_hint_plan.c b/pg_hint_plan.c index 794aac4..a625896 100644 --- a/pg_hint_plan.c +++ b/pg_hint_plan.c @@ -12,6 +12,7 @@ #include "postgres.h" #include "access/genam.h" #include "access/heapam.h" +#include "access/relation.h" #include "catalog/pg_collation.h" #include "catalog/pg_index.h" #include "commands/prepare.h" @@ -19,12 +20,12 @@ #include "miscadmin.h" #include "nodes/nodeFuncs.h" #include "nodes/params.h" -#include "nodes/relation.h" #include "optimizer/appendinfo.h" #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/geqo.h" #include "optimizer/joininfo.h" +#include "optimizer/optimizer.h" #include "optimizer/pathnode.h" #include "optimizer/paths.h" #include "optimizer/plancat.h" @@ -515,6 +516,7 @@ static int pg_hint_plan_debug_message_level = LOG; static bool pg_hint_plan_enable_hint_table = false; static int plpgsql_recurse_level = 0; /* PLpgSQL recursion level */ +static int recurse_level = 0; /* recursion level incl. direct SPI calls */ static int hint_inhibit_level = 0; /* Inhibit hinting if this is above 0 */ /* (This could not be above 1) */ static int max_hint_nworkers = -1; /* Maximum nworkers of Workers hints */ @@ -932,7 +934,7 @@ ParallelHintCreate(const char *hint_str, const char *keyword, { ParallelHint *hint; - hint = palloc(sizeof(ScanMethodHint)); + hint = palloc(sizeof(ParallelHint)); hint->base.hint_str = hint_str; hint->base.keyword = keyword; hint->base.hint_keyword = hint_keyword; @@ -2987,6 +2989,7 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) int save_nestlevel; PlannedStmt *result; HintState *hstate; + const char *prev_hint_str; /* * Use standard planner if pg_hint_plan is disabled or current nesting @@ -3015,9 +3018,6 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) { MemoryContext oldcontext; - if (current_hint_str) - pfree((void *)current_hint_str); - oldcontext = MemoryContextSwitchTo(TopMemoryContext); current_hint_str = get_hints_from_comment((char *)error_context_stack->arg); @@ -3082,6 +3082,14 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) } /* + * The planner call below may replace current_hint_str. Store and restore + * it so that the subsequent planning in the upper level doesn't get + * confused. + */ + recurse_level++; + prev_hint_str = current_hint_str; + + /* * Use PG_TRY mechanism to recover GUC parameters and current_hint_state to * the state when this planner started when error occurred in planner. */ @@ -3091,6 +3099,9 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) result = (*prev_planner) (parse, cursorOptions, boundParams); else result = standard_planner(parse, cursorOptions, boundParams); + + current_hint_str = prev_hint_str; + recurse_level--; } PG_CATCH(); { @@ -3098,6 +3109,8 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) * Rollback changes of GUC parameters, and pop current hint context * from hint stack to rewind the state. */ + current_hint_str = prev_hint_str; + recurse_level--; AtEOXact_GUC(true, save_nestlevel); pop_hint(); PG_RE_THROW(); @@ -3108,7 +3121,7 @@ pg_hint_plan_planner(Query *parse, int cursorOptions, ParamListInfo boundParams) /* * current_hint_str is useless after planning of the top-level query. */ - if (plpgsql_recurse_level < 1 && current_hint_str) + if (recurse_level < 1 && current_hint_str) { pfree((void *)current_hint_str); current_hint_str = NULL;