Skip to content

Commit 51948c4

Browse files
committed
Fix bogus logic for combining range-partitioned columns during pruning.
gen_prune_steps_from_opexps's notion of how to do this was overly complicated and underly correct. Per discussion of a report from Alan Jackson (though this fixes only one aspect of that problem). Back-patch to v11 where this code came in. Amit Langote Discussion: https://postgr.es/m/FAD28A83-AC73-489E-A058-2681FA31D648@tvsquared.com
1 parent 10c5cc4 commit 51948c4

File tree

3 files changed

+55
-37
lines changed

3 files changed

+55
-37
lines changed

src/backend/partitioning/partprune.c

Lines changed: 9 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,9 +1185,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
11851185
List *opsteps = NIL;
11861186
List *btree_clauses[BTMaxStrategyNumber + 1],
11871187
*hash_clauses[HTMaxStrategyNumber + 1];
1188-
bool need_next_less,
1189-
need_next_eq,
1190-
need_next_greater;
11911188
int i;
11921189

11931190
memset(btree_clauses, 0, sizeof(btree_clauses));
@@ -1198,9 +1195,8 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
11981195
bool consider_next_key = true;
11991196

12001197
/*
1201-
* To be useful for pruning, we must have clauses for a prefix of
1202-
* partition keys in the case of range partitioning. So, ignore
1203-
* clauses for keys after this one.
1198+
* For range partitioning, if we have no clauses for the current key,
1199+
* we can't consider any later keys either, so we can stop here.
12041200
*/
12051201
if (part_scheme->strategy == PARTITION_STRATEGY_RANGE &&
12061202
clauselist == NIL)
@@ -1215,7 +1211,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12151211
clauselist == NIL && !bms_is_member(i, nullkeys))
12161212
return NULL;
12171213

1218-
need_next_eq = need_next_less = need_next_greater = true;
12191214
foreach(lc, clauselist)
12201215
{
12211216
PartClauseInfo *pc = (PartClauseInfo *) lfirst(lc);
@@ -1237,7 +1232,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12371232
case PARTITION_STRATEGY_RANGE:
12381233
{
12391234
PartClauseInfo *last = NULL;
1240-
bool inclusive = false;
12411235

12421236
/*
12431237
* Add this clause to the list of clauses to be used
@@ -1255,35 +1249,13 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12551249
lappend(btree_clauses[pc->op_strategy], pc);
12561250

12571251
/*
1258-
* We may not need the next clause if they're of
1259-
* certain strategy.
1252+
* We can't consider subsequent partition keys if the
1253+
* clause for the current key contains a non-inclusive
1254+
* operator.
12601255
*/
1261-
switch (pc->op_strategy)
1262-
{
1263-
case BTLessEqualStrategyNumber:
1264-
inclusive = true;
1265-
/* fall through */
1266-
case BTLessStrategyNumber:
1267-
if (!inclusive)
1268-
need_next_eq = need_next_less = false;
1269-
break;
1270-
case BTEqualStrategyNumber:
1271-
/* always accept clauses for the next key. */
1272-
break;
1273-
case BTGreaterEqualStrategyNumber:
1274-
inclusive = true;
1275-
/* fall through */
1276-
case BTGreaterStrategyNumber:
1277-
if (!inclusive)
1278-
need_next_eq = need_next_greater = false;
1279-
break;
1280-
}
1281-
1282-
/* We may want to change our mind. */
1283-
if (consider_next_key)
1284-
consider_next_key = (need_next_eq ||
1285-
need_next_less ||
1286-
need_next_greater);
1256+
if (pc->op_strategy == BTLessStrategyNumber ||
1257+
pc->op_strategy == BTGreaterStrategyNumber)
1258+
consider_next_key = false;
12871259
break;
12881260
}
12891261

@@ -2822,7 +2794,7 @@ get_matching_range_bounds(PartitionPruneContext *context,
28222794

28232795
/*
28242796
* Look for the greatest bound that is < or <= lookup value and
2825-
* set minoff to its offset.
2797+
* set maxoff to its offset.
28262798
*/
28272799
off = partition_range_datum_bsearch(partsupfunc,
28282800
partcollation,

src/test/regress/expected/partition_prune.out

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3059,6 +3059,33 @@ select * from stable_qual_pruning
30593059
(4 rows)
30603060

30613061
drop table stable_qual_pruning;
3062+
--
3063+
-- Check that pruning with composite range partitioning works correctly when
3064+
-- it must ignore clauses for trailing keys once it has seen a clause with
3065+
-- non-inclusive operator for an earlier key
3066+
--
3067+
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
3068+
create table mc3p0 partition of mc3p
3069+
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
3070+
create table mc3p1 partition of mc3p
3071+
for values from (1, 1, 1) to (2, minvalue, minvalue);
3072+
create table mc3p2 partition of mc3p
3073+
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
3074+
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
3075+
explain (analyze, costs off, summary off, timing off)
3076+
select * from mc3p where a < 3 and abs(b) = 1;
3077+
QUERY PLAN
3078+
-------------------------------------------------
3079+
Append (actual rows=3 loops=1)
3080+
-> Seq Scan on mc3p0 (actual rows=1 loops=1)
3081+
Filter: ((a < 3) AND (abs(b) = 1))
3082+
-> Seq Scan on mc3p1 (actual rows=1 loops=1)
3083+
Filter: ((a < 3) AND (abs(b) = 1))
3084+
-> Seq Scan on mc3p2 (actual rows=1 loops=1)
3085+
Filter: ((a < 3) AND (abs(b) = 1))
3086+
(7 rows)
3087+
3088+
drop table mc3p;
30623089
-- Ensure runtime pruning works with initplans params with boolean types
30633090
create table boolvalues (value bool not null);
30643091
insert into boolvalues values('t'),('f');

src/test/regress/sql/partition_prune.sql

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,25 @@ select * from stable_qual_pruning
757757

758758
drop table stable_qual_pruning;
759759

760+
--
761+
-- Check that pruning with composite range partitioning works correctly when
762+
-- it must ignore clauses for trailing keys once it has seen a clause with
763+
-- non-inclusive operator for an earlier key
764+
--
765+
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
766+
create table mc3p0 partition of mc3p
767+
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
768+
create table mc3p1 partition of mc3p
769+
for values from (1, 1, 1) to (2, minvalue, minvalue);
770+
create table mc3p2 partition of mc3p
771+
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
772+
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
773+
774+
explain (analyze, costs off, summary off, timing off)
775+
select * from mc3p where a < 3 and abs(b) = 1;
776+
777+
drop table mc3p;
778+
760779
-- Ensure runtime pruning works with initplans params with boolean types
761780
create table boolvalues (value bool not null);
762781
insert into boolvalues values('t'),('f');

0 commit comments

Comments
 (0)