summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-05-30 00:08:48 -0400
committerunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-05-30 00:08:48 -0400
commit10c5b8b6fd63365d5d3812964912752a6a89510b (patch)
tree09d13c65f19b8447af078c3fc5cea2d85df632dc
parente05d55de5ff6c95143fb1096da8019ab5fb7c6a2 (diff)
downloadmariadb-git-10c5b8b6fd63365d5d3812964912752a6a89510b.tar.gz
BUG#19801: Valgrind error in check_list_constants
Needed some special handling of the case when no_list_values == 0 mysql-test/r/partition.result: Added a couple of new test cases mysql-test/t/partition.test: Added a couple of new test cases sql/partition_info.cc: Rearranged some code to handle case where no_list_values == 0 which happens when one partition with only one value == NULL. sql/sql_partition.cc: Rearranged code to remove compiler warning and also since we now have handled the case where no_list_values == 0 in a special case before coming here Added code for handling the special case where no_list_values == 0
-rw-r--r--mysql-test/r/partition.result12
-rw-r--r--mysql-test/t/partition.test6
-rw-r--r--sql/partition_info.cc41
-rw-r--r--sql/sql_partition.cc21
4 files changed, 58 insertions, 22 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 3be9f3edee2..a4f40a130b5 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -757,6 +757,18 @@ insert into t1 values (null);
select * from t1 where f1 is null;
f1
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;
create table t1 (f1 smallint)
partition by range (f1) (partition p0 values less than (0));
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index a24124d3fb5..75defdeccf1 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -895,6 +895,12 @@ 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;
+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;
create table t1 (f1 smallint)
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 0924a8adf6e..6e3023289d8 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -612,7 +612,8 @@ bool partition_info::check_list_constants()
no_list_values++;
} while (++i < no_parts);
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))
{
mem_alloc_error(no_list_values * sizeof(LIST_PART_ENTRY));
@@ -631,25 +632,29 @@ bool partition_info::check_list_constants()
}
} while (++i < no_parts);
- qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
- &list_part_cmp);
-
- not_first= FALSE;
- i= prev_value= 0; //prev_value initialised to quiet compiler
- do
+ if (no_list_values)
{
- curr_value= list_array[i].list_value;
- if (likely(!not_first || prev_value != curr_value))
- {
- prev_value= curr_value;
- not_first= TRUE;
- }
- else
+ qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
+ &list_part_cmp);
+
+ not_first= FALSE;
+ i= prev_value= 0; //prev_value initialised to quiet compiler
+ do
{
- my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
- goto end;
- }
- } while (++i < no_list_values);
+ DBUG_ASSERT(i < no_list_values);
+ curr_value= list_array[i].list_value;
+ if (likely(!not_first || prev_value != curr_value))
+ {
+ 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;
end:
DBUG_RETURN(result);
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index e946e972968..b6756821245 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -2257,8 +2257,8 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
int get_partition_id_list(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value)
+ uint32 *part_id,
+ longlong *func_value)
{
LIST_PART_ENTRY *list_array= part_info->list_array;
int list_index;
@@ -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;
/* Get the partitioning function value for the endpoint */
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_value= list_array[list_index].list_value;
@@ -2367,7 +2368,7 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
{
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
}
- }
+ } while (max_list_index >= min_list_index);
notfound:
if (list_value < part_func_value)
list_index++;
@@ -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->part_info= part_info;
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
DBUG_ASSERT(0);