I'm totally fine with setting the target to PG13.
--
I'm interested to know how this works without testing for inner
nullability. If any of the inner side's join exprs are NULL then no
records can match. What do you propose to work around that?
--
We still check for inner side's nullability, when it is nullable we
append a "var is NULL" to the anti join condition. So every outer
tuple is going to evaluate to true on the join condition when there
is indeed a null entry in the inner.
Actually I think the nested loop anti join can end early in this case,
but I haven't find a way to do it properly, this may be one other reason
why we need a new join type for NOT IN.
e.g.
explain select count(*) from s where u not in (select n from l);
QUERY PLAN
------------------------------------------------------------------------------------
Aggregate (cost=2892.88..2892.89 rows=1 width=8)
-> Nested Loop Anti Join (cost=258.87..2892.88 rows=1 width=0)
-> Seq Scan on s (cost=0.00..1.11 rows=11 width=4)
-> Bitmap Heap Scan on l (cost=258.87..262.88 rows=1 width=4)
Recheck Cond: ((s.u = n) OR (n IS NULL))
-> BitmapOr (cost=258.87..258.87 rows=1 width=0)
-> Bitmap Index Scan on l_n (cost=0.00..4.43 rows=1 width=0)
Index Cond: (s.u = n)
-> Bitmap Index Scan on l_n (cost=0.00..4.43 rows=1 width=0)
Index Cond: (n IS NULL)
Zheng