Re: BUG #19007: Planner fails to choose partial index with spurious 'not null'
Richard Guo <guofenglinux@gmail.com>
From: Richard Guo <guofenglinux@gmail.com>
To: David Rowley <dgrowleyml@gmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>, bryfox@gmail.com,
pgsql-bugs@lists.postgresql.org
Date: 2025-08-20T09:37:14Z
Lists: pgsql-bugs
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix const-simplification for index expressions and predicate
- c925ad30b047 19 (unreleased) landed
-
Fix const-simplification for constraints and stats
- 317c117d6d23 19 (unreleased) landed
Attachments
- v1-0001-Fix-const-simplification-of-expressions-loaded-fr.patch (application/octet-stream) patch v1-0001
I've had some time to look at this issue again. There are several cases in plancat.c where specific expressions need to be run through eval_const_expressions because the planner will be comparing them to similarly-processed qual clauses. This includes constraint expressions, statistics expressions, index expressions and index predicates -- as highlighted by this bug report. For a constraint expression, we run it through eval_const_expressions before fixing its Vars to have the correct varno. This is problematic because eval_const_expressions reduces NullTest quals based on varno, so we must ensure the Vars have the correct varnos before calling it. I think we can fix it by reordering the calls to eval_const_expressions and ChangeVarNodes in get_relation_constraints(). For statistics expressions, we have the same issue as with constraint expressions, plus we don't pass a valid root to eval_const_expressions. I think we can fix this by adding "root" as a new parameter to get_relation_statistics() and passing it to eval_const_expressions. For index expressions and index predicates, however, the situation is more complex, because we cache the constant-simplified expressions in the relcache entry. This means we can't fix the Vars before applying eval_const_expressions to them. One possible solution is to run eval_const_expressions twice: first with "root" set to NULL, before fixing the Vars, and then again with a valid "root" after the Vars have been fixed. Please see the attached draft patch. (This is basically what David's proposed patch does. However, I don't think we should limit ourselves to the case where info->indpred contains only a single reducible NullTest qual, since there may be more than one.) However, running eval_const_expressions twice for index expressions and index predicates looks ugly, and one could argue that it might have a performance impact. BTW, all of these solutions are only possible after e2debb643, which is only in master. In v17 and v18, we don't have a way to reduce NullTest quals for these expressions, since that reduction doesn't occur during const-simplification. I don't know what we should do for v17 and v18. Thoughts? Thanks Richard