WIP: Add pg_plan_advice contrib module. advice_unstable
authorRobert Haas <[email protected]>
Tue, 4 Nov 2025 19:45:31 +0000 (14:45 -0500)
committerRobert Haas <[email protected]>
Thu, 6 Nov 2025 16:41:59 +0000 (11:41 -0500)
commitdb2b53bf41f405b83ac4e3c621703a32530850a4
treea42551554faa767e3f648bb09844f7c68186217b
parent05efbb59f18c403be4c7df2a5c115254d0dd81ae
WIP: Add pg_plan_advice contrib module.

Provide a facility that (1) can be used to stabilize certain plan choices
so that the planner cannot reverse course without authorization and
(2) can be used by knowledgeable users to insist on plan choices contrary
to what the planner believes best. In both cases, terrible outcomes are
possible: users should think twice and perhaps three times before
constraining the planner's ability to do as it thinks best; nevertheless,
there are problems that are much more easily solved with these facilities
than without them.

We take the approach of analyzing a finished plan to produce textual
output, which we call "plan advice", that describes key decisions made
during plan; if that plan advice is provided during future planning
cycles, it will force those key decisions to be made in the same way.
Not all planner decisions can be controlled using advice; for example,
decisions about how to perform aggregation are currently out of scope,
as is choice of sort order. Plan advice can also be edited by the user,
or even written from scratch in simple cases, making it possible to
generate outcomes that the planner would not have produced. Partial
advice can be provided to control some planner outcomes but not others.

Currently, plan advice is focused only on specific outcomes, such as
the choice to use a sequential scan for a particular relation, and not
on estimates that might contribute to those outcomes, such as a
possibly-incorrect selectivity estimate. While it would be useful to
users to be able to provide plan advice that affects selectivity
estimates or other aspects of costing, that is out of scope for this
commit.

For more details, see contrib/pg_plan_advice/README.

NOTE: This code is just a proof of concept. A bunch of things don't
work and a lot of the code needs cleanup. It has no SGML documentation
and not enough test cases, and some of the existing test cases don't
do as we would hope. Known problems are called out by XXX.
46 files changed:
contrib/Makefile
contrib/meson.build
contrib/pg_plan_advice/.gitignore [new file with mode: 0644]
contrib/pg_plan_advice/Makefile [new file with mode: 0644]
contrib/pg_plan_advice/README [new file with mode: 0644]
contrib/pg_plan_advice/expected/gather.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/join_order.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/join_strategy.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/local_collector.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/partitionwise.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/scan.out [new file with mode: 0644]
contrib/pg_plan_advice/expected/syntax.out [new file with mode: 0644]
contrib/pg_plan_advice/meson.build [new file with mode: 0644]
contrib/pg_plan_advice/pg_plan_advice--1.0.sql [new file with mode: 0644]
contrib/pg_plan_advice/pg_plan_advice.c [new file with mode: 0644]
contrib/pg_plan_advice/pg_plan_advice.control [new file with mode: 0644]
contrib/pg_plan_advice/pg_plan_advice.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_ast.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_ast.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_collector.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_collector.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_identifier.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_identifier.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_join.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_join.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_output.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_output.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_parser.y [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_planner.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_planner.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_scan.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_scan.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_scanner.l [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_trove.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_trove.h [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_walker.c [new file with mode: 0644]
contrib/pg_plan_advice/pgpa_walker.h [new file with mode: 0644]
contrib/pg_plan_advice/sql/gather.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/join_order.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/join_strategy.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/local_collector.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/partitionwise.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/scan.sql [new file with mode: 0644]
contrib/pg_plan_advice/sql/syntax.sql [new file with mode: 0644]
contrib/pg_plan_advice/t/001_regress.pl [new file with mode: 0644]
src/tools/pgindent/typedefs.list