• R/O
  • HTTP
  • SSH
  • HTTPS

pg_hint_plan: Commit

firtst release


Commit MetaInfo

Revision9d0d4e2bb4559097e7bb0d84d71274822ee2fa2c (tree)
Time2020-02-17 21:07:20
AuthorKyotaro Horiguchi <horikyota.ntt@gmai...>
CommiterKyotaro Horiguchi

Log Message

Restore current hint state when returned from non-hinted query planning.

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
(a-kind-of) broken by the commit d422966 but overlooked as an
inevitable side-effect of the fix. 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

Change Summary

Incremental Difference

--- a/expected/ut-A.out
+++ b/expected/ut-A.out
@@ -4338,6 +4338,9 @@ BEGIN
43384338 RETURN new_cnt;
43394339 END;
43404340 $$ LANGUAGE plpgsql IMMUTABLE;
4341+-- The function called at the bottom desn't use a hint, the immediate
4342+-- caller level should restore its own hint. So, the first LOG from
4343+-- pg_hint_plan should use the IndexScan(t_1) hint
43414344 EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
43424345 NOTICE: nested_planner(5)
43434346 NOTICE: nested_planner(4)
@@ -4345,7 +4348,12 @@ NOTICE: nested_planner(3)
43454348 NOTICE: nested_planner(2)
43464349 NOTICE: nested_planner(1)
43474350 LOG: pg_hint_plan:
4348-no hint
4351+used hint:
4352+IndexScan(t_1)
4353+not used hint:
4354+duplication hint:
4355+error hint:
4356+
43494357 LOG: pg_hint_plan:
43504358 used hint:
43514359 IndexScan(t_1)
@@ -4372,7 +4380,9 @@ error hint:
43724380 Index Only Scan using t1_i1 on t1 t_1
43734381 (1 row)
43744382
4375-/*+SeqScan(t_2)*/
4383+-- The top level uses SeqScan(t_1), but the function should use only
4384+-- the hint in the function.
4385+/*+SeqScan(t_1) SeqScan(t_2)*/
43764386 EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
43774387 NOTICE: nested_planner(5)
43784388 NOTICE: nested_planner(4)
@@ -4409,15 +4419,18 @@ error hint:
44094419
44104420 LOG: pg_hint_plan:
44114421 used hint:
4422+SeqScan(t_1)
44124423 not used hint:
44134424 SeqScan(t_2)
44144425 duplication hint:
44154426 error hint:
44164427
4417- QUERY PLAN
4418----------------------------------------
4419- Index Only Scan using t1_i1 on t1 t_1
4420-(1 row)
4428+ QUERY PLAN
4429+--------------------------
4430+ Sort
4431+ Sort Key: c1
4432+ -> Seq Scan on t1 t_1
4433+(3 rows)
44214434
44224435 ----
44234436 ---- No. A-13-4 output of debugging log on hint status
--- a/expected/ut-S.out
+++ b/expected/ut-S.out
@@ -3761,9 +3761,8 @@ error hint:
37613761 c4 | text | | |
37623762 Indexes:
37633763 "ti1_pkey" PRIMARY KEY, btree (c1)
3764- "ti1_c2_key" UNIQUE CONSTRAINT, btree (c2)
3765- "ti1_uniq" UNIQUE, btree (c1)
37663764 "ti1_btree" btree (c1)
3765+ "ti1_c2_key" UNIQUE CONSTRAINT, btree (c2)
37673766 "ti1_expr" btree ((c1 < 100))
37683767 "ti1_gin" gin (c1)
37693768 "ti1_gist" gist (c1)
@@ -3775,6 +3774,7 @@ Indexes:
37753774 "ti1_multi" btree (c1, c2, c3, c4)
37763775 "ti1_pred" btree (lower(c4))
37773776 "ti1_ts" gin (to_tsvector('english'::regconfig, c4))
3777+ "ti1_uniq" UNIQUE, btree (c1)
37783778
37793779 EXPLAIN (COSTS false) SELECT * FROM s1.ti1 WHERE c1 < 100 AND c2 = 1 AND lower(c4) = '1' AND to_tsvector('english', c4) @@ 'a & b' AND ctid = '(1,1)';
37803780 QUERY PLAN
--- a/pg_hint_plan.c
+++ b/pg_hint_plan.c
@@ -3201,9 +3201,15 @@ standard_planner_proc:
32013201 }
32023202 current_hint_state = NULL;
32033203 if (prev_planner)
3204- return (*prev_planner) (parse, cursorOptions, boundParams);
3204+ result = (*prev_planner) (parse, cursorOptions, boundParams);
32053205 else
3206- return standard_planner(parse, cursorOptions, boundParams);
3206+ result = standard_planner(parse, cursorOptions, boundParams);
3207+
3208+ /* The upper-level planner still needs the current hint state */
3209+ if (HintStateStack != NIL)
3210+ current_hint_state = (HintState *) lfirst(list_head(HintStateStack));
3211+
3212+ return result;
32073213 }
32083214
32093215 /*
--- a/sql/ut-A.sql
+++ b/sql/ut-A.sql
@@ -1137,8 +1137,14 @@ BEGIN
11371137 END;
11381138 $$ LANGUAGE plpgsql IMMUTABLE;
11391139
1140+-- The function called at the bottom desn't use a hint, the immediate
1141+-- caller level should restore its own hint. So, the first LOG from
1142+-- pg_hint_plan should use the IndexScan(t_1) hint
11401143 EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
1141-/*+SeqScan(t_2)*/
1144+
1145+-- The top level uses SeqScan(t_1), but the function should use only
1146+-- the hint in the function.
1147+/*+SeqScan(t_1) SeqScan(t_2)*/
11421148 EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
11431149
11441150 ----
Show on old repository browser