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 →
  1. Fix const-simplification for index expressions and predicate

  2. Fix const-simplification for constraints and stats

Attachments

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