I wrote: > Robert Haas <robertmh...@gmail.com> writes: >> I'm alarmed by your follow-on statement that the current code can't >> handle the two-levels of removable join case. Seems like it ought to >> form {B C} as a path over {B} and then {A B C} as a path over {A}.
> Actually I think it ought to form {A B} as a no-op join and then be able > to join {A B} to {C} as a no-op join. It won't recognize joining A to > {B C} as a no-op because the RHS isn't a baserel. But yeah, I was quite > surprised at the failure too. We should take the time to understand why > it's failing before we go further. OK, I traced through it, and the reason HEAD fails on this example is that it *doesn't* recognize {A B} as a feasible no-op join, for precisely the reason that it sees some B vars marked as being needed for the not-yet-done {B C} join. So that path is blocked, and the other possible path to the desired result is also blocked because it won't consider {B C} as a valid RHS for a removable join. I don't see any practical way to escape the false-attr_needed problem given the current code structure. We could maybe hack our way to a solution by weakening the restriction against the RHS being a join, eg by noting that the best path for the RHS is a no-op join and then drilling down to the one baserel. But it seems pretty ugly. So I think the conclusion is clear: we should consign the current join-removal code to the dustbin and pursue the preprocessing way instead. Will work on it today. regards, tom lane -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers