Fix skipping of join quals for appendrel children

Commit 767c59895 made set_append_rel_size() skip join quals that came
from above an outer join that can null the parent rel.  Such quals are
of no use while generating paths for the child, and skipping them also
keeps them away from adjust_appendrel_attrs(), which cannot apply
nullingrels to a non-Var translation.

However, it identified such quals by looking at their clause_relids.
That misses a reference to the parent rel that is nulled by such an
outer join but appears only within a PlaceHolderVar, because
pull_varnos() reports only where the PHV is evaluated.  Such a qual
could then reach adjust_appendrel_attrs(), which failed with "failed
to apply nullingrels to a non-Var" if the referenced output of a UNION
ALL member was not a plain Var.

To fix, also skip quals whose clause_relids overlap the parent rel's
lateral_referencers.  A reference to the parent rel within a PHV that
is evaluated elsewhere is necessarily a lateral reference, so this
catches all such quals.  These quals are no use for the child either,
since they can never be enforced by a scan of the parent rel; this is
the same reasoning join_clause_is_movable_to() uses.

Back-patch to v16, where commit 767c59895 was introduced.

Author: Richard Guo <[email protected]>
Reviewed-by: wenhui qiu <[email protected]>
Discussion: 
https://postgr.es/m/CAMbWs4_fzrrN9G6-wLwwrdM-n=fwj3uhr1zkgj3o91eec-c...@mail.gmail.com
Backpatch-through: 16

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/23e7ca78a003fb6ae5d983f3a093faaecf0778b8

Modified Files
--------------
src/backend/optimizer/path/allpaths.c | 11 ++++-
src/test/regress/expected/join.out    | 78 +++++++++++++++++++++++++++++++++++
src/test/regress/sql/join.sql         | 14 +++++++
3 files changed, 102 insertions(+), 1 deletion(-)

Reply via email to