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
RETURN new_cnt;
END;
$$ LANGUAGE plpgsql IMMUTABLE;
+-- The function called at the bottom desn't use a hint, the immediate
+-- caller level should restore its own hint. So, the first LOG from
+-- pg_hint_plan should use the IndexScan(t_1) hint
EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
NOTICE: nested_planner(5)
NOTICE: nested_planner(4)
NOTICE: nested_planner(2)
NOTICE: nested_planner(1)
LOG: pg_hint_plan:
-no hint
+used hint:
+IndexScan(t_1)
+not used hint:
+duplication hint:
+error hint:
+
LOG: pg_hint_plan:
used hint:
IndexScan(t_1)
Index Only Scan using t1_i1 on t1 t_1
(1 row)
-/*+SeqScan(t_2)*/
+-- The top level uses SeqScan(t_1), but the function should use only
+-- the hint in the function.
+/*+SeqScan(t_1) SeqScan(t_2)*/
EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
NOTICE: nested_planner(5)
NOTICE: nested_planner(4)
LOG: pg_hint_plan:
used hint:
+SeqScan(t_1)
not used hint:
SeqScan(t_2)
duplication hint:
error hint:
- QUERY PLAN
----------------------------------------
- Index Only Scan using t1_i1 on t1 t_1
-(1 row)
+ QUERY PLAN
+--------------------------
+ Sort
+ Sort Key: c1
+ -> Seq Scan on t1 t_1
+(3 rows)
----
---- No. A-13-4 output of debugging log on hint status
}
current_hint_state = 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_state = (HintState *) lfirst(list_head(HintStateStack));
+
+ return result;
}
/*
END;
$$ LANGUAGE plpgsql IMMUTABLE;
+-- The function called at the bottom desn't use a hint, the immediate
+-- caller level should restore its own hint. So, the first LOG from
+-- pg_hint_plan should use the IndexScan(t_1) hint
EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
-/*+SeqScan(t_2)*/
+
+-- The top level uses SeqScan(t_1), but the function should use only
+-- the hint in the function.
+/*+SeqScan(t_1) SeqScan(t_2)*/
EXPLAIN (COSTS false) SELECT nested_planner(5) FROM s1.t1 t_1 ORDER BY t_1.c1;
----