From dea1491ffb448d20764a5f2cec8ae33b64dd39f8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 1 Aug 2015 14:31:46 -0400 Subject: [PATCH] Teach predtest.c that "foo" implies "foo IS NOT NULL". Per complaint from Peter Holzer. It's useful to cover this special case, since for a boolean variable "foo", earlier parts of the planner will have reduced variants like "foo = true" to just "foo", and thus we may fail to recognize the applicability of a partial index with predicate "foo IS NOT NULL". Back-patch to 9.5, but not further; given the lack of previous complaints this doesn't seem like behavior to change in stable branches. --- src/backend/optimizer/util/predtest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/backend/optimizer/util/predtest.c b/src/backend/optimizer/util/predtest.c index d9e49d127e..7e86ca974b 100644 --- a/src/backend/optimizer/util/predtest.c +++ b/src/backend/optimizer/util/predtest.c @@ -1028,6 +1028,8 @@ arrayexpr_cleanup_fn(PredIterInfo info) * "foo" is NULL, which we can take as equivalent to FALSE because we know * we are within an AND/OR subtree of a WHERE clause. (Again, "foo" is * already known immutable, so the clause will certainly always fail.) + * Also, if the clause is just "foo" (meaning it's a boolean variable), + * the predicate is implied since the clause can't be true if "foo" is NULL. * * Finally, if both clauses are binary operator expressions, we may be able * to prove something using the system's knowledge about operators; those @@ -1061,6 +1063,8 @@ predicate_implied_by_simple_clause(Expr *predicate, Node *clause) list_member_strip(((FuncExpr *) clause)->args, nonnullarg) && func_strict(((FuncExpr *) clause)->funcid)) return true; + if (equal(clause, nonnullarg)) + return true; } return false; /* we can't succeed below... */ }