Robert Haas <robertmh...@gmail.com> writes: > On Fri, Dec 20, 2019 at 11:13 AM Tom Lane <t...@sss.pgh.pa.us> wrote: >> The alternatives that seem plausible at this point are >> ... >> (2) Explicitly mark Vars as being nullable by some outer join. I think >> we could probably get this down to one additional integer field in >> struct Var, so it wouldn't be too much of a penalty.
> It might be useful 'Relids' with each Var rather than just 'bool'. In > other words, based on where the reference to the Var is in the > original query text, figure out the set of joins where (1) the Var is > syntactically above the join and (2) on the nullable side, and then > put the relations on the other sides of those joins into the Relids. > Then if you later determine that A LEFT JOIN B actually can't make > anything go to null, you can just ignore the presence of A in this set > for the rest of planning. I feel like this kind of idea might have > other applications too, although I admit that it also has a cost. Yeah, a bitmapset might be a better idea than just recording the topmost relevant join's relid. But it's also more expensive, and I think we ought to keep the representation of Vars as cheap as possible. (On the third hand, an empty BMS is cheap, while if the alternative to a non-empty BMS is to put a separate wrapper node around the Var, that's hardly better.) The key advantage of a BMS, really, is that it dodges the issue of needing to re-mark Vars when you re-order two outer joins using the outer join identities. You really don't want that to result in having to consider Vars above the two joins to be different depending on the order you chose for the OJs, because that'd enormously complicate considering both sorts of Paths at the same time. The rough idea I'd had about coping with that issue with just a single relid is that maybe it doesn't matter --- maybe we can always mark Vars according to the *syntactically* highest nulling OJ, regardless of the actual join order. But I'm not totally sure that can work. In any case, what the planner likes to work with is sets of baserel relids covered by a join, not the relid(s) of the join RTEs themselves. So maybe there's going to be a conversion step required anyhow. regards, tom lane