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-04T09:14:32Z
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
On Mon, Aug 4, 2025 at 1:29 PM David Rowley <dgrowleyml@gmail.com> wrote: > I guess it doesn't because in RelationGetIndexPredicate(), the call to > eval_const_expressions() passes NULL for the PlannerInfo, resulting in > the NOT NULL information not being available during > eval_const_expressions(). Exactly. The comment of eval_const_expressions also notes that when "root" is NULL, NullTest quals will not be reduced. * NOTE: "root" can be passed as NULL if the caller never wants to do any * Param substitutions nor receive info about inlined functions nor reduce * NullTest for Vars to constant true or constant false. > Looks like we keep the indpred varnos as 1 during > RelationGetIndexPredicate() and only change them to the actual varno > of the relation after that call inside get_relation_info(), so it > wouldn't be valid to pass the PlannerInfo down without first rewriting > the varnos and it doesn't seem correct to rewrite the varnos in the > relcache code. Yeah. And in addition, the fact that we cache the pg_index.indpred in the relcache entry means that we cannot rewrite the varnos within RelationGetIndexPredicate(). > Seems like what it would take to make this work is *another* call to > eval_const_expressions() inside get_relation_info() just after the > varnos have been changed. I wonder if we could move const-simplification and canonicalization of index predicates out of RelationGetIndexPredicate() and into its callers, after the varnos have been updated. That would require changing every caller, though. BTW, I wonder if we should also be concerned about index expressions, in cases like: create table t (a int, b int not null); create index on t ((b is not null)); explain select * from t where b is not null; Thanks Richard