Bug#18053 Partitions: crash if null
Bug#18070 Partitions: wrong result on WHERE ... IS NULL removed unnecessary code added handling of NULL values
This commit is contained in:
parent
3c6d2e322c
commit
9c82b6746a
@ -718,4 +718,105 @@ CALL test.p1(13);
|
||||
Warnings:
|
||||
Warning 1196 Some non-transactional changed tables couldn't be rolled back
|
||||
drop table t1;
|
||||
create table t1 (f1 integer) partition by range(f1)
|
||||
(partition p1 values less than (0), partition p2 values less than (10));
|
||||
insert into t1 set f1 = null;
|
||||
select * from t1 where f1 is null;
|
||||
f1
|
||||
NULL
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 p1 system NULL NULL NULL NULL 1
|
||||
drop table t1;
|
||||
create table t1 (f1 integer) partition by list(f1)
|
||||
(partition p1 values in (1), partition p2 values in (null));
|
||||
insert into t1 set f1 = null;
|
||||
insert into t1 set f1 = 1;
|
||||
select * from t1 where f1 is null or f1 = 1;
|
||||
f1
|
||||
1
|
||||
NULL
|
||||
drop table t1;
|
||||
create table t1 (f1 smallint)
|
||||
partition by list (f1) (partition p0 values in (null));
|
||||
insert into t1 values (null);
|
||||
select * from t1 where f1 is null;
|
||||
f1
|
||||
NULL
|
||||
drop table t1;
|
||||
create table t1 (f1 smallint)
|
||||
partition by range (f1) (partition p0 values less than (0));
|
||||
insert into t1 values (null);
|
||||
select * from t1 where f1 is null;
|
||||
f1
|
||||
NULL
|
||||
drop table t1;
|
||||
create table t1 (f1 integer) partition by list(f1)
|
||||
(
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (NULL),
|
||||
partition p3 values in (2),
|
||||
partition p4 values in (3),
|
||||
partition p5 values in (4)
|
||||
);
|
||||
insert into t1 values (1),(2),(3),(4),(null);
|
||||
select * from t1 where f1 < 3;
|
||||
f1
|
||||
1
|
||||
2
|
||||
explain partitions select * from t1 where f1 < 3;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 p1,p3 ALL NULL NULL NULL NULL 2 Using where
|
||||
select * from t1 where f1 is null;
|
||||
f1
|
||||
NULL
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 p2 system NULL NULL NULL NULL 1
|
||||
drop table t1;
|
||||
create table t1 (f1 int) partition by list(f1 div 2)
|
||||
(
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (NULL),
|
||||
partition p3 values in (2),
|
||||
partition p4 values in (3),
|
||||
partition p5 values in (4)
|
||||
);
|
||||
insert into t1 values (2),(4),(6),(8),(null);
|
||||
select * from t1 where f1 < 3;
|
||||
f1
|
||||
2
|
||||
explain partitions select * from t1 where f1 < 3;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 p1,p2,p3,p4,p5 ALL NULL NULL NULL NULL 5 Using where
|
||||
select * from t1 where f1 is null;
|
||||
f1
|
||||
NULL
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 p2 system NULL NULL NULL NULL 1
|
||||
drop table t1;
|
||||
create table t1 (a int) partition by LIST(a) (
|
||||
partition pn values in (NULL),
|
||||
partition p0 values in (0),
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (2)
|
||||
);
|
||||
insert into t1 values (NULL),(0),(1),(2);
|
||||
select * from t1 where a is null or a < 2;
|
||||
a
|
||||
NULL
|
||||
0
|
||||
1
|
||||
explain partitions select * from t1 where a is null or a < 2;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 pn,p0,p1 ALL NULL NULL NULL NULL 3 Using where
|
||||
select * from t1 where a is null or a < 0 or a > 1;
|
||||
a
|
||||
NULL
|
||||
2
|
||||
explain partitions select * from t1 where a is null or a < 0 or a > 1;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 pn,p2 ALL NULL NULL NULL NULL 2 Using where
|
||||
drop table t1;
|
||||
End of 5.1 tests
|
||||
|
@ -849,4 +849,79 @@ CALL test.p1(12);
|
||||
CALL test.p1(13);
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#18053 Partitions: crash if null
|
||||
# Bug#18070 Partitions: wrong result on WHERE ... IS NULL
|
||||
#
|
||||
create table t1 (f1 integer) partition by range(f1)
|
||||
(partition p1 values less than (0), partition p2 values less than (10));
|
||||
insert into t1 set f1 = null;
|
||||
select * from t1 where f1 is null;
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (f1 integer) partition by list(f1)
|
||||
(partition p1 values in (1), partition p2 values in (null));
|
||||
insert into t1 set f1 = null;
|
||||
insert into t1 set f1 = 1;
|
||||
select * from t1 where f1 is null or f1 = 1;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (f1 smallint)
|
||||
partition by list (f1) (partition p0 values in (null));
|
||||
insert into t1 values (null);
|
||||
select * from t1 where f1 is null;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (f1 smallint)
|
||||
partition by range (f1) (partition p0 values less than (0));
|
||||
insert into t1 values (null);
|
||||
select * from t1 where f1 is null;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (f1 integer) partition by list(f1)
|
||||
(
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (NULL),
|
||||
partition p3 values in (2),
|
||||
partition p4 values in (3),
|
||||
partition p5 values in (4)
|
||||
);
|
||||
|
||||
insert into t1 values (1),(2),(3),(4),(null);
|
||||
select * from t1 where f1 < 3;
|
||||
explain partitions select * from t1 where f1 < 3;
|
||||
select * from t1 where f1 is null;
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (f1 int) partition by list(f1 div 2)
|
||||
(
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (NULL),
|
||||
partition p3 values in (2),
|
||||
partition p4 values in (3),
|
||||
partition p5 values in (4)
|
||||
);
|
||||
|
||||
insert into t1 values (2),(4),(6),(8),(null);
|
||||
select * from t1 where f1 < 3;
|
||||
explain partitions select * from t1 where f1 < 3;
|
||||
select * from t1 where f1 is null;
|
||||
explain partitions select * from t1 where f1 is null;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (a int) partition by LIST(a) (
|
||||
partition pn values in (NULL),
|
||||
partition p0 values in (0),
|
||||
partition p1 values in (1),
|
||||
partition p2 values in (2)
|
||||
);
|
||||
insert into t1 values (NULL),(0),(1),(2);
|
||||
select * from t1 where a is null or a < 2;
|
||||
explain partitions select * from t1 where a is null or a < 2;
|
||||
select * from t1 where a is null or a < 0 or a > 1;
|
||||
explain partitions select * from t1 where a is null or a < 0 or a > 1;
|
||||
drop table t1;
|
||||
|
||||
--echo End of 5.1 tests
|
||||
|
@ -2296,6 +2296,7 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond)
|
||||
RANGE_OPT_PARAM *range_par= &prune_param.range_param;
|
||||
|
||||
prune_param.part_info= part_info;
|
||||
prune_param.part_iter.has_null_value= FALSE;
|
||||
|
||||
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
|
||||
range_par->mem_root= &alloc;
|
||||
|
@ -2868,9 +2868,6 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
||||
/* Get the partitioning function value for the endpoint */
|
||||
longlong part_func_value= part_val_int(part_info->part_expr);
|
||||
|
||||
if (part_info->part_expr->null_value)
|
||||
DBUG_RETURN(0);
|
||||
|
||||
while (max_part_id > min_part_id)
|
||||
{
|
||||
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
||||
@ -5745,6 +5742,19 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
|
||||
else
|
||||
DBUG_ASSERT(0);
|
||||
|
||||
if (field->real_maybe_null() && part_info->has_null_value)
|
||||
{
|
||||
if (*min_value)
|
||||
{
|
||||
if (*max_value && !(flags & (NO_MIN_RANGE | NO_MAX_RANGE)))
|
||||
{
|
||||
init_single_partition_iterator(part_info->has_null_part_id, part_iter);
|
||||
return 1;
|
||||
}
|
||||
if (!(flags & NEAR_MIN))
|
||||
part_iter->has_null_value= TRUE;
|
||||
}
|
||||
}
|
||||
/* Find minimum */
|
||||
if (flags & NO_MIN_RANGE)
|
||||
part_iter->part_nums.start= 0;
|
||||
@ -5956,7 +5966,14 @@ uint32 get_next_partition_id_range(PARTITION_ITERATOR* part_iter)
|
||||
uint32 get_next_partition_id_list(PARTITION_ITERATOR *part_iter)
|
||||
{
|
||||
if (part_iter->part_nums.start == part_iter->part_nums.end)
|
||||
{
|
||||
if (part_iter->has_null_value)
|
||||
{
|
||||
part_iter->has_null_value= FALSE;
|
||||
return part_iter->part_info->has_null_part_id;
|
||||
}
|
||||
return NOT_A_PARTITION_ID;
|
||||
}
|
||||
else
|
||||
return part_iter->part_info->list_array[part_iter->
|
||||
part_nums.start++].partition_id;
|
||||
|
@ -124,7 +124,7 @@ typedef uint32 (*partition_iter_func)(st_partition_iter* part_iter);
|
||||
typedef struct st_partition_iter
|
||||
{
|
||||
partition_iter_func get_next;
|
||||
|
||||
bool has_null_value;
|
||||
struct st_part_num_range
|
||||
{
|
||||
uint32 start;
|
||||
|
Loading…
x
Reference in New Issue
Block a user