OSDN Git Service

Restore current hint state when returned from non-hinted query planning. PG95
authorKyotaro Horiguchi <horikyota.ntt@gmail.com>
Mon, 17 Feb 2020 11:45:36 +0000 (20:45 +0900)
committerKyotaro Horiguchi <horikyota.ntt@gmail.com>
Mon, 17 Feb 2020 12:08:43 +0000 (21:08 +0900)
If no hint is given for the current level query, pg_hint_plan_planner
calls the next level of planner after erasing the
current_hint_state. But it forgot to restore the state before the
planning of the rest part of the current-level query.  It is broken by
the commit 958c60d but overlooked among vast amount of behavioral
changes..  Get back the behavior by restoring current_hint_state after
returned from the lower level planner with unhinted query.

Issue: https://github.com/ossc-db/pg_hint_plan/issues/30
Reported-by: higuchi-daisuke
expected/ut-A.out
pg_hint_plan.c

index e740a16..0e46ea7 100644 (file)
@@ -4260,7 +4260,12 @@ SQL statement "SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1)
         ORDER BY t_1.c1 LIMIT 1"
 PL/pgSQL function nested_planner(integer) line 12 at SQL statement
 LOG:  pg_hint_plan:
-no hint
+used hint:
+IndexScan(t_1)
+not used hint:
+duplication hint:
+error hint:
+
 CONTEXT:  SQL statement "SELECT /*+ IndexScan(t_1) */ nested_planner(cnt - 1)                 FROM s1.t1 t_1
          JOIN s1.t2 t_2 ON (t_1.c1 = t_2.c1)
         ORDER BY t_1.c1 LIMIT 1"
index b7bc728..170b86b 100644 (file)
@@ -2863,9 +2863,15 @@ standard_planner_proc:
        }
        current_hint = NULL;
        if (prev_planner)
-               return (*prev_planner) (parse, cursorOptions, boundParams);
+               result = (*prev_planner) (parse, cursorOptions, boundParams);
        else
-               return standard_planner(parse, cursorOptions, boundParams);
+               result = standard_planner(parse, cursorOptions, boundParams);
+
+       /* The upper-level planner still needs the current hint state */
+       if (HintStateStack != NIL)
+               current_hint = (HintState *) lfirst(list_head(HintStateStack));
+
+       return result;
 }
 
 /*