On Mon, Oct 12, 2026 at 10:18 AM Richard Guo <[email protected]> wrote: > It seems to me that we should check required_relids instead here. > > - if (!bms_overlap(rinfo->clause_relids, rel->nulling_relids)) > + if (!bms_overlap(rinfo->required_relids, rel->nulling_relids)) > > Or, maybe an alternative is to skip quals whose clause_relids overlap > the rel's lateral_referencers, as join_clause_is_movable_to() does, > but checking required_relids seems simpler to me.
After a million times of back and forth, I've decided to go with the lateral_referencers fix, as it is easier to prove correct. Any reference to the parent rel hidden inside a PHV evaluated elsewhere is a lateral reference, so such quals always have one of the parent rel's lateral referencers in their clause_relids. Skipping them is harmless. Enforcing one at a scan of the parent rel would require parameterizing the scan by a rel that itself depends on the parent rel, which is circular. The required_relids check turned out to be insufficient. make_outerjoininfo() can't see PHV-hidden references either, so required_relids may lack the nulling outer join. (And I think this is another latent bug that we need to fix too.) I've pushed the fix and back-patched it to v16. - Richard
