On Mon, 19 Feb 2024 at 05:25, Tom Lane <tgl@sss.pgh.pa.us> wrote: > > David Rowley <dgrowleyml@gmail.com> writes: > > We can do the same for BooleanTests. Given a clause such as: "partkey > > IS NOT false", we can just generate the clause "partkey IS true OR > > partkey IS NULL" and recursively generate steps for that. > > +1 ... sounds clean and clearly correct.
Here's a more complete patch for this. I included some tests for LIST and RANGE partitioned tables. I did manual testing for HASH, and was on the fence about covering that too.
I did try the following using the table from the tests:
select * from boolrangep where a is not true and not b and c = 25 and a is not null;
When will be effectively transformed into:
select * from boolrangep where (a is false or a is null) and not b and c = 25 and a is not null;
It seems that's unable to prune the NULL partition but that mostly seems to be due to a limitation of the current design. I'm not sure it's worth going to any additional trouble to make that work. It seems a bit unlikely, especially so given how long the BooleanTest pruning stuff was broken for before anyone noticed.
> > I'm tempted to go a bit further in master only and add support for > > bool IS NOT UNKNOWN and bool IS UNKNOWN using the same method. > > These are the same as IS NOT NULL and IS NULL, so I don't see the > need for an OR?
Uh, yeah. True. That makes it even more simple. Just use PARTCLAUSE_MATCH_NULLNESS.
David
After git apply fix_partprune_BooleanTests.patch on master, I got below warnings:
partprune.c: In function ‘match_clause_to_partition_key’: ../../../src/include/nodes/nodes.h:221:25: warning: initialization of ‘BooleanTest *’ {aka ‘struct BooleanTest *’} from incompatible pointer type ‘Expr *’ {aka ‘struct Expr *’} [-Wincompatible-pointer-types] 221 | #define copyObject(obj) ((typeof(obj)) copyObjectImpl(obj)) | ^ partprune.c:1824:32: note: in expansion of macro ‘copyObject’ 1824 | BooleanTest *new_booltest = copyObject(clause);