BUG#19801: Valgrind error in check_list_constants

Needed some special handling of the case when no_list_values == 0
parent 2e6b5157
...@@ -757,6 +757,18 @@ insert into t1 values (null); ...@@ -757,6 +757,18 @@ insert into t1 values (null);
select * from t1 where f1 is null; select * from t1 where f1 is null;
f1 f1
NULL NULL
select * from t1 where f1 < 1;
f1
select * from t1 where f1 <= NULL;
f1
select * from t1 where f1 < NULL;
f1
select * from t1 where f1 >= NULL;
f1
select * from t1 where f1 > NULL;
f1
select * from t1 where f1 > 1;
f1
drop table t1; drop table t1;
create table t1 (f1 smallint) create table t1 (f1 smallint)
partition by range (f1) (partition p0 values less than (0)); partition by range (f1) (partition p0 values less than (0));
......
...@@ -895,6 +895,12 @@ create table t1 (f1 smallint) ...@@ -895,6 +895,12 @@ create table t1 (f1 smallint)
partition by list (f1) (partition p0 values in (null)); partition by list (f1) (partition p0 values in (null));
insert into t1 values (null); insert into t1 values (null);
select * from t1 where f1 is null; select * from t1 where f1 is null;
select * from t1 where f1 < 1;
select * from t1 where f1 <= NULL;
select * from t1 where f1 < NULL;
select * from t1 where f1 >= NULL;
select * from t1 where f1 > NULL;
select * from t1 where f1 > 1;
drop table t1; drop table t1;
create table t1 (f1 smallint) create table t1 (f1 smallint)
......
...@@ -612,7 +612,8 @@ bool partition_info::check_list_constants() ...@@ -612,7 +612,8 @@ bool partition_info::check_list_constants()
no_list_values++; no_list_values++;
} while (++i < no_parts); } while (++i < no_parts);
list_func_it.rewind(); list_func_it.rewind();
list_array= (LIST_PART_ENTRY*)sql_alloc(no_list_values*sizeof(LIST_PART_ENTRY)); list_array= (LIST_PART_ENTRY*)sql_alloc((no_list_values+1) *
sizeof(LIST_PART_ENTRY));
if (unlikely(list_array == NULL)) if (unlikely(list_array == NULL))
{ {
mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY)); mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
...@@ -631,25 +632,29 @@ bool partition_info::check_list_constants() ...@@ -631,25 +632,29 @@ bool partition_info::check_list_constants()
} }
} while (++i < no_parts); } while (++i < no_parts);
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY), if (no_list_values)
&list_part_cmp);
not_first= FALSE;
i= prev_value= 0; //prev_value initialised to quiet compiler
do
{ {
curr_value= list_array[i].list_value; qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
if (likely(!not_first || prev_value != curr_value)) &list_part_cmp);
{
prev_value= curr_value; not_first= FALSE;
not_first= TRUE; i= prev_value= 0; //prev_value initialised to quiet compiler
} do
else
{ {
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0)); DBUG_ASSERT(i < no_list_values);
goto end; curr_value= list_array[i].list_value;
} if (likely(!not_first || prev_value != curr_value))
} while (++i < no_list_values); {
prev_value= curr_value;
not_first= TRUE;
}
else
{
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
goto end;
}
} while (++i < no_list_values);
}
result= FALSE; result= FALSE;
end: end:
DBUG_RETURN(result); DBUG_RETURN(result);
......
...@@ -2257,8 +2257,8 @@ static uint32 get_part_id_linear_key(partition_info *part_info, ...@@ -2257,8 +2257,8 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
int get_partition_id_list(partition_info *part_info, int get_partition_id_list(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value) longlong *func_value)
{ {
LIST_PART_ENTRY *list_array= part_info->list_array; LIST_PART_ENTRY *list_array= part_info->list_array;
int list_index; int list_index;
...@@ -2351,7 +2351,8 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info, ...@@ -2351,7 +2351,8 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
uint min_list_index= 0, max_list_index= part_info->no_list_values - 1; uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
/* Get the partitioning function value for the endpoint */ /* Get the partitioning function value for the endpoint */
longlong part_func_value= part_val_int(part_info->part_expr); longlong part_func_value= part_val_int(part_info->part_expr);
while (max_list_index >= min_list_index) DBUG_ASSERT(part_info->no_list_values);
do
{ {
list_index= (max_list_index + min_list_index) >> 1; list_index= (max_list_index + min_list_index) >> 1;
list_value= list_array[list_index].list_value; list_value= list_array[list_index].list_value;
...@@ -2367,7 +2368,7 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info, ...@@ -2367,7 +2368,7 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
{ {
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint)); DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
} }
} } while (max_list_index >= min_list_index);
notfound: notfound:
if (list_value < part_func_value) if (list_value < part_func_value)
list_index++; list_index++;
...@@ -6194,6 +6195,18 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info, ...@@ -6194,6 +6195,18 @@ int get_part_iter_for_interval_via_mapping(partition_info *part_info,
part_iter->get_next= get_next_partition_id_list; part_iter->get_next= get_next_partition_id_list;
part_iter->part_info= part_info; part_iter->part_info= part_info;
part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE; part_iter->ret_null_part= part_iter->ret_null_part_orig= FALSE;
if (max_endpoint_val == 0)
{
/*
We handle this special case without optimisations since it is
of little practical value but causes a great number of complex
checks later in the code.
*/
part_iter->part_nums.start= part_iter->part_nums.end= 0;
part_iter->part_nums.cur= 0;
part_iter->ret_null_part= part_iter->ret_null_part_orig= TRUE;
return -1;
}
} }
else else
DBUG_ASSERT(0); DBUG_ASSERT(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment