Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5a41287

Browse files
david-rowleypull[bot]
authored andcommitted
Support partition pruning on boolcol IS [NOT] UNKNOWN
While working on4c2369a, I noticed we went out of our way not tosupport clauses on boolean partitioned tables in the form of "ISUNKNOWN" and "IS NOT UNKNOWN". It's almost as much code to disallowthis as it is to allow it, so let's allow it.Discussion:https://postgr.es/m/CAApHDvobKtcN6+xOuOfcutfp6T7jP=JPA9y3=MAEqnuKdDsQrw@mail.gmail.com
1 parentdfd3d5c commit5a41287

File tree

3 files changed

+93
-41
lines changed

3 files changed

+93
-41
lines changed

‎src/backend/partitioning/partprune.c

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ static PartClauseMatchStatus match_boolean_partition_clause(Oid partopfamily,
200200
Expr*clause,
201201
Expr*partkey,
202202
Expr**outconst,
203-
bool*noteq);
203+
bool*notclause);
204204
staticvoidpartkey_datum_from_expr(PartitionPruneContext*context,
205205
Expr*expr,intstateidx,
206206
Datum*value,bool*isnull);
@@ -1798,13 +1798,14 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
17981798
Oidpartopfamily=part_scheme->partopfamily[partkeyidx],
17991799
partcoll=part_scheme->partcollation[partkeyidx];
18001800
Expr*expr;
1801-
boolnoteq;
1801+
boolnotclause;
18021802

18031803
/*
18041804
* Recognize specially shaped clauses that match a Boolean partition key.
18051805
*/
18061806
boolmatchstatus=match_boolean_partition_clause(partopfamily,clause,
1807-
partkey,&expr,&noteq);
1807+
partkey,&expr,
1808+
&notclause);
18081809

