Re: BUG #19007: Planner fails to choose partial index with spurious 'not null'

From: Richard Guo <guofenglinux(at)gmail(dot)com>
To: David Rowley <dgrowleyml(at)gmail(dot)com>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, bryfox(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org
Subject: Re: BUG #19007: Planner fails to choose partial index with spurious 'not null'
Date: 2025-08-20 09:37:14
Message-ID: CAMbWs4-Vg+S1=b1TYQ2dWK3H=ZFiPjzSNh1YLdVDxsz=0RiE9g@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

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

Attachment Content-Type Size
v1-0001-Fix-const-simplification-of-expressions-loaded-fr.patch application/octet-stream 5.5 KB

In response to

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Hayato Kuroda (Fujitsu) 2025-08-20 09:58:59 RE: Lock timeouts and unusual spikes in replication lag with logical parallel transaction streaming
Previous Message Zhu Yang 2025-08-20 06:16:53 The memory usage is positively correlated with the number of partition tables when pg_get_expr is called.