Skip to content

Commit 3922f10

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 4b1fcb4 commit 3922f10

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
@@ -1209,9 +1209,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12091209
List *opsteps = NIL;
12101210
List *btree_clauses[BTMaxStrategyNumber + 1],
12111211
*hash_clauses[HTMaxStrategyNumber + 1];
1212-
bool need_next_less,
1213-
need_next_eq,
1214-
need_next_greater;
12151212
int i;
12161213

12171214
memset(btree_clauses, 0, sizeof(btree_clauses));
@@ -1222,9 +1219,8 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12221219
bool consider_next_key = true;
12231220

12241221
/*
1225-
* To be useful for pruning, we must have clauses for a prefix of
1226-
* partition keys in the case of range partitioning. So, ignore
1227-
* clauses for keys after this one.
1222+
* For range partitioning, if we have no clauses for the current key,
1223+
* we can't consider any later keys either, so we can stop here.
12281224
*/
12291225
if (part_scheme->strategy == PARTITION_STRATEGY_RANGE &&
12301226
clauselist == NIL)
@@ -1239,7 +1235,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12391235
clauselist == NIL && !bms_is_member(i, nullkeys))
12401236
return NULL;
12411237

1242-
need_next_eq = need_next_less = need_next_greater = true;
12431238
foreach(lc, clauselist)
12441239
{
12451240
PartClauseInfo *pc = (PartClauseInfo *) lfirst(lc);
@@ -1261,7 +1256,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12611256
case PARTITION_STRATEGY_RANGE:
12621257
{
12631258
PartClauseInfo *last = NULL;
1264-
bool inclusive = false;
12651259

12661260
/*
12671261
* Add this clause to the list of clauses to be used
@@ -1279,35 +1273,13 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
12791273
lappend(btree_clauses[pc->op_strategy], pc);
12801274

12811275
/*
1282-
* We may not need the next clause if they're of
1283-
* certain strategy.
1276+
* We can't consider subsequent partition keys if the
1277+
* clause for the current key contains a non-inclusive
1278+
* operator.
12841279
*/
1285-
switch (pc->op_strategy)
1286-
{
1287-
case BTLessEqualStrategyNumber:
1288-
inclusive = true;
1289-
/* fall through */
1290-
case BTLessStrategyNumber:
1291-
if (!inclusive)
1292-
need_next_eq = need_next_less = false;
1293-
break;
1294-
case BTEqualStrategyNumber:
1295-
/* always accept clauses for the next key. */
1296-
break;
1297-
case BTGreaterEqualStrategyNumber:
1298-
inclusive = true;
1299-
/* fall through */
1300-
case BTGreaterStrategyNumber:
1301-
if (!inclusive)
1302-
need_next_eq = need_next_greater = false;
1303-
break;
1304-
}
1305-
1306-
/* We may want to change our mind. */
1307-
if (consider_next_key)
1308-
consider_next_key = (need_next_eq ||
1309-
need_next_less ||
1310-
need_next_greater);
1280+
if (pc->op_strategy == BTLessStrategyNumber ||
1281+
pc->op_strategy == BTGreaterStrategyNumber)
1282+
consider_next_key = false;
13111283
break;
13121284
}
13131285

@@ -2847,7 +2819,7 @@ get_matching_range_bounds(PartitionPruneContext *context,
28472819

28482820
/*
28492821
* Look for the greatest bound that is < or <= lookup value and
2850-
* set minoff to its offset.
2822+
* set maxoff to its offset.
28512823
*/
28522824
off = partition_range_datum_bsearch(partsupfunc,
28532825
partcollation,

src/test/regress/expected/partition_prune.out

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

31253125
drop table stable_qual_pruning;
3126+
--
3127+
-- Check that pruning with composite range partitioning works correctly when
3128+
-- it must ignore clauses for trailing keys once it has seen a clause with
3129+
-- non-inclusive operator for an earlier key
3130+
--
3131+
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
3132+
create table mc3p0 partition of mc3p
3133+
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
3134+
create table mc3p1 partition of mc3p
3135+
for values from (1, 1, 1) to (2, minvalue, minvalue);
3136+
create table mc3p2 partition of mc3p
3137+
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
3138+
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
3139+
explain (analyze, costs off, summary off, timing off)
3140+
select * from mc3p where a < 3 and abs(b) = 1;
3141+
QUERY PLAN
3142+
-------------------------------------------------
3143+
Append (actual rows=3 loops=1)
3144+
-> Seq Scan on mc3p0 (actual rows=1 loops=1)
3145+
Filter: ((a < 3) AND (abs(b) = 1))
3146+
-> Seq Scan on mc3p1 (actual rows=1 loops=1)
3147+
Filter: ((a < 3) AND (abs(b) = 1))
3148+
-> Seq Scan on mc3p2 (actual rows=1 loops=1)
3149+
Filter: ((a < 3) AND (abs(b) = 1))
3150+
(7 rows)
3151+
3152+
drop table mc3p;
31263153
-- Ensure runtime pruning works with initplans params with boolean types
31273154
create table boolvalues (value bool not null);
31283155
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
@@ -792,6 +792,25 @@ select * from stable_qual_pruning
792792

793793
drop table stable_qual_pruning;
794794

795+
--
796+
-- Check that pruning with composite range partitioning works correctly when
797+
-- it must ignore clauses for trailing keys once it has seen a clause with
798+
-- non-inclusive operator for an earlier key
799+
--
800+
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
801+
create table mc3p0 partition of mc3p
802+
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
803+
create table mc3p1 partition of mc3p
804+
for values from (1, 1, 1) to (2, minvalue, minvalue);
805+
create table mc3p2 partition of mc3p
806+
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
807+
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
808+
809+
explain (analyze, costs off, summary off, timing off)
810+
select * from mc3p where a < 3 and abs(b) = 1;
811+
812+
drop table mc3p;
813+
795814
-- Ensure runtime pruning works with initplans params with boolean types
796815
create table boolvalues (value bool not null);
797816
insert into boolvalues values('t'),('f');

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy