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
This commit is contained in:
parent
10c5cc4b4f
commit
51948c4e1f
@ -1185,9 +1185,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
|
||||
List *opsteps = NIL;
|
||||
List *btree_clauses[BTMaxStrategyNumber + 1],
|
||||
*hash_clauses[HTMaxStrategyNumber + 1];
|
||||
bool need_next_less,
|
||||
need_next_eq,
|
||||
need_next_greater;
|
||||
int i;
|
||||
|
||||
memset(btree_clauses, 0, sizeof(btree_clauses));
|
||||
@ -1198,9 +1195,8 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
|
||||
bool consider_next_key = true;
|
||||
|
||||
/*
|
||||
* To be useful for pruning, we must have clauses for a prefix of
|
||||
* partition keys in the case of range partitioning. So, ignore
|
||||
* clauses for keys after this one.
|
||||
* For range partitioning, if we have no clauses for the current key,
|
||||
* we can't consider any later keys either, so we can stop here.
|
||||
*/
|
||||
if (part_scheme->strategy == PARTITION_STRATEGY_RANGE &&
|
||||
clauselist == NIL)
|
||||
@ -1215,7 +1211,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
|
||||
clauselist == NIL && !bms_is_member(i, nullkeys))
|
||||
return NULL;
|
||||
|
||||
need_next_eq = need_next_less = need_next_greater = true;
|
||||
foreach(lc, clauselist)
|
||||
{
|
||||
PartClauseInfo *pc = (PartClauseInfo *) lfirst(lc);
|
||||
@ -1237,7 +1232,6 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
|
||||
case PARTITION_STRATEGY_RANGE:
|
||||
{
|
||||
PartClauseInfo *last = NULL;
|
||||
bool inclusive = false;
|
||||
|
||||
/*
|
||||
* Add this clause to the list of clauses to be used
|
||||
@ -1255,35 +1249,13 @@ gen_prune_steps_from_opexps(PartitionScheme part_scheme,
|
||||
lappend(btree_clauses[pc->op_strategy], pc);
|
||||
|
||||
/*
|
||||
* We may not need the next clause if they're of
|
||||
* certain strategy.
|
||||
* We can't consider subsequent partition keys if the
|
||||
* clause for the current key contains a non-inclusive
|
||||
* operator.
|
||||
*/
|
||||
switch (pc->op_strategy)
|
||||
{
|
||||
case BTLessEqualStrategyNumber:
|
||||
inclusive = true;
|
||||
/* fall through */
|
||||
case BTLessStrategyNumber:
|
||||
if (!inclusive)
|
||||
need_next_eq = need_next_less = false;
|
||||
break;
|
||||
case BTEqualStrategyNumber:
|
||||
/* always accept clauses for the next key. */
|
||||
break;
|
||||
case BTGreaterEqualStrategyNumber:
|
||||
inclusive = true;
|
||||
/* fall through */
|
||||
case BTGreaterStrategyNumber:
|
||||
if (!inclusive)
|
||||
need_next_eq = need_next_greater = false;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We may want to change our mind. */
|
||||
if (consider_next_key)
|
||||
consider_next_key = (need_next_eq ||
|
||||
need_next_less ||
|
||||
need_next_greater);
|
||||
if (pc->op_strategy == BTLessStrategyNumber ||
|
||||
pc->op_strategy == BTGreaterStrategyNumber)
|
||||
consider_next_key = false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -2822,7 +2794,7 @@ get_matching_range_bounds(PartitionPruneContext *context,
|
||||
|
||||
/*
|
||||
* Look for the greatest bound that is < or <= lookup value and
|
||||
* set minoff to its offset.
|
||||
* set maxoff to its offset.
|
||||
*/
|
||||
off = partition_range_datum_bsearch(partsupfunc,
|
||||
partcollation,
|
||||
|
@ -3059,6 +3059,33 @@ select * from stable_qual_pruning
|
||||
(4 rows)
|
||||
|
||||
drop table stable_qual_pruning;
|
||||
--
|
||||
-- Check that pruning with composite range partitioning works correctly when
|
||||
-- it must ignore clauses for trailing keys once it has seen a clause with
|
||||
-- non-inclusive operator for an earlier key
|
||||
--
|
||||
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
|
||||
create table mc3p0 partition of mc3p
|
||||
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
|
||||
create table mc3p1 partition of mc3p
|
||||
for values from (1, 1, 1) to (2, minvalue, minvalue);
|
||||
create table mc3p2 partition of mc3p
|
||||
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
||||
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
||||
explain (analyze, costs off, summary off, timing off)
|
||||
select * from mc3p where a < 3 and abs(b) = 1;
|
||||
QUERY PLAN
|
||||
-------------------------------------------------
|
||||
Append (actual rows=3 loops=1)
|
||||
-> Seq Scan on mc3p0 (actual rows=1 loops=1)
|
||||
Filter: ((a < 3) AND (abs(b) = 1))
|
||||
-> Seq Scan on mc3p1 (actual rows=1 loops=1)
|
||||
Filter: ((a < 3) AND (abs(b) = 1))
|
||||
-> Seq Scan on mc3p2 (actual rows=1 loops=1)
|
||||
Filter: ((a < 3) AND (abs(b) = 1))
|
||||
(7 rows)
|
||||
|
||||
drop table mc3p;
|
||||
-- Ensure runtime pruning works with initplans params with boolean types
|
||||
create table boolvalues (value bool not null);
|
||||
insert into boolvalues values('t'),('f');
|
||||
|
@ -757,6 +757,25 @@ select * from stable_qual_pruning
|
||||
|
||||
drop table stable_qual_pruning;
|
||||
|
||||
--
|
||||
-- Check that pruning with composite range partitioning works correctly when
|
||||
-- it must ignore clauses for trailing keys once it has seen a clause with
|
||||
-- non-inclusive operator for an earlier key
|
||||
--
|
||||
create table mc3p (a int, b int, c int) partition by range (a, abs(b), c);
|
||||
create table mc3p0 partition of mc3p
|
||||
for values from (0, 0, 0) to (0, maxvalue, maxvalue);
|
||||
create table mc3p1 partition of mc3p
|
||||
for values from (1, 1, 1) to (2, minvalue, minvalue);
|
||||
create table mc3p2 partition of mc3p
|
||||
for values from (2, minvalue, minvalue) to (3, maxvalue, maxvalue);
|
||||
insert into mc3p values (0, 1, 1), (1, 1, 1), (2, 1, 1);
|
||||
|
||||
explain (analyze, costs off, summary off, timing off)
|
||||
select * from mc3p where a < 3 and abs(b) = 1;
|
||||
|
||||
drop table mc3p;
|
||||
|
||||
-- Ensure runtime pruning works with initplans params with boolean types
|
||||
create table boolvalues (value bool not null);
|
||||
insert into boolvalues values('t'),('f');
|
||||
|
Loading…
x
Reference in New Issue
Block a user