firtst release
リビジョン | a9bcfa75e63483f3bf671d4185438e3febf22fe4 (tree) |
---|---|
日時 | 2020-02-17 21:08:03 |
作者 | Kyotaro Horiguchi <horikyota.ntt@gmai...> |
コミッター | Kyotaro Horiguchi |
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
@@ -4324,6 +4324,9 @@ BEGIN | ||
4324 | 4324 | RETURN new_cnt; |
4325 | 4325 | END; |
4326 | 4326 | $$ LANGUAGE plpgsql IMMUTABLE; |
4327 | +-- The function called at the bottom desn't use a hint, the immediate | |
4328 | +-- caller level should restore its own hint. So, the first LOG from | |
4329 | +-- pg_hint_plan should use the IndexScan(t_1) hint | |
4327 | 4330 | EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; |
4328 | 4331 | NOTICE: nested_planner(5) |
4329 | 4332 | NOTICE: nested_planner(4) |
@@ -4331,7 +4334,12 @@ NOTICE: nested_planner(3) | ||
4331 | 4334 | NOTICE: nested_planner(2) |
4332 | 4335 | NOTICE: nested_planner(1) |
4333 | 4336 | LOG: pg_hint_plan: |
4334 | -no hint | |
4337 | +used hint: | |
4338 | +IndexScan(t_1) | |
4339 | +not used hint: | |
4340 | +duplication hint: | |
4341 | +error hint: | |
4342 | + | |
4335 | 4343 | LOG: pg_hint_plan: |
4336 | 4344 | used hint: |
4337 | 4345 | IndexScan(t_1) |
@@ -4358,7 +4366,9 @@ error hint: | ||
4358 | 4366 | Index Only Scan using t1_i1 on t1 t_1 |
4359 | 4367 | (1 row) |
4360 | 4368 | |
4361 | -/*+SeqScan(t_2)*/ | |
4369 | +-- The top level uses SeqScan(t_1), but the function should use only | |
4370 | +-- the hint in the function. | |
4371 | +/*+SeqScan(t_1) SeqScan(t_2)*/ | |
4362 | 4372 | EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; |
4363 | 4373 | NOTICE: nested_planner(5) |
4364 | 4374 | NOTICE: nested_planner(4) |
@@ -4395,15 +4405,18 @@ error hint: | ||
4395 | 4405 | |
4396 | 4406 | LOG: pg_hint_plan: |
4397 | 4407 | used hint: |
4408 | +SeqScan(t_1) | |
4398 | 4409 | not used hint: |
4399 | 4410 | SeqScan(t_2) |
4400 | 4411 | duplication hint: |
4401 | 4412 | error hint: |
4402 | 4413 | |
4403 | - QUERY PLAN | |
4404 | ---------------------------------------- | |
4405 | - Index Only Scan using t1_i1 on t1 t_1 | |
4406 | -(1 row) | |
4414 | + QUERY PLAN | |
4415 | +-------------------------- | |
4416 | + Sort | |
4417 | + Sort Key: c1 | |
4418 | + -> Seq Scan on t1 t_1 | |
4419 | +(3 rows) | |
4407 | 4420 | |
4408 | 4421 | ---- |
4409 | 4422 | ---- No. A-13-4 output of debugging log on hint status |
@@ -3196,9 +3196,15 @@ standard_planner_proc: | ||
3196 | 3196 | } |
3197 | 3197 | current_hint_state = NULL; |
3198 | 3198 | if (prev_planner) |
3199 | - return (*prev_planner) (parse, cursorOptions, boundParams); | |
3199 | + result = (*prev_planner) (parse, cursorOptions, boundParams); | |
3200 | 3200 | else |
3201 | - return standard_planner(parse, cursorOptions, boundParams); | |
3201 | + result = standard_planner(parse, cursorOptions, boundParams); | |
3202 | + | |
3203 | + /* The upper-level planner still needs the current hint state */ | |
3204 | + if (HintStateStack != NIL) | |
3205 | + current_hint_state = (HintState *) lfirst(list_head(HintStateStack)); | |
3206 | + | |
3207 | + return result; | |
3202 | 3208 | } |
3203 | 3209 | |
3204 | 3210 | /* |
@@ -1137,8 +1137,14 @@ BEGIN | ||
1137 | 1137 | END; |
1138 | 1138 | $$ LANGUAGE plpgsql IMMUTABLE; |
1139 | 1139 | |
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 | |
1140 | 1143 | 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)*/ | |
1142 | 1148 | EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1; |
1143 | 1149 | |
1144 | 1150 | ---- |