ossc-db / pg_hint_plan

Extension adding support for optimizer hints in PostgreSQL
Other
715 stars 103 forks source link

Simplify tracking of recursive call depth inside PL/pgSQL functions #131

Closed michaelpq closed 1 year ago

michaelpq commented 1 year ago

This commit replaces and simplifies the calculation of the counter tracking the recursion level inside PL/pgSQL functions by relying on fmgr_start and end hooks within the function manager for this purpose. The previous implementation had a huge flaw: it failed to properly detect the case of exceptions in PL functions, hence it would be possible the static counter so badly that the hint to use would be incorrect, or utterly broken in some cases where it would finish by being negative when stacking exceptions. a9863af has provided a band-aid fix to address this issue, but it has forced the erase_callback of PL/pgSQL to force a level of 0 when reaching the top-level, while the correct method would be to decrement the counter, and apply sanity checks to make sure that the depth calculation is not messed up.

This commit switches the calculation of the depth to not rely any more on a resource owner callback or the plpgsql start/end hooks, as it happens that the function manager is correctly able:

The only tweak that needs to be done is to check if a function needs to call the fmgr hook, something that can be done by checking if the function is written in PL/pgSQL. Eventhough this requires caching the language OID on the first lookup, the change is quite intuitive.

Relying on the fmgr hook has the advantage to not require the registration of the resowner callback for all the backends, saving some cycles in the most common cases.

The PL cases are extended a bit to check for more scenarios:

michaelpq commented 1 year ago

So, this has been around a bit, and I'd like to get this bugfix applied on HEAD if there are no objections. Feel free if you have any.

michaelpq commented 1 year ago

Now applied as of 7c6d950.