Re: pg_plan_advice
Robert Haas <robertmhaas@gmail.com>
On Thu, Jan 8, 2026 at 6:29 PM Michael Paquier <michael@paquier.xyz> wrote: > So you are telling me that I can commit code that deletes code. Count > me in. The project has some merge requests that I've been holding on > a bit due to what's happening here and because I did not really look > at the internals that have changed. It's great to see that you have > begun an investigation, Lukas. :-) > I suspect that this is going to be an incremental integration process, > and it smells to me that it is going to require more than one major > release before being able to remove the whole set of hacks that > pg_hint_plan has been using, particularly with the GUCs, the costing > and the forced update of the backend routines which is a ugly > historical hack. Saying that, I would need to look at the plan > outputs to be sure, perhaps we would be OK even with slight changes. > These happen every year, because the plans tested are complex enough > that some of the sub-paths are changed, but the hints still work > properly. This year for v19 we have at least the changes in the > expression names. I think it's quite possible that you could do a full rip and replace with some study of what needs to be added on top of 0004. The core idea of 0004 is that it adds a field called pgs_mask in several of places, which allows you to set a bitmask to control which operations the planner will consider to be enabled. You can set this via some existing hooks, and it also adds a a new hook (joinrel_setup_hook) which is called near the start of add_paths_to_joinrel(). So, you can set pgs_mask in PlannerGlobal to control planning for the entire operation, RelOptInfo to control it for a particular rel, or JoinPathExtraData to set it for a particular joinrel and a particular choice of outer and inner rel. I am pretty well convinced that this is a good model: instead of duplicating a bunch of planner code, as pg_hint_plan currently does, just have a way to tell the existing planner code what you want it to do. Now, one fly in the ointment is that pgs_mask is just a mask -- that is, it gives us space to store 64 related Booleans, but nothing else. So if we want to store an integer, like a number of parallel workers, we need a separate field for that. But if that integer can reasonably be set at the same levels that are possible for pgs_mask, it's really easy: just look at the places where 0004 adds a pgs_mask field, and add an integer field as well. There is obviously some limit to the number of fields we can reasonably add to PlannerGlobal, RelOptInfo, and JoinPathExtraData, but if it starts to become too much, we could bundle some or all of them up in a struct. The patch has already figured out how to get the mask to propagate down to the places where low-level planning decisions are being made, so it seems worth trying to piggy-back on that for anything else that we need. Now, maybe that won't work out for some reason. But on the other hand, maybe it will work out. I think it's possible that for the price of a quite small patch adding another field or a couple of fields on top of pgs_mask and in the same places, you could get rid of a lot more code. -- Robert Haas EDB: http://www.enterprisedb.com
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
pg_plan_advice: Fix another unique-semijoin bug.
- 4321dcad475b 19 (unreleased) landed
-
pg_plan_advice: Export feedback-related definitions.
- c644aca24089 19 (unreleased) landed
-
pg_plan_advice: Fix a bug when a subquery is pruned away entirely.
- 0f93ebb3112d 19 (unreleased) landed
-
pg_plan_advice: Add alternatives test to Makefile.
- 1faf9dfa4796 19 (unreleased) landed
-
pg_plan_advice: Handle non-repeatable TABLESAMPLE scans.
- 3311ccc3d24b 19 (unreleased) landed
-
pg_stash_advice: Allow stashed advice to be persisted to disk.
- c10edb102ada 19 (unreleased) landed
-
Add pg_stash_advice contrib module.
- e8ec19aa321a 19 (unreleased) landed
-
pg_plan_advice: Avoid assertion failure with partitionwise aggregate.
- e2ee95233cab 19 (unreleased) landed
-
pg_plan_advice: Invent DO_NOT_SCAN(relation_identifier).
- 6455e55b0da4 19 (unreleased) landed
-
Add an alternative_plan_name field to PlannerInfo.
- 26255a320733 19 (unreleased) landed
-
pg_plan_advice: Refactor to invent pgpa_planner_info
- 5dcb15e89af2 19 (unreleased) landed
-
Respect disabled_nodes in fix_alternative_subplan.
- 47c110f77e75 19 (unreleased) landed
-
get_memoize_path: Don't exit quickly when PGS_NESTLOOP_PLAIN is unset.
- dc47beacaa0b 19 (unreleased) landed
-
test_plan_advice: Set TAP test priority 50 in meson.build.
- 12444183e401 19 (unreleased) landed
-
pg_plan_advice: Avoid a crash under GEQO.
- 01b02c0ecad1 19 (unreleased) landed
-
Test pg_plan_advice using a new test_plan_advice module.
- e0e4c132ef2b 19 (unreleased) landed
-
pg_plan_advice: Always install pg_plan_advice.h, and in the right place
- 59dcc19b397f 19 (unreleased) landed
-
pg_plan_advice: Fix failures to accept identifier keywords.
- 5e72ce2467c1 19 (unreleased) landed
-
Add pg_plan_advice contrib module.
- 5883ff30b02c 19 (unreleased) landed
-
Allow extensions to mark an individual index as disabled.
- 0fbfd37cefb7 19 (unreleased) landed
-
Replace get_relation_info_hook with build_simple_rel_hook.
- 91f33a2ae92a 19 (unreleased) landed
-
Store information about Append node consolidation in the final plan.
- 7358abcc6076 19 (unreleased) landed
-
Store information about elided nodes in the final plan.
- 0d4391b265f8 19 (unreleased) landed
-
Store information about range-table flattening in the final plan.
- adbad833f3d9 19 (unreleased) landed
-
Pass cursorOptions to planner_setup_hook.
- 0f4c8d33d49d 19 (unreleased) landed
-
Fix PGS_CONSIDER_NONPARTIAL interaction with Materialize nodes.
- cbdf93d47122 19 (unreleased) landed
-
Fix mistakes in commit 4020b370f214315b8c10430301898ac21658143f
- 71c1136989b3 19 (unreleased) landed
-
Allow for plugin control over path generation strategies.
- 4020b370f214 19 (unreleased) landed
-
Update some comments for fasthash
- 7892e2592471 19 (unreleased) landed
-
Allow passing a pointer to GetNamedDSMSegment()'s init callback.
- 48d4a1423d2e 19 (unreleased) cited
-
Don't reset the pathlist of partitioned joinrels.
- 014f9a831a32 19 (unreleased) cited
-
Treat number of disabled nodes in a path as a separate cost metric.
- e22253467942 18.0 cited