On Tue, Mar 21, 2023 at 12:21 AM Tom Lane <tgl@sss.pgh.pa.us> wrote:
So the idea that I had was to, once we detect that X commutes with Y, immediately call a function that recurses through the relevant parts of root->parse and performs the required nullingrels updates.
So IIUC the idea is that if we are given the first form of identity 3, we update all upper C Vars so that they are marked with both OJ relids. It seems that this may have nullingrels mis-match issue because of how we form outer join's target list.
I do have a try coding along this idea to update all upper C Vars being marked with both OJ relids if the two OJs commute according to identity 3. And then I realize there are several other adjustments needed to make it work.
* As I imagined before, we need to revise how we form outer join's target list to avoid nullingrels mismatch. Currently the outer join's target list is built in a way that the output Vars have the same nulling bitmaps that they would if the two joins had been done in syntactic order. And now we need to change that to always marking the output C Vars with both joins.
* We need to revise how we check if identity 3 applies and if so how we adjust min_lefthand in make_outerjoininfo. Consider
A leftjoin B on (Pab) leftjoin C on (Pbc) leftjoin D on (Pcd)
So now the C Vars in Pcd are marked with A/B join and B/C join since the two joins can commute. When it comes to check if C/D join can commute with B/C join, the A/B join from C Vars' nullingrels would make us think that C/D join cannot commute with B/C join, which is not correct. Besides, C/D join's min_lefthand including A/B join is also problematic.
* We need to adjust how we generate multiple versions for LEFT JOIN quals in deconstruct_distribute_oj_quals, to cope with any new added nulling rel. But I haven't figured out this point clearly yet.
So it seems there is some work involved. I begin to wonder if this is the way we want.