#At file:///home/hf/work/mysql_common/38083/
2743 Alexey Botchkov 2008-09-22
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.
get_part_id_* functions return HA_ERR_NO_PARTITION_FOUND in the
*part_id out parameter in the case of the error.
per-file comments:
mysql-test/r/partition.result
Bug#38083 Error-causing row inserted into partitioned table despite error
test result
mysql-test/t/partition.test
Bug#38083 Error-causing row inserted into partitioned table despite error
test case
sql/ha_ndbcluster.cc
Bug#38083 Error-causing row inserted into partitioned table despite error
get_part_id() call fixed
sql/ha_partition.cc
Bug#38083 Error-causing row inserted into partitioned table despite error
get_part_id() call fixed
sql/opt_range.cc
Bug#38083 Error-causing row inserted into partitioned table despite error
get_part_id() call fixed
sql/partition_info.h
Bug#38083 Error-causing row inserted into partitioned table despite error
get_subpart_id_func interface changed.
sql/sql_partition.cc
Bug#38083 Error-causing row inserted into partitioned table despite error
various functions calculationg partition_id and subpart_id didn't expect
an error returned from item->val_int().
Error checks added.
modified:
mysql-test/r/partition.result
mysql-test/t/partition.test
sql/ha_ndbcluster.cc
sql/ha_partition.cc
sql/opt_range.cc
sql/partition_info.h
sql/sql_partition.cc
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result 2008-08-15 18:26:25 +0000
+++ b/mysql-test/r/partition.result 2008-09-22 08:20:18 +0000
@@ -1637,4 +1637,23 @@ select count(*) from t1, t2 where t1.cre
count(*)
1
drop table t1, t2;
+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;
End of 5.1 tests
=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test 2008-08-15 18:26:25 +0000
+++ b/mysql-test/t/partition.test 2008-09-22 08:20:18 +0000
@@ -1791,4 +1791,26 @@ select count(*) from t1, t2 where t1.cre
drop table t1, t2;
+#
+# 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;
+
+
--echo End of 5.1 tests
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2008-09-15 09:19:56 +0000
+++ b/sql/ha_ndbcluster.cc 2008-09-22 08:20:18 +0000
@@ -2011,7 +2011,7 @@ int ha_ndbcluster::peek_indexed_rows(con
if (error)
{
m_part_info->err_value= func_value;
- DBUG_RETURN(error);
+ DBUG_RETURN(part_id);
}
op->setPartitionId(part_id);
}
@@ -2794,7 +2794,7 @@ int ha_ndbcluster::write_row(uchar *reco
if (error)
{
m_part_info->err_value= func_value;
- DBUG_RETURN(error);
+ DBUG_RETURN(part_id);
}
op->setPartitionId(part_id);
}
=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc 2008-08-20 15:29:14 +0000
+++ b/sql/ha_partition.cc 2008-09-22 08:20:18 +0000
@@ -2896,6 +2896,7 @@ int ha_partition::write_row(uchar * buf)
dbug_tmp_restore_column_map(table->read_set, old_map);
if (unlikely(error))
{
+ error= part_id;
m_part_info->err_value= func_value;
goto exit;
}
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-08-25 17:18:22 +0000
+++ b/sql/opt_range.cc 2008-09-22 08:20:18 +0000
@@ -3145,10 +3145,12 @@ int find_used_partitions(PART_PRUNE_PARA
ppar->subpart_fields););
/* Find the subpartition (it's HASH/KEY so we always have one) */
partition_info *part_info= ppar->part_info;
- uint32 subpart_id= part_info->get_subpartition_id(part_info);
+ uint32 part_id, subpart_id;
+ if (part_info->get_subpartition_id(part_info, &subpart_id))
+ return 0;
+
/* Mark this partition as used in each subpartition. */
- uint32 part_id;
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
NOT_A_PARTITION_ID)
{
=== modified file 'sql/partition_info.h'
--- a/sql/partition_info.h 2008-03-16 08:52:37 +0000
+++ b/sql/partition_info.h 2008-09-22 08:20:18 +0000
@@ -25,7 +25,8 @@ class partition_info;
typedef int (*get_part_id_func)(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
-typedef uint32 (*get_subpart_id_func)(partition_info *part_info);
+typedef int (*get_subpart_id_func)(partition_info *part_info,
+ uint32 *part_id);
struct st_ddl_log_memory_entry;
=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc 2008-08-11 18:02:03 +0000
+++ b/sql/sql_partition.cc 2008-09-22 08:20:18 +0000
@@ -73,10 +73,8 @@ static int get_part_id_charset_func_subp
static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
-static uint32 get_subpart_id_charset_func(partition_info *part_info);
-int get_partition_id_list(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value);
+static int get_subpart_id_charset_func(partition_info *part_info,
+ uint32 *part_id);
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
@@ -119,10 +117,14 @@ int get_partition_id_list_sub_linear_has
int get_partition_id_list_sub_linear_key(partition_info *part_info,
uint32 *part_id,
longlong *func_value);
-uint32 get_partition_id_hash_sub(partition_info *part_info);
-uint32 get_partition_id_key_sub(partition_info *part_info);
-uint32 get_partition_id_linear_hash_sub(partition_info *part_info);
-uint32 get_partition_id_linear_key_sub(partition_info *part_info);
+int get_partition_id_hash_sub(partition_info *part_info,
+ uint32 *part_id);
+int get_partition_id_key_sub(partition_info *part_info,
+ uint32 *part_id);
+int get_partition_id_linear_hash_sub(partition_info *part_info,
+ uint32 *part_id);
+int get_partition_id_linear_key_sub(partition_info *part_info,
+ uint32 *part_id);
static uint32 get_next_partition_via_walking(PARTITION_ITERATOR*);
static void set_up_range_analysis_info(partition_info *part_info);
static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*);
@@ -312,7 +314,7 @@ int get_parts_for_update(const uchar *ol
if (unlikely(error)) // Should never happen
{
DBUG_ASSERT(0);
- DBUG_RETURN(error);
+ DBUG_RETURN(*old_part_id);
}
#ifdef NOT_NEEDED
if (new_data == rec0)
@@ -322,7 +324,7 @@ int get_parts_for_update(const uchar *ol
new_part_id,
new_func_value)))
{
- DBUG_RETURN(error);
+ DBUG_RETURN(*new_part_id);
}
}
#ifdef NOT_NEEDED
@@ -339,7 +341,7 @@ int get_parts_for_update(const uchar *ol
set_field_ptr(part_field_array, rec0, new_data);
if (unlikely(error))
{
- DBUG_RETURN(error);
+ DBUG_RETURN(*new_part_id);
}
}
#endif
@@ -380,7 +382,7 @@ int get_part_for_delete(const uchar *buf
if (unlikely((error= part_info->get_partition_id(part_info, part_id,
&func_value))))
{
- DBUG_RETURN(error);
+ DBUG_RETURN(*part_id);
}
DBUG_PRINT("info", ("Delete from partition %d", *part_id));
}
@@ -392,7 +394,7 @@ int get_part_for_delete(const uchar *buf
set_field_ptr(part_field_array, rec0, buf);
if (unlikely(error))
{
- DBUG_RETURN(error);
+ DBUG_RETURN(*part_id);
}
DBUG_PRINT("info", ("Delete from partition %d (path2)", *part_id));
}
@@ -2319,16 +2321,21 @@ 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 +2343,13 @@ 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;
+ if (current_thd->is_error())
+ {
+ *part_id= HA_ERR_NO_PARTITION_FOUND;
+ DBUG_RETURN(TRUE);
+ }
+ DBUG_RETURN(FALSE);
}
@@ -2349,24 +2362,34 @@ 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())
+ {
+ *part_id= HA_ERR_NO_PARTITION_FOUND;
+ DBUG_RETURN(TRUE);
+ }
+ *part_id= get_part_id_from_linear_hash(*func_value,
+ part_info->linear_hash_mask,
+ no_parts);
+ DBUG_RETURN(FALSE);
}
@@ -2503,49 +2526,7 @@ static void restore_part_field_pointers(
}
return;
}
-/*
- This function is used to calculate the partition id where all partition
- fields have been prepared to point to a record where the partition field
- values are bound.
-
- SYNOPSIS
- get_partition_id()
- part_info A reference to the partition_info struct where all the
- desired information is given
- out:part_id The partition id is returned through this pointer
- out: func_value Value of partition function (longlong)
-
- RETURN VALUE
- part_id Partition id of partition that would contain
- row with given values of PF-fields
- HA_ERR_NO_PARTITION_FOUND The fields of the partition function didn't
- fit into any partition and thus the values of
- the PF-fields are not allowed.
-
- DESCRIPTION
- A routine used from write_row, update_row and delete_row from any
- handler supporting partitioning. It is also a support routine for
- get_partition_set used to find the set of partitions needed to scan
- for a certain index scan or full table scan.
-
- It is actually 14 different variants of this function which are called
- through a function pointer.
- get_partition_id_list
- get_partition_id_range
- get_partition_id_hash_nosub
- get_partition_id_key_nosub
- get_partition_id_linear_hash_nosub
- get_partition_id_linear_key_nosub
- get_partition_id_range_sub_hash
- get_partition_id_range_sub_key
- get_partition_id_range_sub_linear_hash
- get_partition_id_range_sub_linear_key
- get_partition_id_list_sub_hash
- get_partition_id_list_sub_key
- get_partition_id_list_sub_linear_hash
- get_partition_id_list_sub_linear_key
-*/
/*
This function is used to calculate the main partition to use in the case of
@@ -2557,14 +2538,12 @@ static void restore_part_field_pointers(
part_info A reference to the partition_info struct where all the
desired information is given
out:part_id The partition id is returned through this pointer
- out: func_value The value calculated by partition function
+ out:func_value The value calculated by partition function
RETURN VALUE
- part_id Partition id of partition that would contain
- row with given values of PF-fields
- HA_ERR_NO_PARTITION_FOUND The fields of the partition function didn't
- fit into any partition and thus the values of
- the PF-fields are not allowed.
+ TRUE Error, the error code of HA_ERR_NO_PARTITION_FOUND
+ will be in part_id
+ FALSE correct part_id defined
DESCRIPTION
@@ -2640,13 +2619,14 @@ static int get_part_part_id_charset_func
}
-static uint32 get_subpart_id_charset_func(partition_info *part_info)
+static int get_subpart_id_charset_func(partition_info *part_info,
+ uint32 *part_id)
{
int res;
copy_to_part_field_buffers(part_info->subpart_charset_field_array,
part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs);
- res= part_info->get_subpartition_id_charset(part_info);
+ res= part_info->get_subpartition_id_charset(part_info, part_id);
restore_part_field_pointers(part_info->subpart_charset_field_array,
part_info->restore_subpart_field_ptrs);
return res;
@@ -2666,12 +2646,15 @@ 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)
{
*part_id= part_info->has_null_part_id;
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
goto notfound;
}
@@ -2693,12 +2676,12 @@ int get_partition_id_list(partition_info
else
{
*part_id= (uint32)list_array[list_index].partition_id;
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
}
notfound:
- *part_id= 0;
- DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+ *part_id= HA_ERR_NO_PARTITION_FOUND;
+ DBUG_RETURN(TRUE);
}
@@ -2813,10 +2796,16 @@ 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())
+ {
+ *part_id= HA_ERR_NO_PARTITION_FOUND;
+ DBUG_RETURN(TRUE);
+ }
+
if (part_info->part_expr->null_value)
{
*part_id= 0;
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
*func_value= part_func_value;
if (unsigned_flag)
@@ -2837,10 +2826,13 @@ int get_partition_id_range(partition_inf
if (loc_part_id == max_partition &&
part_func_value >= range_array[loc_part_id] &&
!part_info->defined_max_value)
- DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+ {
+ *part_id= HA_ERR_NO_PARTITION_FOUND;
+ DBUG_RETURN(TRUE);
+ }
DBUG_PRINT("exit",("partition: %d", *part_id));
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -2970,9 +2962,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 +2971,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);
}
@@ -2992,7 +2982,7 @@ int get_partition_id_key_nosub(partition
{
*part_id= get_part_id_key(part_info->part_field_array,
part_info->no_parts, func_value);
- return 0;
+ return FALSE;
}
@@ -3003,7 +2993,7 @@ int get_partition_id_linear_key_nosub(pa
*part_id= get_part_id_linear_key(part_info,
part_info->part_field_array,
part_info->no_parts, func_value);
- return 0;
+ return FALSE;
}
@@ -3020,13 +3010,19 @@ int get_partition_id_range_sub_hash(part
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
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))
+ {
+ *part_id= sub_part_id;
+ DBUG_RETURN(TRUE);
+ }
+
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3043,14 +3039,21 @@ int get_partition_id_range_sub_linear_ha
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
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))
+ {
+ *part_id= sub_part_id;
+ DBUG_RETURN(TRUE);
+ }
+
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3067,13 +3070,14 @@ int get_partition_id_range_sub_key(parti
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_key(part_info->subpart_field_array,
no_subparts, &local_func_value);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3090,6 +3094,7 @@ int get_partition_id_range_sub_linear_ke
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
@@ -3097,7 +3102,7 @@ int get_partition_id_range_sub_linear_ke
part_info->subpart_field_array,
no_subparts, &local_func_value);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3114,13 +3119,19 @@ int get_partition_id_list_sub_hash(parti
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
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))
+ {
+ *part_id= sub_part_id;
+ DBUG_RETURN(TRUE);
+ }
+
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3137,14 +3148,21 @@ int get_partition_id_list_sub_linear_has
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
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))
+ {
+ *part_id= sub_part_id;
+ DBUG_RETURN(TRUE);
+ }
+
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3161,13 +3179,14 @@ int get_partition_id_list_sub_key(partit
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_key(part_info->subpart_field_array,
no_subparts, &local_func_value);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3184,6 +3203,7 @@ int get_partition_id_list_sub_linear_key
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value))))
{
+ *part_id= loc_part_id;
DBUG_RETURN(error);
}
no_subparts= part_info->no_subparts;
@@ -3191,7 +3211,7 @@ int get_partition_id_list_sub_linear_key
part_info->subpart_field_array,
no_subparts, &local_func_value);
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -3219,36 +3239,43 @@ int get_partition_id_list_sub_linear_key
get_partition_id_linear_key_sub
*/
-uint32 get_partition_id_hash_sub(partition_info *part_info)
+int get_partition_id_hash_sub(partition_info *part_info,
+ uint32 *part_id)
{
longlong func_value;
return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr,
- &func_value);
+ part_id, &func_value);
}
-uint32 get_partition_id_linear_hash_sub(partition_info *part_info)
+int get_partition_id_linear_hash_sub(partition_info *part_info,
+ uint32 *part_id)
{
longlong func_value;
return get_part_id_linear_hash(part_info, part_info->no_subparts,
- part_info->subpart_expr, &func_value);
+ part_info->subpart_expr, part_id,
+ &func_value);
}
-uint32 get_partition_id_key_sub(partition_info *part_info)
+int get_partition_id_key_sub(partition_info *part_info,
+ uint32 *part_id)
{
longlong func_value;
- return get_part_id_key(part_info->subpart_field_array,
- part_info->no_subparts, &func_value);
+ *part_id= get_part_id_key(part_info->subpart_field_array,
+ part_info->no_subparts, &func_value);
+ return FALSE;
}
-uint32 get_partition_id_linear_key_sub(partition_info *part_info)
+int get_partition_id_linear_key_sub(partition_info *part_info,
+ uint32 *part_id)
{
longlong func_value;
- return get_part_id_linear_key(part_info,
- part_info->subpart_field_array,
- part_info->no_subparts, &func_value);
+ *part_id= get_part_id_linear_key(part_info,
+ part_info->subpart_field_array,
+ part_info->no_subparts, &func_value);
+ return FALSE;
}
@@ -3337,37 +3364,39 @@ static bool check_part_func_bound(Field
buf A buffer that can be used to evaluate the partition function
key_info The index object
key_spec A key_range containing key and key length
+ out:part_id The returned partition id
RETURN VALUES
- part_id Subpartition id to use
+ TRUE All fields in partition function are set
+ FALSE Not all fields in partition function are set
+
DESCRIPTION
Use key buffer to set-up record in buf, move field pointers and
get the partition identity and restore field pointers afterwards.
*/
-static uint32 get_sub_part_id_from_key(const TABLE *table,uchar *buf,
- KEY *key_info,
- const key_range *key_spec)
+static int get_sub_part_id_from_key(const TABLE *table,uchar *buf,
+ KEY *key_info,
+ const key_range *key_spec,
+ uint32 *part_id)
{
uchar *rec0= table->record[0];
partition_info *part_info= table->part_info;
- uint32 part_id;
+ int res;
DBUG_ENTER("get_sub_part_id_from_key");
key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
if (likely(rec0 == buf))
- {
- part_id= part_info->get_subpartition_id(part_info);
- }
+ res= part_info->get_subpartition_id(part_info, part_id);
else
{
Field **part_field_array= part_info->subpart_field_array;
set_field_ptr(part_field_array, buf, rec0);
- part_id= part_info->get_subpartition_id(part_info);
+ res= part_info->get_subpartition_id(part_info, part_id);
set_field_ptr(part_field_array, rec0, buf);
}
- DBUG_RETURN(part_id);
+ DBUG_RETURN(res);
}
/*
@@ -3586,7 +3615,13 @@ void get_partition_set(const TABLE *tabl
else if (part_info->is_sub_partitioned())
{
if (part_info->all_fields_in_SPF.is_set(index))
- sub_part= get_sub_part_id_from_key(table, buf, key_info, key_spec);
+ {
+ if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
+ {
+ part_spec->start_part= no_parts;
+ DBUG_VOID_RETURN;
+ }
+ }
else if (part_info->all_fields_in_PPF.is_set(index))
{
if (get_part_id_from_key(table,buf,key_info,
@@ -3632,7 +3667,14 @@ void get_partition_set(const TABLE *tabl
else if (part_info->is_sub_partitioned())
{
if (check_part_func_bound(part_info->subpart_field_array))
- sub_part= get_sub_part_id_from_key(table, buf, key_info, key_spec);
+ {
+ if (get_sub_part_id_from_key(table, buf, key_info, key_spec, &sub_part))
+ {
+ part_spec->start_part= no_parts;
+ clear_indicator_in_key_fields(key_info);
+ DBUG_VOID_RETURN;
+ }
+ }
else if (check_part_func_bound(part_info->part_field_array))
{
if (get_part_id_from_key(table,buf,key_info,key_spec,&part_part))
@@ -6836,9 +6878,11 @@ int get_part_iter_for_interval_via_walki
field->set_null();
if (is_subpart)
{
- part_id= part_info->get_subpartition_id(part_info);
- init_single_partition_iterator(part_id, part_iter);
- return 1; /* Ok, iterator initialized */
+ if (!part_info->get_subpartition_id(part_info, &part_id))
+ {
+ init_single_partition_iterator(part_id, part_iter);
+ return 1; /* Ok, iterator initialized */
+ }
}
else
{
@@ -7007,13 +7051,17 @@ static uint32 get_next_partition_via_wal
static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
{
Field *field= part_iter->part_info->subpart_field_array[0];
+ uint32 res;
if (part_iter->field_vals.cur == part_iter->field_vals.end)
{
part_iter->field_vals.cur= part_iter->field_vals.start;
return NOT_A_PARTITION_ID;
}
field->store(part_iter->field_vals.cur++, FALSE);
- return part_iter->part_info->get_subpartition_id(part_iter->part_info);
+ if (part_iter->part_info->get_subpartition_id(part_iter->part_info,
+ &res))
+ return NOT_A_PARTITION_ID;
+ return res;
}
| Thread |
|---|
| • bzr commit into mysql-5.1 branch (holyfoot:2743) Bug#38083 | Alexey Botchkov | 22 Sep |