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