pgsql: Fix planner crash from pfree'ing a partial path that a GatherPat

Started by Tom Lanealmost 10 years ago2 messageshackers
Jump to latest
#1Tom Lane
tgl@sss.pgh.pa.us

Fix planner crash from pfree'ing a partial path that a GatherPath uses.

We mustn't run generate_gather_paths() during add_paths_to_joinrel(),
because that function can be invoked multiple times for the same target
joinrel. Not only is it wasteful to build GatherPaths repeatedly, but
a later add_partial_path() could delete the partial path that a previously
created GatherPath depends on. Instead establish the convention that we
do generate_gather_paths() for a rel only just before set_cheapest().

The code was accidentally not broken for baserels, because as of today there
never is more than one partial path for a baserel. But that assumption
obviously has a pretty short half-life, so move the generate_gather_paths()
calls for those cases as well.

Also add some generic comments explaining how and why this all works.

Per fuzz testing by Andreas Seltenreich.

Report: <871t5pgwdt.fsf@credativ.de>

Branch
------
master

Details
-------
http://git.postgresql.org/pg/commitdiff/c45bf5751b6338488bd79ce777210285531da373

Modified Files
--------------
src/backend/optimizer/README | 15 ++++++++--
src/backend/optimizer/geqo/geqo_eval.c | 3 ++
src/backend/optimizer/path/allpaths.c | 50 ++++++++++++++++++++--------------
src/backend/optimizer/path/joinpath.c | 7 +----
src/backend/optimizer/util/pathnode.c | 30 ++++++++++++++++----
5 files changed, 71 insertions(+), 34 deletions(-)

--
Sent via pgsql-committers mailing list (pgsql-committers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-committers

#2Robert Haas
robertmhaas@gmail.com
In reply to: Tom Lane (#1)
Re: [COMMITTERS] pgsql: Fix planner crash from pfree'ing a partial path that a GatherPat

On Sat, Apr 30, 2016 at 12:29 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote:

Fix planner crash from pfree'ing a partial path that a GatherPath uses.

We mustn't run generate_gather_paths() during add_paths_to_joinrel(),
because that function can be invoked multiple times for the same target
joinrel. Not only is it wasteful to build GatherPaths repeatedly, but
a later add_partial_path() could delete the partial path that a previously
created GatherPath depends on. Instead establish the convention that we
do generate_gather_paths() for a rel only just before set_cheapest().

The code was accidentally not broken for baserels, because as of today there
never is more than one partial path for a baserel. But that assumption
obviously has a pretty short half-life, so move the generate_gather_paths()
calls for those cases as well.

Also add some generic comments explaining how and why this all works.

Per fuzz testing by Andreas Seltenreich.

Report: <871t5pgwdt.fsf@credativ.de>

Thanks!

The preposition at the end of this sentence broke my internal English parser:

+ * This must not be called until after we're done creating all partial paths
+ * for the specified relation.  (Otherwise, add_partial_path might delete a
+ * path that some GatherPath has a reference to.)

I eventually figured out what you were saying there, and it does make sense.

--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company

--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers