Loading mysql-test/r/partition.result +101 −0 Original line number Diff line number Diff line Loading @@ -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 mysql-test/t/partition.test +75 −0 Original line number Diff line number Diff line Loading @@ -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 sql/opt_range.cc +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading sql/sql_partition.cc +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading sql/sql_partition.h +1 −1 Original line number Diff line number Diff line Loading @@ -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 Loading
mysql-test/r/partition.result +101 −0 Original line number Diff line number Diff line Loading @@ -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
mysql-test/t/partition.test +75 −0 Original line number Diff line number Diff line Loading @@ -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
sql/opt_range.cc +1 −0 Original line number Diff line number Diff line Loading @@ -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; Loading
sql/sql_partition.cc +20 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading
sql/sql_partition.h +1 −1 Original line number Diff line number Diff line Loading @@ -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