Currently, we have an optimization that reduces an IS [NOT] NULL qual on a NOT NULL column to constant true or constant false, provided we can prove that the input expression of the NullTest is not nullable by any outer joins. This deduction happens pretty late in planner, during the distribution of quals to relations in query_planner(). As mentioned in [1], doing it at such a late stage has some drawbacks.
Ideally, this deduction should happen during constant folding. However, we don't have the per-relation information about which columns are defined as NOT NULL available at that point. That information is collected from catalogs when building RelOptInfos for base or other relations. I'm wondering whether we can collect that information while building the RangeTblEntry for a base or other relation, so that it's available before constant folding. This could also enable other optimizations, such as checking if a NOT IN subquery's output columns and its left-hand expressions are all certainly not NULL, in which case we can convert it to an anti-join. Attached is a draft patch to reduce NullTest on a NOT NULL column in eval_const_expressions. Initially, I planned to get rid of restriction_is_always_true and restriction_is_always_false altogether, since we now perform the reduction of "Var IS [NOT] NULL" quals in eval_const_expressions. However, removing them would prevent us from reducing some IS [NOT] NULL quals that we were previously able to reduce, because (a) the self-join elimination may introduce new IS NOT NULL quals after the constant folding, and (b) if some outer joins are converted to inner joins, previously irreducible NullTest quals may become reducible. So I think maybe we'd better keep restriction_is_always_true and restriction_is_always_false as-is. Any thoughts? [1] https://postgr.es/m/2323997.1740623...@sss.pgh.pa.us Thanks Richard
v1-0001-Reduce-Var-IS-NOT-NULL-quals-during-constant-folding.patch
Description: Binary data