18091810
if (boolmatchstatus==PARTCLAUSE_MATCH_CLAUSE)
18101811
{
@@ -1818,7 +1819,7 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
18181819
* punt it off to gen_partprune_steps_internal() to generate pruning
18191820
* steps.
18201821
*/
1821-
if (noteq)
1822+
if (notclause)
18221823
{
18231824
List*new_clauses;
18241825
List*or_clause;
@@ -1836,9 +1837,8 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
18361837
else
18371838
{
18381839
/*
1839-
* We only expect match_boolean_partition_clause to match for
1840-
* IS_NOT_TRUE and IS_NOT_FALSE. IS_NOT_UNKNOWN is not
1841-
* supported.
1840+
* We only expect match_boolean_partition_clause to return
1841+
* PARTCLAUSE_MATCH_CLAUSE for IS_NOT_TRUE and IS_NOT_FALSE.
18421842
*/
18431843
Assert(false);
18441844
}
@@ -1876,6 +1876,15 @@ match_clause_to_partition_key(GeneratePruningStepsContext *context,
18761876

18771877
returnPARTCLAUSE_MATCH_CLAUSE;
18781878
}
1879+
elseif (boolmatchstatus==PARTCLAUSE_MATCH_NULLNESS)
1880+
{
1881+
/*
1882+
* Handle IS UNKNOWN and IS NOT UNKNOWN. These just logically
1883+
* translate to IS NULL and IS NOT NULL.
1884+
*/
1885+
*clause_is_not_null=notclause;
1886+
returnPARTCLAUSE_MATCH_NULLNESS;
1887+
}
18791888
elseif (IsA(clause,OpExpr)&&
18801889
list_length(((OpExpr*)clause)->args)==2)
18811890
{
@@ -3652,22 +3661,23 @@ perform_pruning_combine_step(PartitionPruneContext *context,
36523661
* match_boolean_partition_clause
36533662
*
36543663
* If we're able to match the clause to the partition key as specially-shaped
3655-
* boolean clause, set *outconst to a Const containing a true or false value,
3656-
* set *noteq according to if the clause was in the "not" form, i.e. "is not
3657-
* true" or "is not false", and return PARTCLAUSE_MATCH_CLAUSE. Returns
3658-
* PARTCLAUSE_UNSUPPORTED if the clause is not a boolean clause or if the
3659-
* boolean clause is unsuitable for partition pruning. Returns
3660-
* PARTCLAUSE_NOMATCH if it's a bool quals but just does not match this
3661-
* partition key. *outconst is set to NULL in the latter two cases.
3664+
* boolean clause, set *outconst to a Const containing a true, false or NULL
3665+
* value, set *notclause according to if the clause was in the "not" form,
3666+
* i.e. "IS NOT TRUE", "IS NOT FALSE" or "IS NOT UNKNOWN" and return
3667+
* PARTCLAUSE_MATCH_CLAUSE for "IS [NOT] (TRUE|FALSE)" clauses and
3668+
* PARTCLAUSE_MATCH_NULLNESS for "IS [NOT] UNKNOWN" clauses. Otherwise,
3669+
* return PARTCLAUSE_UNSUPPORTED if the clause cannot be used for partition
3670+
* pruning, and PARTCLAUSE_NOMATCH for supported clauses that do not match this
3671+
* 'partkey'.
36623672
*/
36633673
staticPartClauseMatchStatus
36643674
match_boolean_partition_clause(Oidpartopfamily,Expr*clause,Expr*partkey,
3665-
Expr**outconst,bool*noteq)
3675+
Expr**outconst,bool*notclause)
36663676
{
36673677
Expr*leftop;
36683678

36693679
*outconst=NULL;
3670-
*noteq= false;
3680+
*notclause= false;
36713681

36723682
/*
36733683
* Partitioning currently can only use built-in AMs, so checking for
@@ -3680,11 +3690,6 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
36803690
{
36813691
BooleanTest*btest= (BooleanTest*)clause;
36823692

3683-
/* Only IS [NOT] TRUE/FALSE are any good to us */
3684-
if (btest->booltesttype==IS_UNKNOWN||
3685-
btest->booltesttype==IS_NOT_UNKNOWN)
3686-
returnPARTCLAUSE_UNSUPPORTED;
3687-
36883693
leftop=btest->arg;
36893694
if (IsA(leftop,RelabelType))
36903695
leftop= ((RelabelType*)leftop)->arg;
@@ -3694,23 +3699,28 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
36943699
switch (btest->booltesttype)
36953700
{
36963701
caseIS_NOT_TRUE:
3697-
*noteq= true;
3702+
*notclause= true;
36983703
/* fall through */
36993704
caseIS_TRUE:
37003705
*outconst= (Expr*)makeBoolConst(true, false);
3701-
break;
3706+
returnPARTCLAUSE_MATCH_CLAUSE;
37023707
caseIS_NOT_FALSE:
3703-
*noteq= true;
3708+
*notclause= true;
37043709
/* fall through */
37053710
caseIS_FALSE:
37063711
*outconst= (Expr*)makeBoolConst(false, false);
3707-
break;
3712+
returnPARTCLAUSE_MATCH_CLAUSE;
3713+
caseIS_NOT_UNKNOWN:
3714+
*notclause= true;
3715+
/* fall through */
3716+
caseIS_UNKNOWN:
3717+
returnPARTCLAUSE_MATCH_NULLNESS;
37083718
default:
37093719
returnPARTCLAUSE_UNSUPPORTED;
37103720
}
37113721
}
3712-
if (*outconst)
3713-
returnPARTCLAUSE_MATCH_CLAUSE;
3722+
/* does not match partition key */
3723+
returnPARTCLAUSE_NOMATCH;
37143724
}
37153725
else
37163726
{
@@ -3726,12 +3736,11 @@ match_boolean_partition_clause(Oid partopfamily, Expr *clause, Expr *partkey,
37263736
*outconst= (Expr*)makeBoolConst(!is_not_clause, false);
37273737
elseif (equal(negate_clause((Node*)leftop),partkey))
37283738
*outconst= (Expr*)makeBoolConst(is_not_clause, false);
3739+
else
3740+
returnPARTCLAUSE_NOMATCH;
37293741

3730-
if (*outconst)
3731-
returnPARTCLAUSE_MATCH_CLAUSE;
3742+
returnPARTCLAUSE_MATCH_CLAUSE;
37323743
}
3733-
3734-
returnPARTCLAUSE_NOMATCH;
37353744
}
37363745

37373746
/*

‎src/test/regress/expected/partition_prune.out

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,16 +1093,11 @@ explain (costs off) select * from boolpart where a is not true and a is not fals
10931093
(2 rows)
10941094

10951095
explain (costs off) select * from boolpart where a is unknown;
1096-
QUERY PLAN
1097-
-----------------------------------------------
1098-
Append
1099-
-> Seq Scan on boolpart_f boolpart_1
1100-
Filter: (a IS UNKNOWN)
1101-
-> Seq Scan on boolpart_t boolpart_2
1102-
Filter: (a IS UNKNOWN)
1103-
-> Seq Scan on boolpart_default boolpart_3
1104-
Filter: (a IS UNKNOWN)
1105-
(7 rows)
1096+
QUERY PLAN
1097+
---------------------------------------
1098+
Seq Scan on boolpart_default boolpart
1099+
Filter: (a IS UNKNOWN)
1100+
(2 rows)
11061101

11071102
explain (costs off) select * from boolpart where a is not unknown;
11081103
QUERY PLAN
@@ -1200,6 +1195,18 @@ explain (costs off) select * from boolpart where a is not false;
12001195
Filter: (a IS NOT FALSE)
12011196
(5 rows)
12021197

1198+
explain (costs off) select * from boolpart where a is not unknown;
1199+
QUERY PLAN
1200+
-----------------------------------------------
1201+
Append
1202+
-> Seq Scan on boolpart_f boolpart_1
1203+
Filter: (a IS NOT UNKNOWN)
1204+
-> Seq Scan on boolpart_t boolpart_2
1205+
Filter: (a IS NOT UNKNOWN)
1206+
-> Seq Scan on boolpart_default boolpart_3
1207+
Filter: (a IS NOT UNKNOWN)
1208+
(7 rows)
1209+
12031210
select * from boolpart where a is not true;
12041211
a
12051212
---
@@ -1220,6 +1227,35 @@ select * from boolpart where a is not false;
12201227

12211228
(2 rows)
12221229

1230+
select * from boolpart where a is not unknown;
1231+
a
1232+
---
1233+
f
1234+
t
1235+
(2 rows)
1236+
1237+
-- check that all partitions are pruned when faced with conflicting clauses
1238+
explain (costs off) select * from boolpart where a is not unknown and a is unknown;
1239+
QUERY PLAN
1240+
--------------------------
1241+
Result
1242+
One-Time Filter: false
1243+
(2 rows)
1244+
1245+
explain (costs off) select * from boolpart where a is false and a is unknown;
1246+
QUERY PLAN
1247+
--------------------------
1248+
Result
1249+
One-Time Filter: false
1250+
(2 rows)
1251+
1252+
explain (costs off) select * from boolpart where a is true and a is unknown;
1253+
QUERY PLAN
1254+
--------------------------
1255+
Result
1256+
One-Time Filter: false
1257+
(2 rows)
1258+
12231259
-- inverse boolean partitioning - a seemingly unlikely design, but we've got
12241260
-- code for it, so we'd better test it.
12251261
create table iboolpart (a bool) partition by list ((not a));

‎src/test/regress/sql/partition_prune.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,17 @@ insert into boolpart values(null);
186186
explain (costs off)select*from boolpartwhere a is not true;
187187
explain (costs off)select*from boolpartwhere a is not trueand a is not false;
188188
explain (costs off)select*from boolpartwhere a is not false;
189+
explain (costs off)select*from boolpartwhere a is not unknown;
189190

190191
select*from boolpartwhere a is not true;
191192
select*from boolpartwhere a is not trueand a is not false;
192193
select*from boolpartwhere a is not false;
194+
select*from boolpartwhere a is not unknown;
195+
196+
-- check that all partitions are pruned when faced with conflicting clauses
197+
explain (costs off)select*from boolpartwhere a is not unknownand a is unknown;
198+
explain (costs off)select*from boolpartwhere a is falseand a is unknown;
199+
explain (costs off)select*from boolpartwhere a is trueand a is unknown;
193200

194201
-- inverse boolean partitioning - a seemingly unlikely design, but we've got
195202
-- code for it, so we'd better test it.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp