Commit 4d026889 authored by Tatiana A. Nurnberg's avatar Tatiana A. Nurnberg

auto-merge

parents 1ad9d235 4be617cb
...@@ -1637,4 +1637,74 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate; ...@@ -1637,4 +1637,74 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
count(*) count(*)
1 1
drop table t1, t2; drop table t1, t2;
create table t1 (s1 int) partition by hash(s1) partitions 2;
create index i on t1 (s1);
insert into t1 values (1);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
s1
1
1
1
1
1
1
1
1
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (1);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
s1
1
1
1
1
1
1
1
1
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (20);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
s1
20
20
20
20
20
20
20
20
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
insert into t1 select s1 from t1 where s1=3;
select count(*) from t1;
count(*)
288
drop table t1;
End of 5.1 tests End of 5.1 tests
...@@ -1791,4 +1791,53 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate; ...@@ -1791,4 +1791,53 @@ select count(*) from t1, t2 where t1.createdDate = t2.createdDate;
drop table t1, t2; drop table t1, t2;
#
# Bug #38005 Partitions: error with insert select
#
create table t1 (s1 int) partition by hash(s1) partitions 2;
create index i on t1 (s1);
insert into t1 values (1);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (1);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (20);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
select * from t1;
drop table t1;
create table t1 (s1 int) partition by range(s1)
(partition pa1 values less than (10),
partition pa2 values less than MAXVALUE);
create index i on t1 (s1);
insert into t1 values (1), (2), (3), (4), (5), (6), (7), (8);
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1;
insert into t1 select s1 from t1 order by s1 desc;
insert into t1 select s1 from t1 where s1=3;
select count(*) from t1;
drop table t1;
--echo End of 5.1 tests --echo End of 5.1 tests
...@@ -4290,6 +4290,17 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf) ...@@ -4290,6 +4290,17 @@ int ha_partition::handle_unordered_scan_next_partition(uchar * buf)
break; break;
case partition_index_first: case partition_index_first:
DBUG_PRINT("info", ("index_first on partition %d", i)); DBUG_PRINT("info", ("index_first on partition %d", i));
/* MyISAM engine can fail if we call index_first() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_first(buf); error= file->index_first(buf);
break; break;
case partition_index_first_unordered: case partition_index_first_unordered:
...@@ -4377,10 +4388,32 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) ...@@ -4377,10 +4388,32 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order)
m_start_key.flag); m_start_key.flag);
break; break;
case partition_index_first: case partition_index_first:
/* MyISAM engine can fail if we call index_first() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_first(rec_buf_ptr); error= file->index_first(rec_buf_ptr);
reverse_order= FALSE; reverse_order= FALSE;
break; break;
case partition_index_last: case partition_index_last:
/* MyISAM engine can fail if we call index_last() when indexes disabled */
/* that happens if the table is empty. */
/* Here we use file->stats.records instead of file->records() because */
/* file->records() is supposed to return an EXACT count, and it can be */
/* possibly slow. We don't need an exact number, an approximate one- from*/
/* the last ::info() call - is sufficient. */
if (file->stats.records == 0)
{
error= HA_ERR_END_OF_FILE;
break;
}
error= file->index_last(rec_buf_ptr); error= file->index_last(rec_buf_ptr);
reverse_order= TRUE; reverse_order= TRUE;
break; break;
......
...@@ -3145,10 +3145,12 @@ int find_used_partitions(PART_PRUNE_PARAM *ppar, SEL_ARG *key_tree) ...@@ -3145,10 +3145,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;
} }
...@@ -3016,6 +2999,8 @@ int get_partition_id_range_sub_hash(partition_info *part_info, ...@@ -3016,6 +2999,8 @@ int get_partition_id_range_sub_hash(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_range_sub_hash"); DBUG_ENTER("get_partition_id_range_sub_hash");
LINT_INIT(loc_part_id);
LINT_INIT(sub_part_id);
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id, if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3023,8 +3008,12 @@ int get_partition_id_range_sub_hash(partition_info *part_info, ...@@ -3023,8 +3008,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);
} }
...@@ -3039,6 +3028,8 @@ int get_partition_id_range_sub_linear_hash(partition_info *part_info, ...@@ -3039,6 +3028,8 @@ int get_partition_id_range_sub_linear_hash(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_range_sub_linear_hash"); DBUG_ENTER("get_partition_id_range_sub_linear_hash");
LINT_INIT(loc_part_id);
LINT_INIT(sub_part_id);
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id, if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3046,9 +3037,14 @@ int get_partition_id_range_sub_linear_hash(partition_info *part_info, ...@@ -3046,9 +3037,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);
} }
...@@ -3063,6 +3059,7 @@ int get_partition_id_range_sub_key(partition_info *part_info, ...@@ -3063,6 +3059,7 @@ int get_partition_id_range_sub_key(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_range_sub_key"); DBUG_ENTER("get_partition_id_range_sub_key");
LINT_INIT(loc_part_id);
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id, if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3086,6 +3083,7 @@ int get_partition_id_range_sub_linear_key(partition_info *part_info, ...@@ -3086,6 +3083,7 @@ int get_partition_id_range_sub_linear_key(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_range_sub_linear_key"); DBUG_ENTER("get_partition_id_range_sub_linear_key");
LINT_INIT(loc_part_id);
if (unlikely((error= get_partition_id_range(part_info, &loc_part_id, if (unlikely((error= get_partition_id_range(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3110,6 +3108,7 @@ int get_partition_id_list_sub_hash(partition_info *part_info, ...@@ -3110,6 +3108,7 @@ int get_partition_id_list_sub_hash(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_list_sub_hash"); DBUG_ENTER("get_partition_id_list_sub_hash");
LINT_INIT(sub_part_id);
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id, if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3117,8 +3116,12 @@ int get_partition_id_list_sub_hash(partition_info *part_info, ...@@ -3117,8 +3116,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);
} }
...@@ -3133,6 +3136,7 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info, ...@@ -3133,6 +3136,7 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info,
longlong local_func_value; longlong local_func_value;
int error; int error;
DBUG_ENTER("get_partition_id_list_sub_linear_hash"); DBUG_ENTER("get_partition_id_list_sub_linear_hash");
LINT_INIT(sub_part_id);
if (unlikely((error= get_partition_id_list(part_info, &loc_part_id, if (unlikely((error= get_partition_id_list(part_info, &loc_part_id,
func_value)))) func_value))))
...@@ -3140,9 +3144,14 @@ int get_partition_id_list_sub_linear_hash(partition_info *part_info, ...@@ -3140,9 +3144,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 +3228,43 @@ int get_partition_id_list_sub_linear_key(partition_info *part_info, ...@@ -3219,36 +3228,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 +3353,40 @@ static bool check_part_func_bound(Field **ptr) ...@@ -3337,37 +3353,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 +3605,13 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index, ...@@ -3586,7 +3605,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 +3657,14 @@ void get_partition_set(const TABLE *table, uchar *buf, const uint index, ...@@ -3632,7 +3657,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 +6868,11 @@ int get_part_iter_for_interval_via_walking(partition_info *part_info, ...@@ -6836,9 +6868,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 +7041,18 @@ static uint32 get_next_partition_via_walking(PARTITION_ITERATOR *part_iter) ...@@ -7007,13 +7041,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