Fix computation of varnullingrels when translating appendrel Var When adjust_appendrel_attrs translates a Var referencing a parent relation into a Var referencing a child relation, it propagates varnullingrels from the parent Var to the translated Var. Previously, the code simply overwrote the translated Var's varnullingrels with those of the parent.
This was incorrect because the translated Var might already possess nonempty varnullingrels. This happens, for example, when a LATERAL subquery within a UNION ALL references a Var from the nullable side of an outer join. In such cases, the translated Var correctly carries the outer join's relid in its varnullingrels. Overwriting these bits with the parent Var's set caused the planner to lose track of the fact that the Var could be nulled by that outer join. In the reported case, because the underlying column had a NOT NULL constraint, the planner incorrectly deduced that the Var could never be NULL and discarded essential IS NOT NULL filters. This led to incorrect query results where NULL rows were returned instead of being filtered out. To fix, use bms_add_members to merge the parent Var's varnullingrels into the translated Var's existing set, preserving both sources of nullability. Back-patch to v16. Although the reported case does not seem to cause problems in v16, leaving incorrect varnullingrels in the tree seems like a trap for the unwary. Bug: #19412 Reported-by: Sergey Shinderuk <[email protected]> Author: Richard Guo <[email protected]> Reviewed-by: Tom Lane <[email protected]> Discussion: https://postgr.es/m/[email protected] Backpatch-through: 16 Branch ------ REL_16_STABLE Details ------- https://git.postgresql.org/pg/commitdiff/ec20a45528bf1731bd532edd51cb68e5f341ac8f Modified Files -------------- src/backend/optimizer/util/appendinfo.c | 12 ++++++-- src/test/regress/expected/join.out | 52 +++++++++++++++++++++++++++++++++ src/test/regress/sql/join.sql | 24 +++++++++++++++ 3 files changed, 85 insertions(+), 3 deletions(-)
