Re: BUG #18627: Regression (15 -> 16) - Join removal not performed when join condition spans multiple tables

Tom Lane <tgl@sss.pgh.pa.us>

From: Tom Lane <tgl@sss.pgh.pa.us>
To: Richard Guo <guofenglinux@gmail.com>
Cc: David Rowley <dgrowleyml@gmail.com>, gourlaouen.mikael@gmail.com, pgsql-bugs@lists.postgresql.org
Date: 2024-09-25T20:33:42Z
Lists: pgsql-bugs

Attachments

I wrote:
> I'm taking a second look at the idea of regenerating the attr_needed
> values altogether.  It doesn't look that bad, especially if we cheat
> to the extent of preserving the existing "relation 0" bits (that is,
> tlist and HAVING references).  That's fine since we could never
> remove a rel that supplies Vars used in those places.

Here's a finished patch that fixes it along those lines.

I worried that this might have nasty performance impact, so I added
some instr_time calls (not included in patch) to check the runtime of
remove_useless_joins() by itself as well as the overall planner run
time.  Using a test case like

SELECT a.id
FROM a
LEFT JOIN b ON a.id = b.id

I found that HEAD takes about 500ns on my machine to run
remove_useless_joins, out of a total planner run time of about 12.5us.
With the patch, it's more like 530ns, but the total planner run time
seems barely different.  So I find that totally acceptable, especially
if it helps us find join removals we missed before.

This seems straightforward enough that maybe we could put it into
v16/v17 after all, although I'm still leaning towards not doing so.

To validate the patch, verify that add_vars_to_targetlist is
presently the only function that adds bits to attr_needed or
ph_needed.  Then check that for every caller of that function,
I've added parallel code to re-insert those bits (except for
callers that set the "relation 0" bit, which we handle by not
removing that bit in the first place).

Comments?

			regards, tom lane

Commits

  1. Recalculate where-needed data accurately after a join removal.