Bug#17909699: WRONG RESULTS WITH PARTITION BY LIST COLUMNS()
Typo leading to not including the last list values (partition). Also improved pruning to skip last partition if not used. rb#4762 approved by Aditya and Marko.
This commit is contained in:
parent
aced599475
commit
b822ebf60c
@ -3294,3 +3294,117 @@ explain partitions select * from t1 where a between 10 and 10+33;
|
|||||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t1 p0,p1,p2 ALL NULL NULL NULL NULL 100 Using where
|
1 SIMPLE t1 p0,p1,p2 ALL NULL NULL NULL NULL 100 Using where
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
#
|
||||||
|
# Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
|
||||||
|
#
|
||||||
|
CREATE TABLE t1
|
||||||
|
(c1 int,
|
||||||
|
c2 int,
|
||||||
|
c3 int,
|
||||||
|
c4 int,
|
||||||
|
PRIMARY KEY (c1,c2))
|
||||||
|
PARTITION BY LIST COLUMNS (c2)
|
||||||
|
(PARTITION p1 VALUES IN (1,2),
|
||||||
|
PARTITION p2 VALUES IN (3,4));
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
|
||||||
|
INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 1 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 1 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 1 1 1
|
||||||
|
1 2 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 2 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 1 1 1
|
||||||
|
1 2 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
1 1 1 1
|
||||||
|
1 2 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 3 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 3 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 3 1 1
|
||||||
|
2 4 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 4 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 3 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 3 1 1
|
||||||
|
2 4 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 4 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
2 4 1 1
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
|
||||||
|
c1 c2 c3 c4
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 1 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1 const PRIMARY PRIMARY 8 const,const 1
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1 range PRIMARY PRIMARY 8 NULL 1 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p1,p2 range PRIMARY PRIMARY 8 NULL 2 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p2 const PRIMARY PRIMARY 8 const,const 1
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE t1 p2 range PRIMARY PRIMARY 8 NULL 1 Using where
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
|
||||||
|
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -1410,3 +1410,51 @@ explain partitions select * from t1 where a between 10 and 13;
|
|||||||
explain partitions select * from t1 where a between 10 and 10+33;
|
explain partitions select * from t1 where a between 10 and 10+33;
|
||||||
|
|
||||||
drop table t0, t1;
|
drop table t0, t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug#71095: Wrong results with PARTITION BY LIST COLUMNS()
|
||||||
|
--echo #
|
||||||
|
CREATE TABLE t1
|
||||||
|
(c1 int,
|
||||||
|
c2 int,
|
||||||
|
c3 int,
|
||||||
|
c4 int,
|
||||||
|
PRIMARY KEY (c1,c2))
|
||||||
|
PARTITION BY LIST COLUMNS (c2)
|
||||||
|
(PARTITION p1 VALUES IN (1,2),
|
||||||
|
PARTITION p2 VALUES IN (3,4));
|
||||||
|
INSERT INTO t1 VALUES (1, 1, 1, 1), (2, 3, 1, 1);
|
||||||
|
INSERT INTO t1 VALUES (1, 2, 1, 1), (2, 4, 1, 1);
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
|
||||||
|
SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 1;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 1;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 = 1;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 >= 1;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 > 1;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 < 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 1 AND c2 <= 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 3;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 < 4;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 <= 4;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 = 4;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 >= 4;
|
||||||
|
EXPLAIN PARTITIONS SELECT * FROM t1 WHERE c1 = 2 AND c2 > 4;
|
||||||
|
DROP TABLE t1;
|
||||||
|
@ -3304,19 +3304,28 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
|
|||||||
uint num_columns= part_info->part_field_list.elements;
|
uint num_columns= part_info->part_field_list.elements;
|
||||||
uint list_index;
|
uint list_index;
|
||||||
uint min_list_index= 0;
|
uint min_list_index= 0;
|
||||||
|
int cmp;
|
||||||
|
/* Notice that max_list_index = last_index + 1 here! */
|
||||||
uint max_list_index= part_info->num_list_values;
|
uint max_list_index= part_info->num_list_values;
|
||||||
DBUG_ENTER("get_partition_id_cols_list_for_endpoint");
|
DBUG_ENTER("get_partition_id_cols_list_for_endpoint");
|
||||||
|
|
||||||
/* Find the matching partition (including taking endpoint into account). */
|
/* Find the matching partition (including taking endpoint into account). */
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Midpoint, adjusted down, so it can never be > last index. */
|
/* Midpoint, adjusted down, so it can never be >= max_list_index. */
|
||||||
list_index= (max_list_index + min_list_index) >> 1;
|
list_index= (max_list_index + min_list_index) >> 1;
|
||||||
if (cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
|
cmp= cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
|
||||||
nparts, left_endpoint, include_endpoint) > 0)
|
nparts, left_endpoint, include_endpoint);
|
||||||
|
if (cmp > 0)
|
||||||
|
{
|
||||||
min_list_index= list_index + 1;
|
min_list_index= list_index + 1;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
max_list_index= list_index;
|
max_list_index= list_index;
|
||||||
|
if (cmp == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (max_list_index > min_list_index);
|
} while (max_list_index > min_list_index);
|
||||||
list_index= max_list_index;
|
list_index= max_list_index;
|
||||||
|
|
||||||
@ -3333,12 +3342,10 @@ uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
|
|||||||
nparts, left_endpoint,
|
nparts, left_endpoint,
|
||||||
include_endpoint)));
|
include_endpoint)));
|
||||||
|
|
||||||
if (!left_endpoint)
|
/* Include the right endpoint if not already passed end of array. */
|
||||||
{
|
if (!left_endpoint && include_endpoint && cmp == 0 &&
|
||||||
/* Set the end after this list tuple if not already after the last. */
|
list_index < part_info->num_list_values)
|
||||||
if (list_index < part_info->num_parts)
|
list_index++;
|
||||||
list_index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBUG_RETURN(list_index);
|
DBUG_RETURN(list_index);
|
||||||
}
|
}
|
||||||
@ -7493,15 +7500,13 @@ static int cmp_rec_and_tuple_prune(part_column_list_val *val,
|
|||||||
field= val->part_info->part_field_array + n_vals_in_rec;
|
field= val->part_info->part_field_array + n_vals_in_rec;
|
||||||
if (!(*field))
|
if (!(*field))
|
||||||
{
|
{
|
||||||
/*
|
/* Full match. Only equal if including endpoint. */
|
||||||
Full match, if right endpoint and not including the endpoint,
|
if (include_endpoint)
|
||||||
(rec < part) return lesser.
|
return 0;
|
||||||
*/
|
|
||||||
if (!is_left_endpoint && !include_endpoint)
|
|
||||||
return -4;
|
|
||||||
|
|
||||||
/* Otherwise they are equal! */
|
if (is_left_endpoint)
|
||||||
return 0;
|
return +4; /* Start of range, part_tuple < rec, return higher. */
|
||||||
|
return -4; /* End of range, rec < part_tupe, return lesser. */
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
The prefix is equal and there are more partition columns to compare.
|
The prefix is equal and there are more partition columns to compare.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user