Re: pgsql: Reduce "Var IS [NOT] NULL" quals during constant folding

From: Nikolay Samokhvalov <nik(at)postgres(dot)ai>
To: pgsql-hackers(at)lists(dot)postgresql(dot)org
Cc: Robert Haas <robertmhaas(at)gmail(dot)com>, rguo(at)postgresql(dot)org
Subject: Re: pgsql: Reduce "Var IS [NOT] NULL" quals during constant folding
Date: 2026-11-04 06:41:15
Message-ID: CAM527d8xLp2ZFaOgU9oz7Xt51VmqQeKbR=gt-K3geeS=dhH_vQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-committers pgsql-hackers

On Tue, Oct 6, 2026 at 8:53 AM Robert Haas <robertmhaas(at)gmail(dot)com> wrote:
> I feel like this commit message might have missed a fairly important
> point here, which is that this commit made it necessary, in some set
> of circumstances, for eval_const_expressions() to happen with a valid
> PlannerInfo *root and with varnos already fixed. In addition to the
> cases covered by 317c117d6d2 and c925ad30b04, there seems to be issues
> with partition keys and partition constraints: see
> set_baserel_partition_key_exprs and set_baserel_partition_constraint.
> Attached are a pair of Claude-written test case that demonstrate
> partition pruning failing as a result.
> I'm afraid this isn't going to be all the bugs. We have expression
> trees in a lot of places, and we call eval_const_expressions()
> directly or indirectly in a lot of places, and it doesn't seem easy to
> know what we might still have missed.

Here is a fix for both, done the same way as c925ad30b04. A plain int
key is enough to see it:

create table pt (a int not null, b int) partition by list (coalesce(a, b));
create table pt1 partition of pt for values in (1);
create table pt2 partition of pt for values in (2);
explain (costs off) select * from pt where coalesce(a, b) = 1;

18.3 scans only pt1. REL_19_STABLE 4b1abd678223 scans pt1 and pt2,
with Filter: (a = 1): the qual is reduced, the key is not, so they no
longer match. The CASE WHEN a IS NULL THEN b ELSE a END shape breaks
since e2debb64380 [1], the COALESCE shape since 10c4fe074a9 [2].
Run-time pruning with a generic plan and partitionwise join on such
keys are lost the same way, and come back with the patch.

The patch runs each partition key expression through
eval_const_expressions() again with the root after ChangeVarNodes(),
like c925ad30b04 does for index expressions [3]. For the partition
constraint it fixes the varnos first and then const-simplifies with
the root instead of expression_planner(), so the constraint is still
simplified only once. Your finding8.sql gives One-Time Filter: false
again, and finding6.sql scans only p1.

AI prepared the attached patch and tests; I haven't manually reviewed
the code yet. The new tests in partition_prune.sql cover the COALESCE
and CASE keys, run-time pruning with a prepared statement, and the
partition constraint case; each fails without the plancat.c change.
Tested on REL_19_STABLE 4b1abd678223 and master b6178c942ea7 (the
patch applies to both), assertions on: the regress and isolation
suites pass.

[1] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=e2debb64380ebcf0979708a0fa88d9c8d924005b
[2] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=10c4fe074a92eccf9fa6f7a39fe4d3f97b9b87e2
[3] https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c925ad30b047ec1388247539e86729d584c34b8d

Nik

Attachment Content-Type Size
v1-0001-Fix-const-simplification-of-partition-keys-and-co.patch application/x-patch 10.4 KB

In response to

Browse pgsql-committers by date

  From Date Subject
Next Message Amit Langote 2026-11-04 06:45:31 pgsql: Don't free a cached RI plan that may be in use
Previous Message David Rowley 2026-11-04 03:24:04 pgsql: Allow LIMIT pushdown in postgres_fdw with empty ORDER BY pathkey

Browse pgsql-hackers by date

  From Date Subject
Next Message Nikolay Samokhvalov 2026-11-04 06:43:58 Re: Add wait events for server logging destination writes
Previous Message Nikolay Samokhvalov 2026-11-04 06:37:52 Re: PG19 regression in ecd9288624a: JSON_ARRAY() indexes that go stale