Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
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

+9-37
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

+27
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

+19
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)