Commit a206d672 authored by Alexey Botchkov's avatar Alexey Botchkov

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:
modified:
  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/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.
parent 85d5121a
...@@ -1637,4 +1637,23 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate; ...@@ -1637,4 +1637,23 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
count(*) count(*)
1 1
drop table t1, t2; 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 End of 5.1 tests
...@@ -1791,4 +1791,27 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate; ...@@ -1791,4 +1791,27 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
drop table t1, t2; 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 --echo End of 5.1 tests
...@@ -3215,10 +3215,12 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) ...@@ -3215,10 +3215,12 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree)
ppar->subpart_fields);); ppar->subpart_fields););
/* Find the subpartition (it's HASH/KEY so we always have one) */ /* Find the subpartition (it's HASH/KEY so we always have one) */
partition_info *part_info= ppar->part_info; 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. */ /* Mark this partition as used in each subpartition. */
uint32 part_id;
while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) != while ((part_id= ppar->part_iter.get_next(&ppar->part_iter)) !=
NOT_A_PARTITION_ID) NOT_A_PARTITION_ID)
{ {
......
...@@ -25,8 +25,9 @@ class partition_info; ...@@ -25,8 +25,9 @@ class partition_info;
typedef int (*get_part_id_func)(partition_info *part_info, typedef int (*get_part_id_func)(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value); 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; struct st_ddl_log_memory_entry;
class partition_info : public Sql_alloc class partition_info : public Sql_alloc
......
...@@ -73,10 +73,8 @@ static int get_part_id_charset_func_subpart(partition_info *part_info, ...@@ -73,10 +73,8 @@ static int get_part_id_charset_func_subpart(partition_info *part_info,
static int get_part_part_id_charset_func(partition_info *part_info, static int get_part_part_id_charset_func(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value); longlong *func_value);
static uint32 get_subpart_id_charset_func(partition_info *part_info); static int get_subpart_id_charset_func(partition_info *part_info,
int get_partition_id_list(partition_info *part_info, uint32 *part_id);
uint32 *part_id,
longlong *func_value);
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);
...@@ -119,10 +117,14 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info, ...@@ -119,10 +117,14 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info,
int get_partition_id_list_sub_linear_key(partition_info *part_info, int get_partition_id_list_sub_linear_key(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value); longlong *func_value);
uint32 get_partition_id_hash_sub(partition_info *part_info); int get_partition_id_hash_sub(partition_info *part_info,
uint32 get_partition_id_key_sub(partition_info *part_info); uint32 *part_id);
uint32 get_partition_id_linear_hash_sub(partition_info *part_info); int get_partition_id_key_sub(partition_info *part_info,
uint32 get_partition_id_linear_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 uint32 get_next_partition_via_walking(PARTITION_ITERATOR*);
static void set_up_range_analysis_info(partition_info *part_info); static void set_up_range_analysis_info(partition_info *part_info);
static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*); static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR*);
...@@ -2232,17 +2234,24 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields) ...@@ -2232,17 +2234,24 @@ bool partition_key_modified(TABLE *table, const MY_BITMAP *fields)
SYNOPSIS SYNOPSIS
part_val_int() part_val_int()
item_expr The item expression to evaluate item_expr The item expression to evaluate
out:result The value of the partition function,
LONGLONG_MIN if any null value in function
RETURN VALUES RETURN VALUES
The value of the partition function, LONGLONG_MIN if any null value TRUE Error in val_int()
in function FALSE ok
*/ */
static inline longlong part_val_int(Item *item_expr) static inline int part_val_int(Item *item_expr, longlong *result)
{ {
longlong value= item_expr->val_int(); *result= item_expr->val_int();
if (item_expr->null_value) if (item_expr->null_value)
value= LONGLONG_MIN; {
return value; if (current_thd->is_error())
return TRUE;
else
*result= LONGLONG_MIN;
}
return FALSE;
} }
...@@ -2319,24 +2328,29 @@ static uint32 get_part_id_for_sub(uint32 loc_part_id, uint32 sub_part_id, ...@@ -2319,24 +2328,29 @@ static uint32 get_part_id_for_sub(uint32 loc_part_id, uint32 sub_part_id,
get_part_id_hash() get_part_id_hash()
no_parts Number of hash partitions no_parts Number of hash partitions
part_expr Item tree of hash function 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 RETURN VALUE
Calculated partition id != 0 Error code
FALSE Success
*/ */
inline static int get_part_id_hash(uint no_parts,
static uint32 get_part_id_hash(uint no_parts, Item *part_expr,
Item *part_expr, uint32 *part_id,
longlong *func_value) longlong *func_value)
{ {
longlong int_hash_id; longlong int_hash_id;
DBUG_ENTER("get_part_id_hash"); DBUG_ENTER("get_part_id_hash");
*func_value= part_val_int(part_expr); if (part_val_int(part_expr, func_value))
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
int_hash_id= *func_value % no_parts; 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(FALSE);
} }
...@@ -2349,24 +2363,29 @@ static uint32 get_part_id_hash(uint no_parts, ...@@ -2349,24 +2363,29 @@ static uint32 get_part_id_hash(uint no_parts,
desired information is given desired information is given
no_parts Number of hash partitions no_parts Number of hash partitions
part_expr Item tree of hash function part_expr Item tree of hash function
out:part_id The returned partition id
out:func_value Value of hash function out:func_value Value of hash function
RETURN VALUE RETURN VALUE
Calculated partition id != 0 Error code
0 OK
*/ */
inline static int get_part_id_linear_hash(partition_info *part_info,
static uint32 get_part_id_linear_hash(partition_info *part_info, uint no_parts,
uint no_parts, Item *part_expr,
Item *part_expr, uint32 *part_id,
longlong *func_value) longlong *func_value)
{ {
DBUG_ENTER("get_part_id_linear_hash"); DBUG_ENTER("get_part_id_linear_hash");
*func_value= part_val_int(part_expr); if (part_val_int(part_expr, func_value))
DBUG_RETURN(get_part_id_from_linear_hash(*func_value, DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
part_info->linear_hash_mask,
no_parts)); *part_id= get_part_id_from_linear_hash(*func_value,
part_info->linear_hash_mask,
no_parts);
DBUG_RETURN(FALSE);
} }
...@@ -2503,49 +2522,7 @@ static void restore_part_field_pointers(Field **ptr, uchar **restore_ptr) ...@@ -2503,49 +2522,7 @@ static void restore_part_field_pointers(Field **ptr, uchar **restore_ptr)
} }
return; 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 This function is used to calculate the main partition to use in the case of
...@@ -2557,14 +2534,13 @@ static void restore_part_field_pointers(Field **ptr, uchar **restore_ptr) ...@@ -2557,14 +2534,13 @@ static void restore_part_field_pointers(Field **ptr, uchar **restore_ptr)
part_info A reference to the partition_info struct where all the part_info A reference to the partition_info struct where all the
desired information is given desired information is given
out:part_id The partition id is returned through this pointer 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 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 HA_ERR_NO_PARTITION_FOUND The fields of the partition function didn't
fit into any partition and thus the values of fit into any partition and thus the values of
the PF-fields are not allowed. the PF-fields are not allowed.
0 OK
DESCRIPTION DESCRIPTION
...@@ -2640,13 +2616,14 @@ static int get_part_part_id_charset_func(partition_info *part_info, ...@@ -2640,13 +2616,14 @@ static int get_part_part_id_charset_func(partition_info *part_info,
} }
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; int res;
copy_to_part_field_buffers(part_info->subpart_charset_field_array, copy_to_part_field_buffers(part_info->subpart_charset_field_array,
part_info->subpart_field_buffers, part_info->subpart_field_buffers,
part_info->restore_subpart_field_ptrs); 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, restore_part_field_pointers(part_info->subpart_charset_field_array,
part_info->restore_subpart_field_ptrs); part_info->restore_subpart_field_ptrs);
return res; return res;
...@@ -2661,11 +2638,15 @@ int get_partition_id_list(partition_info *part_info, ...@@ -2661,11 +2638,15 @@ int get_partition_id_list(partition_info *part_info,
int list_index; int list_index;
int min_list_index= 0; int min_list_index= 0;
int max_list_index= part_info->no_list_values - 1; int max_list_index= part_info->no_list_values - 1;
longlong part_func_value= part_val_int(part_info->part_expr); longlong part_func_value;
int error= part_val_int(part_info->part_expr, &part_func_value);
longlong list_value; longlong list_value;
bool unsigned_flag= part_info->part_expr->unsigned_flag; bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("get_partition_id_list"); DBUG_ENTER("get_partition_id_list");
if (error)
goto notfound;
if (part_info->part_expr->null_value) if (part_info->part_expr->null_value)
{ {
if (part_info->has_null_value) if (part_info->has_null_value)
...@@ -2809,10 +2790,14 @@ int get_partition_id_range(partition_info *part_info, ...@@ -2809,10 +2790,14 @@ int get_partition_id_range(partition_info *part_info,
uint min_part_id= 0; uint min_part_id= 0;
uint max_part_id= max_partition; uint max_part_id= max_partition;
uint loc_part_id; uint loc_part_id;
longlong part_func_value= part_val_int(part_info->part_expr); longlong part_func_value;
int error= part_val_int(part_info->part_expr, &part_func_value);
bool unsigned_flag= part_info->part_expr->unsigned_flag; bool unsigned_flag= part_info->part_expr->unsigned_flag;
DBUG_ENTER("get_partition_id_range"); DBUG_ENTER("get_partition_id_range");
if (error)
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
if (part_info->part_expr->null_value) if (part_info->part_expr->null_value)
{ {
*part_id= 0; *part_id= 0;
...@@ -2970,9 +2955,8 @@ int get_partition_id_hash_nosub(partition_info *part_info, ...@@ -2970,9 +2955,8 @@ int get_partition_id_hash_nosub(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value) longlong *func_value)
{ {
*part_id= get_part_id_hash(part_info->no_parts, part_info->part_expr, return get_part_id_hash(part_info->no_parts, part_info->part_expr,
func_value); part_id, func_value);
return 0;
} }
...@@ -2980,9 +2964,8 @@ int get_partition_id_linear_hash_nosub(partition_info *part_info, ...@@ -2980,9 +2964,8 @@ int get_partition_id_linear_hash_nosub(partition_info *part_info,
uint32 *part_id, uint32 *part_id,
longlong *func_value) longlong *func_value)
{ {
*part_id= get_part_id_linear_hash(part_info, part_info->no_parts, return get_part_id_linear_hash(part_info, part_info->no_parts,
part_info->part_expr, func_value); part_info->part_expr, part_id, func_value);
return 0;
} }
...@@ -3023,8 +3006,12 @@ int get_partition_id_range_sub_hash(partition_info *part_info, ...@@ -3023,8 +3006,12 @@ int get_partition_id_range_sub_hash(partition_info *part_info,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
no_subparts= part_info->no_subparts; no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr, if (unlikely((error= get_part_id_hash(no_subparts, part_info->subpart_expr,
&local_func_value); &sub_part_id, &local_func_value))))
{
DBUG_RETURN(error);
}
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts); *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3046,9 +3033,14 @@ int get_partition_id_range_sub_linear_hash(partition_info *part_info, ...@@ -3046,9 +3033,14 @@ int get_partition_id_range_sub_linear_hash(partition_info *part_info,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
no_subparts= part_info->no_subparts; no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_linear_hash(part_info, no_subparts, if (unlikely((error= get_part_id_linear_hash(part_info, no_subparts,
part_info->subpart_expr, part_info->subpart_expr,
&local_func_value); &sub_part_id,
&local_func_value))))
{
DBUG_RETURN(error);
}
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts); *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3117,8 +3109,12 @@ int get_partition_id_list_sub_hash(partition_info *part_info, ...@@ -3117,8 +3109,12 @@ int get_partition_id_list_sub_hash(partition_info *part_info,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
no_subparts= part_info->no_subparts; no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_hash(no_subparts, part_info->subpart_expr, if (unlikely((error= get_part_id_hash(no_subparts, part_info->subpart_expr,
&local_func_value); &sub_part_id, &local_func_value))))
{
DBUG_RETURN(error);
}
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts); *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3140,9 +3136,14 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info, ...@@ -3140,9 +3136,14 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info,
DBUG_RETURN(error); DBUG_RETURN(error);
} }
no_subparts= part_info->no_subparts; no_subparts= part_info->no_subparts;
sub_part_id= get_part_id_linear_hash(part_info, no_subparts, if (unlikely((error= get_part_id_linear_hash(part_info, no_subparts,
part_info->subpart_expr, part_info->subpart_expr,
&local_func_value); &sub_part_id,
&local_func_value))))
{
DBUG_RETURN(error);
}
*part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts); *part_id= get_part_id_for_sub(loc_part_id, sub_part_id, no_subparts);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3219,36 +3220,43 @@ int get_partition_id_list_sub_linear_key(partition_info *part_info, ...@@ -3219,36 +3220,43 @@ int get_partition_id_list_sub_linear_key(partition_info *part_info,
get_partition_id_linear_key_sub 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; longlong func_value;
return get_part_id_hash(part_info->no_subparts, part_info->subpart_expr, 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; longlong func_value;
return get_part_id_linear_hash(part_info, part_info->no_subparts, 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; longlong func_value;
return get_part_id_key(part_info->subpart_field_array, *part_id= get_part_id_key(part_info->subpart_field_array,
part_info->no_subparts, &func_value); 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; longlong func_value;
return get_part_id_linear_key(part_info, *part_id= get_part_id_linear_key(part_info,
part_info->subpart_field_array, part_info->subpart_field_array,
part_info->no_subparts, &func_value); part_info->no_subparts, &func_value);
return FALSE;
} }
...@@ -3337,37 +3345,40 @@ static bool check_part_func_bound(Field **ptr) ...@@ -3337,37 +3345,40 @@ static bool check_part_func_bound(Field **ptr)
buf A buffer that can be used to evaluate the partition function buf A buffer that can be used to evaluate the partition function
key_info The index object key_info The index object
key_spec A key_range containing key and key length key_spec A key_range containing key and key length
out:part_id The returned partition id
RETURN VALUES 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 DESCRIPTION
Use key buffer to set-up record in buf, move field pointers and Use key buffer to set-up record in buf, move field pointers and
get the partition identity and restore field pointers afterwards. get the partition identity and restore field pointers afterwards.
*/ */
static uint32 get_sub_part_id_from_key(const TABLE *table,uchar *buf, static int get_sub_part_id_from_key(const TABLE *table,uchar *buf,
KEY *key_info, KEY *key_info,
const key_range *key_spec) const key_range *key_spec,
uint32 *part_id)
{ {
uchar *rec0= table->record[0]; uchar *rec0= table->record[0];
partition_info *part_info= table->part_info; partition_info *part_info= table->part_info;
uint32 part_id; int res;
DBUG_ENTER("get_sub_part_id_from_key"); DBUG_ENTER("get_sub_part_id_from_key");
key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length); key_restore(buf, (uchar*)key_spec->key, key_info, key_spec->length);
if (likely(rec0 == buf)) if (likely(rec0 == buf))
{ {
part_id= part_info->get_subpartition_id(part_info); res= part_info->get_subpartition_id(part_info, part_id);
} }
else else
{ {
Field **part_field_array= part_info->subpart_field_array; Field **part_field_array= part_info->subpart_field_array;
set_field_ptr(part_field_array, buf, rec0); 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); set_field_ptr(part_field_array, rec0, buf);
} }
DBUG_RETURN(part_id); DBUG_RETURN(res);
} }
/* /*
...@@ -3586,7 +3597,13 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index, ...@@ -3586,7 +3597,13 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
else if (part_info->is_sub_partitioned()) else if (part_info->is_sub_partitioned())
{ {
if (part_info->all_fields_in_SPF.is_set(index)) 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)) else if (part_info->all_fields_in_PPF.is_set(index))
{ {
if (get_part_id_from_key(table,buf,key_info, if (get_part_id_from_key(table,buf,key_info,
...@@ -3632,7 +3649,14 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index, ...@@ -3632,7 +3649,14 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index,
else if (part_info->is_sub_partitioned()) else if (part_info->is_sub_partitioned())
{ {
if (check_part_func_bound(part_info->subpart_field_array)) 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)) 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)) if (get_part_id_from_key(table,buf,key_info,key_spec,&part_part))
...@@ -6836,9 +6860,11 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info, ...@@ -6836,9 +6860,11 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info,
field->set_null(); field->set_null();
if (is_subpart) if (is_subpart)
{ {
part_id= part_info->get_subpartition_id(part_info); if (!part_info->get_subpartition_id(part_info, &part_id))
init_single_partition_iterator(part_id, part_iter); {
return 1; /* Ok, iterator initialized */ init_single_partition_iterator(part_id, part_iter);
return 1; /* Ok, iterator initialized */
}
} }
else else
{ {
...@@ -7007,13 +7033,18 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter) ...@@ -7007,13 +7033,18 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter)
static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter) static uint32 get_next_subpartition_via_walking(PARTITION_ITERATOR *part_iter)
{ {
Field *field= part_iter->part_info->subpart_field_array[0]; Field *field= part_iter->part_info->subpart_field_array[0];
uint32 res;
if (part_iter->field_vals.cur == part_iter->field_vals.end) if (part_iter->field_vals.cur == part_iter->field_vals.end)
{ {
part_iter->field_vals.cur= part_iter->field_vals.start; part_iter->field_vals.cur= part_iter->field_vals.start;
return NOT_A_PARTITION_ID; return NOT_A_PARTITION_ID;
} }
field->store(part_iter->field_vals.cur++, FALSE); 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;
} }
......
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