#At file:///home/hf/work/mysql_common/38083/
2683 Alexey Botchkov 2008-08-05
Bug#38083 Error-causing row inserted into partitioned table despite error
problems are located in the sql_partition.cc where functions calculation
partition_id
don't expect error returned from item->val_int().
Fixed by adding checks to these functions.
Note - it tries to fix more problems than just the reported bug
per-file comments:
mysql-test/r/partition_error.result
Bug#38083 Error-causing row inserted into partitioned table despite error
test result
mysql-test/t/partition_error.test
Bug#38083 Error-causing row inserted into partitioned table despite error
test case
sql/sql_partition.cc
Bug#38083 Error-causing row inserted into partitioned table despite error
various functions calculationg partition_id didn't expect an error returned
from item->val_int().
Error checks added.
modified:
mysql-test/r/partition_error.result
mysql-test/t/partition_error.test
sql/sql_partition.cc
=== modified file 'mysql-test/r/partition_error.result'
--- a/mysql-test/r/partition_error.result 2008-02-25 20:18:50 +0000
+++ b/mysql-test/r/partition_error.result 2008-08-05 07:40:32 +0000
@@ -642,3 +642,22 @@ ERROR HY000: This partition function is
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
ERROR HY000: This partition function is not allowed
+set @orig_sql_mode = @@sql_mode;
+SET SQL_MODE='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';
+CREATE TABLE t1 (c1 INT)
+PARTITION BY LIST(1 DIV c1) (
+PARTITION p0 VALUES IN (NULL),
+PARTITION p1 VALUES IN (1)
+);
+INSERT INTO t1 VALUES (0);
+ERROR 22012: Division by 0
+SELECT * FROM t1;
+c1
+TRUNCATE t1;
+INSERT INTO t1 VALUES (NULL), (0), (1), (2);
+ERROR 22012: Division by 0
+SELECT * FROM t1;
+c1
+NULL
+DROP TABLE t1;
+set sql_mode= @orig_sql_mode;
=== modified file 'mysql-test/t/partition_error.test'
--- a/mysql-test/t/partition_error.test 2008-02-25 20:18:50 +0000
+++ b/mysql-test/t/partition_error.test 2008-08-05 07:40:32 +0000
@@ -826,4 +826,23 @@ partition by range (a + (select count(*)
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
+#
+# Bug #38083 Error-causing row inserted into partitioned table despite error
+#
+set @orig_sql_mode = @@sql_mode;
+SET SQL_MODE='STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO';
+CREATE TABLE t1 (c1 INT)
+ PARTITION BY LIST(1 DIV c1) (
+ PARTITION p0 VALUES IN (NULL),
+ PARTITION p1 VALUES IN (1)
+ );
+-- error ER_DIVISION_BY_ZERO
+INSERT INTO t1 VALUES (0);
+SELECT * FROM t1;
+TRUNCATE t1;
+-- error ER_DIVISION_BY_ZERO
+INSERT INTO t1 VALUES (NULL), (0), (1), (2);
+SELECT * FROM t1;
+DROP TABLE t1;
+set sql_mode= @orig_sql_mode;
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2008-07-15 01:43:12 +0000
+++ b/sql/sql_partition.cc 2008-08-05 07:40:32 +0000
@@ -2319,16 +2319,19 @@ static uint32 get_part_id_for_sub(uint32
get_part_id_hash()
no_parts Number of hash partitions
part_expr Item tree of hash function
- out:func_value Value of hash function
+ out:part_id The returned partition id
+ out:func_value Value of hash function
RETURN VALUE
- Calculated partition id
+ FALSE Success
+ TRUE Failure
*/
inline
-static uint32 get_part_id_hash(uint no_parts,
- Item *part_expr,
- longlong *func_value)
+static int get_part_id_hash(uint no_parts,
+ Item *part_expr,
+ uint32 *part_id,
+ longlong *func_value)
{
longlong int_hash_id;
DBUG_ENTER("get_part_id_hash");
@@ -2336,7 +2339,8 @@ static uint32 get_part_id_hash(uint no_p
*func_value= part_val_int(part_expr);
int_hash_id= *func_value % no_parts;
- DBUG_RETURN(int_hash_id < 0 ? (uint32) -int_hash_id : (uint32) int_hash_id);
+ *part_id= int_hash_id < 0 ? (uint32) -int_hash_id : (uint32) int_hash_id;
+ DBUG_RETURN(current_thd->is_error());
}
@@ -2349,24 +2353,30 @@ static uint32 get_part_id_hash(uint no_p
desired information is given
no_parts Number of hash partitions
part_expr Item tree of hash function
+ out:part_id The returned partition id
out:func_value Value of hash function
RETURN VALUE
- Calculated partition id
+ FALSE Success
+ TRUE Failure
*/
inline
-static uint32 get_part_id_linear_hash(partition_info *part_info,
- uint no_parts,
- Item *part_expr,
- longlong *func_value)
+static int get_part_id_linear_hash(partition_info *part_info,
+ uint no_parts,
+ Item *part_expr,
+ uint32 *part_id,
+ longlong *func_value)
{
DBUG_ENTER("get_part_id_linear_hash");
*func_value= part_val_int(part_expr);
- DBUG_RETURN(get_part_id_from_linear_hash(*func_value,
- part_info->linear_hash_mask,
- no_parts));
+ if (current_thd->is_error())
+ DBUG_RETURN(TRUE);
+ *part_id= get_part_id_from_linear_hash(*func_value,
+ part_info->linear_hash_mask,
+ no_parts);
+ DBUG_RETURN(FALSE);
}
@@ -2666,6 +2676,8 @@ int get_partition_id_list(partition_info
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("get_partition_id_list");
+ if (current_thd->is_error())
+ goto notfound;
if (part_info->part_expr->null_value)
{
if (part_info->has_null_value)
@@ -2813,6 +2825,9 @@ int get_partition_id_range(partition_inf
bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("get_partition_id_range");
+ if (current_thd->is_error())
+ DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
if (part_info->part_expr->null_value)
{
*part_id= 0;
@@ -2970,9 +2985,8 @@ int get_partition_id_hash_nosub(partitio
uint32 *part_id,
longlong *func_value)
{
- *part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr,
- func_value);
- return 0;
+ return get_part_id_hash(part_info->no_parts, part_info->part_expr,
+ part_id, func_value);
}
@@ -2980,9 +2994,8 @@ int get_partition_id_linear_hash_nosub(p
uint32 *part_id,
longlong *func_value)
{
- *part_id= get_part_id_linear_hash(part_info, part_info->no_parts,
- part_info->part_expr, func_value);
- return 0;
+ return get_part_id_linear_hash(part_info, part_info->no_parts,
+ part_info->part_expr, part_id, func_value);
}
@@ -3023,8 +3036,10 @@ int get_partition_id_range_sub_hash(part
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
- sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
- &local_func_value);
+ if (get_part_id_hash(no_subparts, part_info->subpart_expr,
+ &sub_part_id, &local_func_value))
+ DBUG_RETURN(1);
+
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0);
}
@@ -3046,9 +3061,11 @@ int get_partition_id_range_sub_linear_ha
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
- sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
- part_info->subpart_expr,
- &local_func_value);
+ if (get_part_id_linear_hash(part_info, no_subparts,
+ part_info->subpart_expr,
+ &sub_part_id,
+ &local_func_value))
+ DBUG_RETURN(1);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0);
}
@@ -3117,8 +3134,9 @@ int get_partition_id_list_sub_hash(parti
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
- sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr,
- &local_func_value);
+ if (get_part_id_hash(no_subparts, part_info->subpart_expr,
+ &sub_part_id, &local_func_value))
+ DBUG_RETURN(1);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0);
}
@@ -3140,9 +3158,11 @@ int get_partition_id_list_sub_linear_has
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
- sub_part_id= get_part_id_linear_hash(part_info, no_subparts,
- part_info->subpart_expr,
- &local_func_value);
+ if (get_part_id_linear_hash(part_info, no_subparts,
+ part_info->subpart_expr,
+ &sub_part_id,
+ &local_func_value))
+ DBUG_RETURN(1);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0);
}
@@ -3222,16 +3242,20 @@ int get_partition_id_list_sub_linear_key
uint32 get_partition_id_hash_sub(partition_info *part_info)
{
longlong func_value;
- return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr,
- &func_value);
+ uint32 part_id;
+ (void) get_part_id_hash(part_info->no_subparts, part_info->subpart_expr,
+ &part_id, &func_value);
+ return part_id;
}
uint32 get_partition_id_linear_hash_sub(partition_info *part_info)
{
longlong func_value;
- return get_part_id_linear_hash(part_info, part_info->no_subparts,
- part_info->subpart_expr, &func_value);
+ uint32 part_id;
+ (void) get_part_id_linear_hash(part_info, part_info->no_subparts,
+ part_info->subpart_expr, &part_id,
&func_value);
+ return part_id;
}