BUG#16002: Make partition functions that are unsigned work properly
This commit is contained in:
parent
ba5d08f340
commit
cef06fdb61
@ -1,4 +1,14 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
|
create table t1 (a bigint unsigned);
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFD);
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFE);
|
||||||
|
select * from t1 where (a + 1) < 10;
|
||||||
|
a
|
||||||
|
select * from t1 where (a + 1) > 10;
|
||||||
|
a
|
||||||
|
18446744073709551613
|
||||||
|
18446744073709551614
|
||||||
|
drop table t1;
|
||||||
CREATE TABLE t1 (
|
CREATE TABLE t1 (
|
||||||
a int not null,
|
a int not null,
|
||||||
b int not null,
|
b int not null,
|
||||||
@ -839,4 +849,14 @@ SHOW TABLE STATUS;
|
|||||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||||
t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
|
t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by list (a)
|
||||||
|
(partition p0 values in (0-1));
|
||||||
|
ERROR HY000: Partition function is unsigned, cannot have negative constants
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (10));
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFF);
|
||||||
|
ERROR HY000: Table has no partition for value 18446744073709551615
|
||||||
|
drop table t1;
|
||||||
End of 5.1 tests
|
End of 5.1 tests
|
||||||
|
@ -554,3 +554,7 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
|
|||||||
insert into t1 values (10);
|
insert into t1 values (10);
|
||||||
ERROR HY000: Table has no partition for value 10
|
ERROR HY000: Table has no partition for value 10
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (-1));
|
||||||
|
ERROR HY000: Partition function is unsigned, cannot have negative constants
|
||||||
|
@ -363,3 +363,15 @@ SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
|
|||||||
COUNT(*)
|
COUNT(*)
|
||||||
10
|
10
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (0),
|
||||||
|
partition p1 values less than (10));
|
||||||
|
ERROR HY000: VALUES LESS THAN value must be strictly increasing for each partition
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (2),
|
||||||
|
partition p1 values less than (10));
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFF);
|
||||||
|
ERROR HY000: Table has no partition for value 18446744073709551615
|
||||||
|
drop table t1;
|
||||||
|
@ -9,6 +9,13 @@
|
|||||||
drop table if exists t1;
|
drop table if exists t1;
|
||||||
--enable_warnings
|
--enable_warnings
|
||||||
|
|
||||||
|
create table t1 (a bigint unsigned);
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFD);
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFE);
|
||||||
|
select * from t1 where (a + 1) < 10;
|
||||||
|
select * from t1 where (a + 1) > 10;
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
#
|
#
|
||||||
# Partition by key no partition defined => OK
|
# Partition by key no partition defined => OK
|
||||||
#
|
#
|
||||||
@ -956,4 +963,20 @@ PARTITION p2 VALUES LESS THAN (30) ENGINE = MyISAM);
|
|||||||
SHOW TABLE STATUS;
|
SHOW TABLE STATUS;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
#BUG 16002 Erroneus handling of unsigned partition functions
|
||||||
|
#
|
||||||
|
--error ER_SIGNED_PARTITION_CONSTANT_ERROR
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by list (a)
|
||||||
|
(partition p0 values in (0-1));
|
||||||
|
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (10));
|
||||||
|
|
||||||
|
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFF);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
--echo End of 5.1 tests
|
--echo End of 5.1 tests
|
||||||
|
@ -747,3 +747,8 @@ CREATE TABLE t1(a int)
|
|||||||
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
|
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
|
||||||
insert into t1 values (10);
|
insert into t1 values (10);
|
||||||
drop table t1;
|
drop table t1;
|
||||||
|
|
||||||
|
--error ER_SIGNED_PARTITION_CONSTANT_ERROR
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (-1));
|
||||||
|
@ -388,3 +388,20 @@ SELECT COUNT(*) FROM t1 WHERE c3 BETWEEN '1996-12-31' AND '2000-12-31';
|
|||||||
SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
|
SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
#
|
||||||
|
# BUG 16002: Unsigned partition functions not handled correctly
|
||||||
|
#
|
||||||
|
--error ER_RANGE_NOT_INCREASING_ERROR
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (0),
|
||||||
|
partition p1 values less than (10));
|
||||||
|
|
||||||
|
create table t1 (a bigint unsigned)
|
||||||
|
partition by range (a)
|
||||||
|
(partition p0 values less than (2),
|
||||||
|
partition p1 values less than (10));
|
||||||
|
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
|
||||||
|
insert into t1 values (0xFFFFFFFFFFFFFFFF);
|
||||||
|
|
||||||
|
drop table t1;
|
||||||
|
@ -5165,9 +5165,20 @@ void ha_partition::print_error(int error, myf errflag)
|
|||||||
if (error == HA_ERR_NO_PARTITION_FOUND)
|
if (error == HA_ERR_NO_PARTITION_FOUND)
|
||||||
{
|
{
|
||||||
char buf[100];
|
char buf[100];
|
||||||
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
|
longlong value= m_part_info->part_expr->val_int();
|
||||||
m_part_info->part_expr->null_value ? "NULL" :
|
if (!m_part_info->part_expr->unsigned_flag ||
|
||||||
llstr(m_part_info->part_expr->val_int(), buf));
|
m_part_info->part_expr->null_value)
|
||||||
|
{
|
||||||
|
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),
|
||||||
|
m_part_info->part_expr->null_value ? "NULL" :
|
||||||
|
llstr(m_part_info->part_expr->val_int(), buf));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulonglong value= m_part_info->part_expr->val_int();
|
||||||
|
longlong2str(value, buf, 10);
|
||||||
|
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_file[0]->print_error(error, errflag);
|
m_file[0]->print_error(error, errflag);
|
||||||
|
@ -36,15 +36,22 @@ enum partition_state {
|
|||||||
PART_IS_ADDED= 8
|
PART_IS_ADDED= 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct p_elem_val
|
||||||
|
{
|
||||||
|
longlong value;
|
||||||
|
bool null_value;
|
||||||
|
bool unsigned_flag;
|
||||||
|
} part_elem_value;
|
||||||
|
|
||||||
class partition_element :public Sql_alloc {
|
class partition_element :public Sql_alloc {
|
||||||
public:
|
public:
|
||||||
List<partition_element> subpartitions;
|
List<partition_element> subpartitions;
|
||||||
List<longlong> list_val_list;
|
List<part_elem_value> list_val_list;
|
||||||
ulonglong part_max_rows;
|
ulonglong part_max_rows;
|
||||||
ulonglong part_min_rows;
|
ulonglong part_min_rows;
|
||||||
|
longlong range_value;
|
||||||
char *partition_name;
|
char *partition_name;
|
||||||
char *tablespace_name;
|
char *tablespace_name;
|
||||||
longlong range_value;
|
|
||||||
char* part_comment;
|
char* part_comment;
|
||||||
char* data_file_name;
|
char* data_file_name;
|
||||||
char* index_file_name;
|
char* index_file_name;
|
||||||
@ -52,13 +59,16 @@ public:
|
|||||||
enum partition_state part_state;
|
enum partition_state part_state;
|
||||||
uint16 nodegroup_id;
|
uint16 nodegroup_id;
|
||||||
bool has_null_value;
|
bool has_null_value;
|
||||||
|
bool signed_flag;
|
||||||
|
bool max_value;
|
||||||
|
|
||||||
partition_element()
|
partition_element()
|
||||||
: part_max_rows(0), part_min_rows(0), partition_name(NULL),
|
: part_max_rows(0), part_min_rows(0), range_value(0),
|
||||||
tablespace_name(NULL), range_value(0), part_comment(NULL),
|
partition_name(NULL), tablespace_name(NULL), part_comment(NULL),
|
||||||
data_file_name(NULL), index_file_name(NULL),
|
data_file_name(NULL), index_file_name(NULL),
|
||||||
engine_type(NULL),part_state(PART_NORMAL),
|
engine_type(NULL), part_state(PART_NORMAL),
|
||||||
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE)
|
nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
|
||||||
|
signed_flag(FALSE), max_value(FALSE)
|
||||||
{
|
{
|
||||||
subpartitions.empty();
|
subpartitions.empty();
|
||||||
list_val_list.empty();
|
list_val_list.empty();
|
||||||
|
@ -445,10 +445,12 @@ bool partition_info::check_range_constants()
|
|||||||
{
|
{
|
||||||
partition_element* part_def;
|
partition_element* part_def;
|
||||||
longlong current_largest_int= LONGLONG_MIN;
|
longlong current_largest_int= LONGLONG_MIN;
|
||||||
|
ulonglong current_largest_uint= 0;
|
||||||
longlong part_range_value_int;
|
longlong part_range_value_int;
|
||||||
uint i;
|
uint i;
|
||||||
List_iterator<partition_element> it(partitions);
|
List_iterator<partition_element> it(partitions);
|
||||||
bool result= TRUE;
|
bool result= TRUE;
|
||||||
|
bool signed_flag= !part_expr->unsigned_flag;
|
||||||
DBUG_ENTER("partition_info::check_range_constants");
|
DBUG_ENTER("partition_info::check_range_constants");
|
||||||
DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
|
DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
|
||||||
|
|
||||||
@ -463,19 +465,40 @@ bool partition_info::check_range_constants()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
part_def= it++;
|
part_def= it++;
|
||||||
if ((i != (no_parts - 1)) || !defined_max_value)
|
if (signed_flag)
|
||||||
part_range_value_int= part_def->range_value;
|
|
||||||
else
|
|
||||||
part_range_value_int= LONGLONG_MAX;
|
|
||||||
if (likely(current_largest_int < part_range_value_int))
|
|
||||||
{
|
{
|
||||||
current_largest_int= part_range_value_int;
|
if ((i != (no_parts - 1)) || !defined_max_value)
|
||||||
range_int_array[i]= part_range_value_int;
|
part_range_value_int= part_def->range_value;
|
||||||
|
else
|
||||||
|
part_range_value_int= LONGLONG_MAX;
|
||||||
|
if (likely(current_largest_int < part_range_value_int))
|
||||||
|
{
|
||||||
|
current_largest_int= part_range_value_int;
|
||||||
|
range_int_array[i]= part_range_value_int;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
|
ulonglong upart_range_value_int;
|
||||||
goto end;
|
if ((i != (no_parts - 1)) || !defined_max_value)
|
||||||
|
upart_range_value_int= part_def->range_value;
|
||||||
|
else
|
||||||
|
upart_range_value_int= ULONGLONG_MAX;
|
||||||
|
if (likely(current_largest_uint < upart_range_value_int))
|
||||||
|
{
|
||||||
|
current_largest_uint= upart_range_value_int;
|
||||||
|
range_int_array[i]= part_range_value_int;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (++i < no_parts);
|
} while (++i < no_parts);
|
||||||
result= FALSE;
|
result= FALSE;
|
||||||
@ -485,8 +508,8 @@ end:
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A support routine for check_list_constants used by qsort to sort the
|
Support routines for check_list_constants used by qsort to sort the
|
||||||
constant list expressions.
|
constant list expressions. One routine for unsigned and one for signed.
|
||||||
|
|
||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
list_part_cmp()
|
list_part_cmp()
|
||||||
@ -511,6 +534,18 @@ int partition_info::list_part_cmp(const void* a, const void* b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int partition_info::list_part_cmp_unsigned(const void* a, const void* b)
|
||||||
|
{
|
||||||
|
ulonglong a1= ((LIST_PART_ENTRY*)a)->list_value;
|
||||||
|
ulonglong b1= ((LIST_PART_ENTRY*)b)->list_value;
|
||||||
|
if (a1 < b1)
|
||||||
|
return -1;
|
||||||
|
else if (a1 > b1)
|
||||||
|
return +1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This routine allocates an array for all list constants to achieve a fast
|
This routine allocates an array for all list constants to achieve a fast
|
||||||
@ -536,7 +571,7 @@ bool partition_info::check_list_constants()
|
|||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
uint list_index= 0;
|
uint list_index= 0;
|
||||||
longlong *list_value;
|
part_elem_value *list_value;
|
||||||
bool not_first;
|
bool not_first;
|
||||||
bool result= TRUE;
|
bool result= TRUE;
|
||||||
longlong curr_value, prev_value;
|
longlong curr_value, prev_value;
|
||||||
@ -577,7 +612,7 @@ bool partition_info::check_list_constants()
|
|||||||
has_null_part_id= i;
|
has_null_part_id= i;
|
||||||
found_null= TRUE;
|
found_null= TRUE;
|
||||||
}
|
}
|
||||||
List_iterator<longlong> list_val_it1(part_def->list_val_list);
|
List_iterator<part_elem_value> list_val_it1(part_def->list_val_list);
|
||||||
while (list_val_it1++)
|
while (list_val_it1++)
|
||||||
no_list_values++;
|
no_list_values++;
|
||||||
} while (++i < no_parts);
|
} while (++i < no_parts);
|
||||||
@ -593,33 +628,40 @@ bool partition_info::check_list_constants()
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
part_def= list_func_it++;
|
part_def= list_func_it++;
|
||||||
List_iterator<longlong> list_val_it2(part_def->list_val_list);
|
List_iterator<part_elem_value> list_val_it2(part_def->list_val_list);
|
||||||
while ((list_value= list_val_it2++))
|
while ((list_value= list_val_it2++))
|
||||||
{
|
{
|
||||||
list_array[list_index].list_value= *list_value;
|
list_array[list_index].list_value= list_value->value;
|
||||||
list_array[list_index++].partition_id= i;
|
list_array[list_index++].partition_id= i;
|
||||||
}
|
}
|
||||||
} while (++i < no_parts);
|
} while (++i < no_parts);
|
||||||
|
|
||||||
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
|
if (fixed)
|
||||||
&list_part_cmp);
|
|
||||||
|
|
||||||
not_first= FALSE;
|
|
||||||
i= prev_value= 0; //prev_value initialised to quiet compiler
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
curr_value= list_array[i].list_value;
|
if (!part_expr->unsigned_flag)
|
||||||
if (likely(!not_first || prev_value != curr_value))
|
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
|
||||||
{
|
&list_part_cmp);
|
||||||
prev_value= curr_value;
|
|
||||||
not_first= TRUE;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
|
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
|
||||||
|
&list_part_cmp_unsigned);
|
||||||
|
|
||||||
|
not_first= FALSE;
|
||||||
|
i= prev_value= 0; //prev_value initialised to quiet compiler
|
||||||
|
do
|
||||||
{
|
{
|
||||||
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
|
curr_value= list_array[i].list_value;
|
||||||
goto end;
|
if (likely(!not_first || prev_value != curr_value))
|
||||||
}
|
{
|
||||||
} while (++i < no_list_values);
|
prev_value= curr_value;
|
||||||
|
not_first= TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
} while (++i < no_list_values);
|
||||||
|
}
|
||||||
result= FALSE;
|
result= FALSE;
|
||||||
end:
|
end:
|
||||||
DBUG_RETURN(result);
|
DBUG_RETURN(result);
|
||||||
@ -647,7 +689,7 @@ end:
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool partition_info::check_partition_info(handlerton **eng_type,
|
bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
||||||
handler *file, ulonglong max_rows)
|
handler *file, ulonglong max_rows)
|
||||||
{
|
{
|
||||||
handlerton **engine_array= NULL;
|
handlerton **engine_array= NULL;
|
||||||
@ -733,9 +775,12 @@ bool partition_info::check_partition_info(handlerton **eng_type,
|
|||||||
list constants.
|
list constants.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
|
if (fixed)
|
||||||
(part_type == LIST_PARTITION && check_list_constants())))
|
{
|
||||||
goto end;
|
if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
|
||||||
|
(part_type == LIST_PARTITION && check_list_constants())))
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
result= FALSE;
|
result= FALSE;
|
||||||
end:
|
end:
|
||||||
my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
|
my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
|
||||||
|
@ -163,6 +163,7 @@ public:
|
|||||||
uint no_subpart_fields;
|
uint no_subpart_fields;
|
||||||
uint no_full_part_fields;
|
uint no_full_part_fields;
|
||||||
|
|
||||||
|
uint has_null_part_id;
|
||||||
/*
|
/*
|
||||||
This variable is used to calculate the partition id when using
|
This variable is used to calculate the partition id when using
|
||||||
LINEAR KEY/HASH. This functionality is kept in the MySQL Server
|
LINEAR KEY/HASH. This functionality is kept in the MySQL Server
|
||||||
@ -182,7 +183,6 @@ public:
|
|||||||
bool fixed;
|
bool fixed;
|
||||||
bool from_openfrm;
|
bool from_openfrm;
|
||||||
bool has_null_value;
|
bool has_null_value;
|
||||||
uint has_null_part_id;
|
|
||||||
|
|
||||||
|
|
||||||
partition_info()
|
partition_info()
|
||||||
@ -204,19 +204,13 @@ public:
|
|||||||
no_parts(0), no_subparts(0),
|
no_parts(0), no_subparts(0),
|
||||||
count_curr_subparts(0), part_error_code(0),
|
count_curr_subparts(0), part_error_code(0),
|
||||||
no_list_values(0), no_part_fields(0), no_subpart_fields(0),
|
no_list_values(0), no_part_fields(0), no_subpart_fields(0),
|
||||||
no_full_part_fields(0), linear_hash_mask(0),
|
no_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
|
||||||
use_default_partitions(TRUE),
|
use_default_partitions(TRUE), use_default_no_partitions(TRUE),
|
||||||
use_default_no_partitions(TRUE),
|
use_default_subpartitions(TRUE), use_default_no_subpartitions(TRUE),
|
||||||
use_default_subpartitions(TRUE),
|
default_partitions_setup(FALSE), defined_max_value(FALSE),
|
||||||
use_default_no_subpartitions(TRUE),
|
|
||||||
default_partitions_setup(FALSE),
|
|
||||||
defined_max_value(FALSE),
|
|
||||||
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
|
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
|
||||||
linear_hash_ind(FALSE),
|
linear_hash_ind(FALSE), fixed(FALSE), from_openfrm(FALSE),
|
||||||
fixed(FALSE),
|
has_null_value(FALSE)
|
||||||
from_openfrm(FALSE),
|
|
||||||
has_null_value(FALSE),
|
|
||||||
has_null_part_id(0)
|
|
||||||
{
|
{
|
||||||
all_fields_in_PF.clear_all();
|
all_fields_in_PF.clear_all();
|
||||||
all_fields_in_PPF.clear_all();
|
all_fields_in_PPF.clear_all();
|
||||||
@ -248,10 +242,11 @@ public:
|
|||||||
static bool check_engine_mix(handlerton **engine_array, uint no_parts);
|
static bool check_engine_mix(handlerton **engine_array, uint no_parts);
|
||||||
bool check_range_constants();
|
bool check_range_constants();
|
||||||
bool check_list_constants();
|
bool check_list_constants();
|
||||||
bool check_partition_info(handlerton **eng_type,
|
bool check_partition_info(THD *thd, handlerton **eng_type,
|
||||||
handler *file, ulonglong max_rows);
|
handler *file, ulonglong max_rows);
|
||||||
private:
|
private:
|
||||||
static int list_part_cmp(const void* a, const void* b);
|
static int list_part_cmp(const void* a, const void* b);
|
||||||
|
static int list_part_cmp_unsigned(const void* a, const void* b);
|
||||||
bool set_up_default_partitions(handler *file, ulonglong max_rows,
|
bool set_up_default_partitions(handler *file, ulonglong max_rows,
|
||||||
uint start_no);
|
uint start_no);
|
||||||
bool set_up_default_subpartitions(handler *file, ulonglong max_rows);
|
bool set_up_default_subpartitions(handler *file, ulonglong max_rows);
|
||||||
|
@ -5826,3 +5826,6 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
|
|||||||
eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
|
eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
|
||||||
ER_PARTITION_NO_TEMPORARY
|
ER_PARTITION_NO_TEMPORARY
|
||||||
eng "Cannot create temporary table with partitions"
|
eng "Cannot create temporary table with partitions"
|
||||||
|
ER_SIGNED_PARTITION_CONSTANT_ERROR
|
||||||
|
eng "Partition function is unsigned, cannot have negative constants"
|
||||||
|
swe "Partitionsfunktionen är positiv, kan inte ha negativa konstanter"
|
||||||
|
@ -61,7 +61,6 @@ static const char *equal_str= "=";
|
|||||||
static const char *end_paren_str= ")";
|
static const char *end_paren_str= ")";
|
||||||
static const char *begin_paren_str= "(";
|
static const char *begin_paren_str= "(";
|
||||||
static const char *comma_str= ",";
|
static const char *comma_str= ",";
|
||||||
static char buff[22];
|
|
||||||
|
|
||||||
int get_partition_id_list(partition_info *part_info,
|
int get_partition_id_list(partition_info *part_info,
|
||||||
uint32 *part_id,
|
uint32 *part_id,
|
||||||
@ -189,9 +188,9 @@ bool is_name_in_list(char *name,
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
partition_default_handling()
|
partition_default_handling()
|
||||||
table Table object
|
table Table object
|
||||||
table_name Table name to use when getting no_parts
|
|
||||||
db_name Database name to use when getting no_parts
|
|
||||||
part_info Partition info to set up
|
part_info Partition info to set up
|
||||||
|
is_create_table_ind Is this part of a table creation
|
||||||
|
normalized_path Normalized path name of table and database
|
||||||
|
|
||||||
RETURN VALUES
|
RETURN VALUES
|
||||||
TRUE Error
|
TRUE Error
|
||||||
@ -793,6 +792,43 @@ end:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Support function to check if all VALUES * (expression) is of the
|
||||||
|
right sign (no signed constants when unsigned partition function)
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
check_signed_flag()
|
||||||
|
part_info Partition info object
|
||||||
|
|
||||||
|
RETURN VALUES
|
||||||
|
0 No errors due to sign errors
|
||||||
|
>0 Sign error
|
||||||
|
*/
|
||||||
|
|
||||||
|
int check_signed_flag(partition_info *part_info)
|
||||||
|
{
|
||||||
|
int error= 0;
|
||||||
|
uint i= 0;
|
||||||
|
if (part_info->part_type != HASH_PARTITION &&
|
||||||
|
part_info->part_expr->unsigned_flag)
|
||||||
|
{
|
||||||
|
List_iterator<partition_element> part_it(part_info->partitions);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
partition_element *part_elem= part_it++;
|
||||||
|
|
||||||
|
if (part_elem->signed_flag)
|
||||||
|
{
|
||||||
|
my_error(ER_SIGNED_PARTITION_CONSTANT_ERROR, MYF(0));
|
||||||
|
error= ER_SIGNED_PARTITION_CONSTANT_ERROR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (++i < part_info->no_parts);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The function uses a new feature in fix_fields where the flag
|
The function uses a new feature in fix_fields where the flag
|
||||||
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
|
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
|
||||||
@ -802,10 +838,11 @@ end:
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
fix_fields_part_func()
|
fix_fields_part_func()
|
||||||
thd The thread object
|
thd The thread object
|
||||||
tables A list of one table, the partitioned table
|
|
||||||
func_expr The item tree reference of the partition function
|
func_expr The item tree reference of the partition function
|
||||||
|
table The table object
|
||||||
part_info Reference to partitioning data structure
|
part_info Reference to partitioning data structure
|
||||||
sub_part Is the table subpartitioned as well
|
sub_part Is the table subpartitioned as well
|
||||||
|
set_up_fields Flag if we are to set-up field arrays
|
||||||
|
|
||||||
RETURN VALUE
|
RETURN VALUE
|
||||||
TRUE An error occurred, something was wrong with the
|
TRUE An error occurred, something was wrong with the
|
||||||
@ -828,26 +865,54 @@ end:
|
|||||||
on the field object.
|
on the field object.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
|
bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||||
Item* func_expr, partition_info *part_info,
|
bool is_sub_part, bool is_field_to_be_setup)
|
||||||
bool is_sub_part)
|
|
||||||
{
|
{
|
||||||
|
partition_info *part_info= table->part_info;
|
||||||
|
uint dir_length, home_dir_length;
|
||||||
bool result= TRUE;
|
bool result= TRUE;
|
||||||
TABLE *table= tables->table;
|
TABLE_LIST tables;
|
||||||
TABLE_LIST *save_table_list, *save_first_table, *save_last_table;
|
TABLE_LIST *save_table_list, *save_first_table, *save_last_table;
|
||||||
int error;
|
int error;
|
||||||
Name_resolution_context *context;
|
Name_resolution_context *context;
|
||||||
const char *save_where;
|
const char *save_where;
|
||||||
|
char* db_name;
|
||||||
|
char db_name_string[FN_REFLEN];
|
||||||
DBUG_ENTER("fix_fields_part_func");
|
DBUG_ENTER("fix_fields_part_func");
|
||||||
|
|
||||||
|
if (part_info->fixed)
|
||||||
|
{
|
||||||
|
if (!(is_sub_part || (error= check_signed_flag(part_info))))
|
||||||
|
result= FALSE;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Set-up the TABLE_LIST object to be a list with a single table
|
||||||
|
Set the object to zero to create NULL pointers and set alias
|
||||||
|
and real name to table name and get database name from file name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bzero((void*)&tables, sizeof(TABLE_LIST));
|
||||||
|
tables.alias= tables.table_name= (char*) table->s->table_name.str;
|
||||||
|
tables.table= table;
|
||||||
|
tables.next_local= 0;
|
||||||
|
tables.next_name_resolution_table= 0;
|
||||||
|
strmov(db_name_string, table->s->normalized_path.str);
|
||||||
|
dir_length= dirname_length(db_name_string);
|
||||||
|
db_name_string[dir_length - 1]= 0;
|
||||||
|
home_dir_length= dirname_length(db_name_string);
|
||||||
|
db_name= &db_name_string[home_dir_length];
|
||||||
|
tables.db= db_name;
|
||||||
|
|
||||||
context= thd->lex->current_context();
|
context= thd->lex->current_context();
|
||||||
table->map= 1; //To ensure correct calculation of const item
|
table->map= 1; //To ensure correct calculation of const item
|
||||||
table->get_fields_in_item_tree= TRUE;
|
table->get_fields_in_item_tree= TRUE;
|
||||||
save_table_list= context->table_list;
|
save_table_list= context->table_list;
|
||||||
save_first_table= context->first_name_resolution_table;
|
save_first_table= context->first_name_resolution_table;
|
||||||
save_last_table= context->last_name_resolution_table;
|
save_last_table= context->last_name_resolution_table;
|
||||||
context->table_list= tables;
|
context->table_list= &tables;
|
||||||
context->first_name_resolution_table= tables;
|
context->first_name_resolution_table= &tables;
|
||||||
context->last_name_resolution_table= NULL;
|
context->last_name_resolution_table= NULL;
|
||||||
func_expr->walk(&Item::change_context_processor, (byte*) context);
|
func_expr->walk(&Item::change_context_processor, (byte*) context);
|
||||||
save_where= thd->where;
|
save_where= thd->where;
|
||||||
@ -859,7 +924,8 @@ static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
|
|||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
{
|
{
|
||||||
DBUG_PRINT("info", ("Field in partition function not part of table"));
|
DBUG_PRINT("info", ("Field in partition function not part of table"));
|
||||||
clear_field_flag(table);
|
if (is_field_to_be_setup)
|
||||||
|
clear_field_flag(table);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
@ -869,7 +935,13 @@ static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
|
|||||||
clear_field_flag(table);
|
clear_field_flag(table);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
result= set_up_field_array(table, is_sub_part);
|
if ((!is_sub_part) && (error= check_signed_flag(part_info)))
|
||||||
|
goto end;
|
||||||
|
result= FALSE;
|
||||||
|
if (is_field_to_be_setup)
|
||||||
|
result= set_up_field_array(table, is_sub_part);
|
||||||
|
if (!is_sub_part)
|
||||||
|
part_info->fixed= TRUE;
|
||||||
end:
|
end:
|
||||||
table->get_fields_in_item_tree= FALSE;
|
table->get_fields_in_item_tree= FALSE;
|
||||||
table->map= 0; //Restore old value
|
table->map= 0; //Restore old value
|
||||||
@ -1303,7 +1375,6 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
|
|||||||
SYNOPSIS
|
SYNOPSIS
|
||||||
fix_partition_func()
|
fix_partition_func()
|
||||||
thd The thread object
|
thd The thread object
|
||||||
name The name of the partitioned table
|
|
||||||
table TABLE object for which partition fields are set-up
|
table TABLE object for which partition fields are set-up
|
||||||
create_table_ind Indicator of whether openfrm was called as part of
|
create_table_ind Indicator of whether openfrm was called as part of
|
||||||
CREATE or ALTER TABLE
|
CREATE or ALTER TABLE
|
||||||
@ -1325,15 +1396,10 @@ NOTES
|
|||||||
of an error that is not discovered until here.
|
of an error that is not discovered until here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
bool fix_partition_func(THD *thd, TABLE *table,
|
||||||
bool is_create_table_ind)
|
bool is_create_table_ind)
|
||||||
{
|
{
|
||||||
bool result= TRUE;
|
bool result= TRUE;
|
||||||
uint dir_length, home_dir_length;
|
|
||||||
TABLE_LIST tables;
|
|
||||||
TABLE_SHARE *share= table->s;
|
|
||||||
char db_name_string[FN_REFLEN];
|
|
||||||
char* db_name;
|
|
||||||
partition_info *part_info= table->part_info;
|
partition_info *part_info= table->part_info;
|
||||||
ulong save_set_query_id= thd->set_query_id;
|
ulong save_set_query_id= thd->set_query_id;
|
||||||
Item *thd_free_list= thd->free_list;
|
Item *thd_free_list= thd->free_list;
|
||||||
@ -1345,23 +1411,6 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
}
|
}
|
||||||
thd->set_query_id= 0;
|
thd->set_query_id= 0;
|
||||||
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
|
DBUG_PRINT("info", ("thd->set_query_id: %d", thd->set_query_id));
|
||||||
/*
|
|
||||||
Set-up the TABLE_LIST object to be a list with a single table
|
|
||||||
Set the object to zero to create NULL pointers and set alias
|
|
||||||
and real name to table name and get database name from file name.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bzero((void*)&tables, sizeof(TABLE_LIST));
|
|
||||||
tables.alias= tables.table_name= (char*) share->table_name.str;
|
|
||||||
tables.table= table;
|
|
||||||
tables.next_local= 0;
|
|
||||||
tables.next_name_resolution_table= 0;
|
|
||||||
strmov(db_name_string, name);
|
|
||||||
dir_length= dirname_length(db_name_string);
|
|
||||||
db_name_string[dir_length - 1]= 0;
|
|
||||||
home_dir_length= dirname_length(db_name_string);
|
|
||||||
db_name= &db_name_string[home_dir_length];
|
|
||||||
tables.db= db_name;
|
|
||||||
|
|
||||||
if (!is_create_table_ind ||
|
if (!is_create_table_ind ||
|
||||||
thd->lex->sql_command != SQLCOM_CREATE_TABLE)
|
thd->lex->sql_command != SQLCOM_CREATE_TABLE)
|
||||||
@ -1391,9 +1440,8 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (unlikely(fix_fields_part_func(thd, &tables,
|
if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
|
||||||
part_info->subpart_expr, part_info,
|
table, TRUE, TRUE)))
|
||||||
TRUE)))
|
|
||||||
goto end;
|
goto end;
|
||||||
if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
|
if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
|
||||||
{
|
{
|
||||||
@ -1420,8 +1468,8 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (unlikely(fix_fields_part_func(thd, &tables, part_info->part_expr,
|
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
|
||||||
part_info, FALSE)))
|
table, FALSE, TRUE)))
|
||||||
goto end;
|
goto end;
|
||||||
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
|
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
|
||||||
{
|
{
|
||||||
@ -1434,6 +1482,9 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
const char *error_str;
|
const char *error_str;
|
||||||
|
if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
|
||||||
|
table, FALSE, TRUE)))
|
||||||
|
goto end;
|
||||||
if (part_info->part_type == RANGE_PARTITION)
|
if (part_info->part_type == RANGE_PARTITION)
|
||||||
{
|
{
|
||||||
error_str= partition_keywords[PKW_RANGE].str;
|
error_str= partition_keywords[PKW_RANGE].str;
|
||||||
@ -1457,9 +1508,6 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_str);
|
my_error(ER_PARTITIONS_MUST_BE_DEFINED_ERROR, MYF(0), error_str);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (unlikely(fix_fields_part_func(thd, &tables, part_info->part_expr,
|
|
||||||
part_info, FALSE)))
|
|
||||||
goto end;
|
|
||||||
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
|
if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
|
||||||
{
|
{
|
||||||
my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), part_str);
|
my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), part_str);
|
||||||
@ -1479,7 +1527,6 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
|
|||||||
check_range_capable_PF(table);
|
check_range_capable_PF(table);
|
||||||
set_up_partition_key_maps(table, part_info);
|
set_up_partition_key_maps(table, part_info);
|
||||||
set_up_partition_func_pointers(part_info);
|
set_up_partition_func_pointers(part_info);
|
||||||
part_info->fixed= TRUE;
|
|
||||||
set_up_range_analysis_info(part_info);
|
set_up_range_analysis_info(part_info);
|
||||||
result= FALSE;
|
result= FALSE;
|
||||||
end:
|
end:
|
||||||
@ -1563,6 +1610,7 @@ static int add_hash(File fptr)
|
|||||||
|
|
||||||
static int add_partition(File fptr)
|
static int add_partition(File fptr)
|
||||||
{
|
{
|
||||||
|
char buff[22];
|
||||||
strxmov(buff, part_str, space_str, NullS);
|
strxmov(buff, part_str, space_str, NullS);
|
||||||
return add_string(fptr, buff);
|
return add_string(fptr, buff);
|
||||||
}
|
}
|
||||||
@ -1576,6 +1624,7 @@ static int add_subpartition(File fptr)
|
|||||||
|
|
||||||
static int add_partition_by(File fptr)
|
static int add_partition_by(File fptr)
|
||||||
{
|
{
|
||||||
|
char buff[22];
|
||||||
strxmov(buff, part_str, space_str, by_str, space_str, NullS);
|
strxmov(buff, part_str, space_str, by_str, space_str, NullS);
|
||||||
return add_string(fptr, buff);
|
return add_string(fptr, buff);
|
||||||
}
|
}
|
||||||
@ -1616,10 +1665,18 @@ static int add_key_partition(File fptr, List<char> field_list)
|
|||||||
|
|
||||||
static int add_int(File fptr, longlong number)
|
static int add_int(File fptr, longlong number)
|
||||||
{
|
{
|
||||||
|
char buff[32];
|
||||||
llstr(number, buff);
|
llstr(number, buff);
|
||||||
return add_string(fptr, buff);
|
return add_string(fptr, buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_uint(File fptr, ulonglong number)
|
||||||
|
{
|
||||||
|
char buff[32];
|
||||||
|
longlong2str(number, buff, 10);
|
||||||
|
return add_string(fptr, buff);
|
||||||
|
}
|
||||||
|
|
||||||
static int add_keyword_string(File fptr, const char *keyword,
|
static int add_keyword_string(File fptr, const char *keyword,
|
||||||
bool should_use_quotes,
|
bool should_use_quotes,
|
||||||
const char *keystr)
|
const char *keystr)
|
||||||
@ -1681,28 +1738,43 @@ static int add_partition_options(File fptr, partition_element *p_elem)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int add_partition_values(File fptr, partition_info *part_info,
|
static int add_partition_values(File fptr, partition_info *part_info,
|
||||||
partition_element *p_elem)
|
partition_element *p_elem)
|
||||||
{
|
{
|
||||||
int err= 0;
|
int err= 0;
|
||||||
|
|
||||||
if (part_info->part_type == RANGE_PARTITION)
|
if (part_info->part_type == RANGE_PARTITION)
|
||||||
{
|
{
|
||||||
err+= add_string(fptr, "VALUES LESS THAN ");
|
err+= add_string(fptr, "VALUES LESS THAN ");
|
||||||
if (p_elem->range_value != LONGLONG_MAX)
|
if (p_elem->signed_flag)
|
||||||
{
|
{
|
||||||
err+= add_begin_parenthesis(fptr);
|
if (!p_elem->max_value)
|
||||||
err+= add_int(fptr, p_elem->range_value);
|
{
|
||||||
err+= add_end_parenthesis(fptr);
|
err+= add_begin_parenthesis(fptr);
|
||||||
|
err+= add_int(fptr, p_elem->range_value);
|
||||||
|
err+= add_end_parenthesis(fptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
|
{
|
||||||
|
if (!p_elem->max_value)
|
||||||
|
{
|
||||||
|
err+= add_begin_parenthesis(fptr);
|
||||||
|
err+= add_uint(fptr, (ulonglong)p_elem->range_value);
|
||||||
|
err+= add_end_parenthesis(fptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (part_info->part_type == LIST_PARTITION)
|
else if (part_info->part_type == LIST_PARTITION)
|
||||||
{
|
{
|
||||||
uint i;
|
uint i;
|
||||||
List_iterator<longlong> list_val_it(p_elem->list_val_list);
|
List_iterator<part_elem_value> list_val_it(p_elem->list_val_list);
|
||||||
err+= add_string(fptr, "VALUES IN ");
|
err+= add_string(fptr, "VALUES IN ");
|
||||||
uint no_items= p_elem->list_val_list.elements;
|
uint no_items= p_elem->list_val_list.elements;
|
||||||
|
|
||||||
err+= add_begin_parenthesis(fptr);
|
err+= add_begin_parenthesis(fptr);
|
||||||
if (p_elem->has_null_value)
|
if (p_elem->has_null_value)
|
||||||
{
|
{
|
||||||
@ -1717,8 +1789,12 @@ static int add_partition_values(File fptr, partition_info *part_info,
|
|||||||
i= 0;
|
i= 0;
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
longlong *list_value= list_val_it++;
|
part_elem_value *list_value= list_val_it++;
|
||||||
err+= add_int(fptr, *list_value);
|
|
||||||
|
if (!list_value->unsigned_flag)
|
||||||
|
err+= add_int(fptr, list_value->value);
|
||||||
|
else
|
||||||
|
err+= add_uint(fptr, list_value->value);
|
||||||
if (i != (no_items-1))
|
if (i != (no_items-1))
|
||||||
err+= add_comma(fptr);
|
err+= add_comma(fptr);
|
||||||
} while (++i < no_items);
|
} while (++i < no_items);
|
||||||
@ -2294,15 +2370,15 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
|
|||||||
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
LIST_PART_ENTRY *list_array= part_info->list_array;
|
LIST_PART_ENTRY *list_array= part_info->list_array;
|
||||||
int list_index;
|
int list_index;
|
||||||
longlong list_value;
|
|
||||||
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= part_val_int(part_info->part_expr);
|
||||||
|
bool unsigned_flag= part_info->part_expr->unsigned_flag;
|
||||||
DBUG_ENTER("get_partition_id_list");
|
DBUG_ENTER("get_partition_id_list");
|
||||||
|
|
||||||
if (part_info->part_expr->null_value)
|
if (part_info->part_expr->null_value)
|
||||||
@ -2315,22 +2391,49 @@ int get_partition_id_list(partition_info *part_info,
|
|||||||
goto notfound;
|
goto notfound;
|
||||||
}
|
}
|
||||||
*func_value= part_func_value;
|
*func_value= part_func_value;
|
||||||
while (max_list_index >= min_list_index)
|
if (!unsigned_flag)
|
||||||
{
|
{
|
||||||
list_index= (max_list_index + min_list_index) >> 1;
|
longlong list_value;
|
||||||
list_value= list_array[list_index].list_value;
|
while (max_list_index >= min_list_index)
|
||||||
if (list_value < part_func_value)
|
|
||||||
min_list_index= list_index + 1;
|
|
||||||
else if (list_value > part_func_value)
|
|
||||||
{
|
{
|
||||||
if (!list_index)
|
list_index= (max_list_index + min_list_index) >> 1;
|
||||||
goto notfound;
|
list_value= list_array[list_index].list_value;
|
||||||
max_list_index= list_index - 1;
|
if (list_value < part_func_value)
|
||||||
|
min_list_index= list_index + 1;
|
||||||
|
else if (list_value > part_func_value)
|
||||||
|
{
|
||||||
|
if (!list_index)
|
||||||
|
goto notfound;
|
||||||
|
max_list_index= list_index - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*part_id= (uint32)list_array[list_index].partition_id;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulonglong ulist_value;
|
||||||
|
ulonglong upart_func_value= part_func_value;
|
||||||
|
while (max_list_index >= min_list_index)
|
||||||
{
|
{
|
||||||
*part_id= (uint32)list_array[list_index].partition_id;
|
list_index= (max_list_index + min_list_index) >> 1;
|
||||||
DBUG_RETURN(0);
|
ulist_value= list_array[list_index].list_value;
|
||||||
|
if (ulist_value < upart_func_value)
|
||||||
|
min_list_index= list_index + 1;
|
||||||
|
else if (ulist_value > upart_func_value)
|
||||||
|
{
|
||||||
|
if (!list_index)
|
||||||
|
goto notfound;
|
||||||
|
max_list_index= list_index - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*part_id= (uint32)list_array[list_index].partition_id;
|
||||||
|
DBUG_RETURN(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
notfound:
|
notfound:
|
||||||
@ -2381,34 +2484,65 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
|
|||||||
bool left_endpoint,
|
bool left_endpoint,
|
||||||
bool include_endpoint)
|
bool include_endpoint)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("get_list_array_idx_for_endpoint");
|
|
||||||
LIST_PART_ENTRY *list_array= part_info->list_array;
|
LIST_PART_ENTRY *list_array= part_info->list_array;
|
||||||
uint list_index;
|
uint list_index;
|
||||||
longlong list_value;
|
|
||||||
uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
|
uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
|
||||||
/* Get the partitioning function value for the endpoint */
|
/* Get the partitioning function value for the endpoint */
|
||||||
longlong part_func_value= part_val_int(part_info->part_expr);
|
longlong part_func_value= part_val_int(part_info->part_expr);
|
||||||
while (max_list_index >= min_list_index)
|
bool unsigned_flag= part_info->part_expr->unsigned_flag;
|
||||||
|
DBUG_ENTER("get_list_array_idx_for_endpoint");
|
||||||
|
|
||||||
|
if (!unsigned_flag)
|
||||||
{
|
{
|
||||||
list_index= (max_list_index + min_list_index) >> 1;
|
longlong list_value;
|
||||||
list_value= list_array[list_index].list_value;
|
while (max_list_index >= min_list_index)
|
||||||
|
{
|
||||||
|
list_index= (max_list_index + min_list_index) >> 1;
|
||||||
|
list_value= list_array[list_index].list_value;
|
||||||
|
if (list_value < part_func_value)
|
||||||
|
min_list_index= list_index + 1;
|
||||||
|
else if (list_value > part_func_value)
|
||||||
|
{
|
||||||
|
if (!list_index)
|
||||||
|
goto notfound_signed;
|
||||||
|
max_list_index= list_index - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notfound_signed:
|
||||||
if (list_value < part_func_value)
|
if (list_value < part_func_value)
|
||||||
min_list_index= list_index + 1;
|
list_index++;
|
||||||
else if (list_value > part_func_value)
|
DBUG_RETURN(list_index);
|
||||||
{
|
}
|
||||||
if (!list_index)
|
else
|
||||||
goto notfound;
|
{
|
||||||
max_list_index= list_index - 1;
|
ulonglong upart_func_value= part_func_value;
|
||||||
}
|
ulonglong ulist_value;
|
||||||
else
|
while (max_list_index >= min_list_index)
|
||||||
{
|
{
|
||||||
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
|
list_index= (max_list_index + min_list_index) >> 1;
|
||||||
}
|
ulist_value= list_array[list_index].list_value;
|
||||||
|
if (ulist_value < upart_func_value)
|
||||||
|
min_list_index= list_index + 1;
|
||||||
|
else if (ulist_value > upart_func_value)
|
||||||
|
{
|
||||||
|
if (!list_index)
|
||||||
|
goto notfound_unsigned;
|
||||||
|
max_list_index= list_index - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DBUG_RETURN(list_index + test(left_endpoint ^ include_endpoint));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
notfound_unsigned:
|
||||||
|
if (ulist_value < upart_func_value)
|
||||||
|
list_index++;
|
||||||
|
DBUG_RETURN(list_index);
|
||||||
}
|
}
|
||||||
notfound:
|
|
||||||
if (list_value < part_func_value)
|
|
||||||
list_index++;
|
|
||||||
DBUG_RETURN(list_index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2422,6 +2556,7 @@ int get_partition_id_range(partition_info *part_info,
|
|||||||
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= part_val_int(part_info->part_expr);
|
||||||
|
bool unsigned_flag= part_info->part_expr->unsigned_flag;
|
||||||
DBUG_ENTER("get_partition_id_int_range");
|
DBUG_ENTER("get_partition_id_int_range");
|
||||||
|
|
||||||
if (part_info->part_expr->null_value)
|
if (part_info->part_expr->null_value)
|
||||||
@ -2429,24 +2564,52 @@ int get_partition_id_range(partition_info *part_info,
|
|||||||
*part_id= 0;
|
*part_id= 0;
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
while (max_part_id > min_part_id)
|
|
||||||
{
|
|
||||||
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
|
||||||
if (range_array[loc_part_id] <= part_func_value)
|
|
||||||
min_part_id= loc_part_id + 1;
|
|
||||||
else
|
|
||||||
max_part_id= loc_part_id - 1;
|
|
||||||
}
|
|
||||||
loc_part_id= max_part_id;
|
|
||||||
if (part_func_value >= range_array[loc_part_id])
|
|
||||||
if (loc_part_id != max_partition)
|
|
||||||
loc_part_id++;
|
|
||||||
*part_id= (uint32)loc_part_id;
|
|
||||||
*func_value= part_func_value;
|
*func_value= part_func_value;
|
||||||
if (loc_part_id == max_partition)
|
if (!unsigned_flag)
|
||||||
if (range_array[loc_part_id] != LONGLONG_MAX)
|
{
|
||||||
if (part_func_value >= range_array[loc_part_id])
|
while (max_part_id > min_part_id)
|
||||||
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
|
{
|
||||||
|
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
||||||
|
if (range_array[loc_part_id] <= part_func_value)
|
||||||
|
min_part_id= loc_part_id + 1;
|
||||||
|
else
|
||||||
|
max_part_id= loc_part_id - 1;
|
||||||
|
}
|
||||||
|
loc_part_id= max_part_id;
|
||||||
|
if (part_func_value >= range_array[loc_part_id])
|
||||||
|
if (loc_part_id != max_partition)
|
||||||
|
loc_part_id++;
|
||||||
|
*part_id= (uint32)loc_part_id;
|
||||||
|
if (loc_part_id == max_partition)
|
||||||
|
if (range_array[loc_part_id] != LONGLONG_MAX)
|
||||||
|
if (part_func_value >= range_array[loc_part_id])
|
||||||
|
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ulonglong upart_func_value= part_func_value;
|
||||||
|
ulonglong urange_value;
|
||||||
|
while (max_part_id > min_part_id)
|
||||||
|
{
|
||||||
|
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (urange_value <= upart_func_value)
|
||||||
|
min_part_id= loc_part_id + 1;
|
||||||
|
else
|
||||||
|
max_part_id= loc_part_id - 1;
|
||||||
|
}
|
||||||
|
loc_part_id= max_part_id;
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (upart_func_value >= urange_value)
|
||||||
|
if (loc_part_id != max_partition)
|
||||||
|
loc_part_id++;
|
||||||
|
*part_id= (uint32)loc_part_id;
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (loc_part_id == max_partition)
|
||||||
|
if (urange_value != ULONGLONG_MAX)
|
||||||
|
if (upart_func_value >= urange_value)
|
||||||
|
DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
|
||||||
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2496,39 +2659,79 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
|||||||
bool left_endpoint,
|
bool left_endpoint,
|
||||||
bool include_endpoint)
|
bool include_endpoint)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("get_partition_id_range_for_endpoint");
|
|
||||||
longlong *range_array= part_info->range_int_array;
|
longlong *range_array= part_info->range_int_array;
|
||||||
uint max_partition= part_info->no_parts - 1;
|
uint max_partition= part_info->no_parts - 1;
|
||||||
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
|
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
|
||||||
/* Get the partitioning function value for the endpoint */
|
/* Get the partitioning function value for the endpoint */
|
||||||
longlong part_func_value= part_val_int(part_info->part_expr);
|
longlong part_func_value= part_val_int(part_info->part_expr);
|
||||||
|
bool unsigned_flag= part_info->part_expr->unsigned_flag;
|
||||||
|
DBUG_ENTER("get_partition_id_range_for_endpoint");
|
||||||
|
|
||||||
while (max_part_id > min_part_id)
|
if (!unsigned_flag)
|
||||||
{
|
{
|
||||||
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
while (max_part_id > min_part_id)
|
||||||
if (range_array[loc_part_id] <= part_func_value)
|
{
|
||||||
min_part_id= loc_part_id + 1;
|
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
||||||
else
|
if (range_array[loc_part_id] <= part_func_value)
|
||||||
max_part_id= loc_part_id - 1;
|
min_part_id= loc_part_id + 1;
|
||||||
}
|
else
|
||||||
loc_part_id= max_part_id;
|
max_part_id= loc_part_id - 1;
|
||||||
if (loc_part_id < max_partition &&
|
}
|
||||||
part_func_value >= range_array[loc_part_id+1])
|
loc_part_id= max_part_id;
|
||||||
{
|
if (loc_part_id < max_partition &&
|
||||||
loc_part_id++;
|
part_func_value >= range_array[loc_part_id+1])
|
||||||
}
|
{
|
||||||
if (left_endpoint)
|
loc_part_id++;
|
||||||
{
|
}
|
||||||
if (part_func_value >= range_array[loc_part_id])
|
if (left_endpoint)
|
||||||
|
{
|
||||||
|
if (part_func_value >= range_array[loc_part_id])
|
||||||
|
loc_part_id++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (part_func_value == range_array[loc_part_id])
|
||||||
|
loc_part_id += test(include_endpoint);
|
||||||
|
else if (part_func_value > range_array[loc_part_id])
|
||||||
|
loc_part_id++;
|
||||||
loc_part_id++;
|
loc_part_id++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (part_func_value == range_array[loc_part_id])
|
ulonglong upart_func_value= part_func_value;
|
||||||
loc_part_id += test(include_endpoint);
|
ulonglong urange_value;
|
||||||
else if (part_func_value > range_array[loc_part_id])
|
while (max_part_id > min_part_id)
|
||||||
|
{
|
||||||
|
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (urange_value <= upart_func_value)
|
||||||
|
min_part_id= loc_part_id + 1;
|
||||||
|
else
|
||||||
|
max_part_id= loc_part_id - 1;
|
||||||
|
}
|
||||||
|
loc_part_id= max_part_id;
|
||||||
|
urange_value= range_array[loc_part_id+1];
|
||||||
|
if (loc_part_id < max_partition &&
|
||||||
|
upart_func_value >= urange_value)
|
||||||
|
{
|
||||||
|
loc_part_id++;
|
||||||
|
}
|
||||||
|
if (left_endpoint)
|
||||||
|
{
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (upart_func_value >= urange_value)
|
||||||
|
loc_part_id++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
urange_value= range_array[loc_part_id];
|
||||||
|
if (upart_func_value == urange_value)
|
||||||
|
loc_part_id += test(include_endpoint);
|
||||||
|
else if (upart_func_value > urange_value)
|
||||||
|
loc_part_id++;
|
||||||
loc_part_id++;
|
loc_part_id++;
|
||||||
loc_part_id++;
|
}
|
||||||
}
|
}
|
||||||
DBUG_RETURN(loc_part_id);
|
DBUG_RETURN(loc_part_id);
|
||||||
}
|
}
|
||||||
@ -4497,8 +4700,8 @@ the generated partition syntax in a correct manner.
|
|||||||
tab_part_info->use_default_subpartitions= FALSE;
|
tab_part_info->use_default_subpartitions= FALSE;
|
||||||
tab_part_info->use_default_no_subpartitions= FALSE;
|
tab_part_info->use_default_no_subpartitions= FALSE;
|
||||||
}
|
}
|
||||||
if (tab_part_info->check_partition_info((handlerton**)NULL,
|
if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
|
||||||
table->file, ULL(0)))
|
table->file, ULL(0)))
|
||||||
{
|
{
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
}
|
}
|
||||||
|
@ -65,9 +65,8 @@ int get_part_for_delete(const byte *buf, const byte *rec0,
|
|||||||
partition_info *part_info, uint32 *part_id);
|
partition_info *part_info, uint32 *part_id);
|
||||||
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
|
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
|
||||||
bool check_partition_info(partition_info *part_info,handlerton **eng_type,
|
bool check_partition_info(partition_info *part_info,handlerton **eng_type,
|
||||||
handler *file, ulonglong max_rows);
|
TABLE *table, handler *file, ulonglong max_rows);
|
||||||
bool fix_partition_func(THD *thd, const char *name, TABLE *table,
|
bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind);
|
||||||
bool create_table_ind);
|
|
||||||
char *generate_partition_syntax(partition_info *part_info,
|
char *generate_partition_syntax(partition_info *part_info,
|
||||||
uint *buf_length, bool use_sql_alloc,
|
uint *buf_length, bool use_sql_alloc,
|
||||||
bool write_all);
|
bool write_all);
|
||||||
@ -91,6 +90,8 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
|
|||||||
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
|
||||||
bool left_endpoint,
|
bool left_endpoint,
|
||||||
bool include_endpoint);
|
bool include_endpoint);
|
||||||
|
bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||||
|
bool is_sub_part, bool is_field_to_be_setup);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A "Get next" function for partition iterator.
|
A "Get next" function for partition iterator.
|
||||||
|
@ -3851,8 +3851,8 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
|
|||||||
}
|
}
|
||||||
else if (part_info->part_type == LIST_PARTITION)
|
else if (part_info->part_type == LIST_PARTITION)
|
||||||
{
|
{
|
||||||
List_iterator<longlong> list_val_it(part_elem->list_val_list);
|
List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
|
||||||
longlong *list_value;
|
part_elem_value *list_value;
|
||||||
uint no_items= part_elem->list_val_list.elements;
|
uint no_items= part_elem->list_val_list.elements;
|
||||||
tmp_str.length(0);
|
tmp_str.length(0);
|
||||||
tmp_res.length(0);
|
tmp_res.length(0);
|
||||||
@ -3864,7 +3864,10 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
|
|||||||
}
|
}
|
||||||
while ((list_value= list_val_it++))
|
while ((list_value= list_val_it++))
|
||||||
{
|
{
|
||||||
tmp_res.set(*list_value, cs);
|
if (!list_value->unsigned_flag)
|
||||||
|
tmp_res.set(list_value->value, cs);
|
||||||
|
else
|
||||||
|
tmp_res.set((ulonglong)list_value->value, cs);
|
||||||
tmp_str.append(tmp_res);
|
tmp_str.append(tmp_res);
|
||||||
if (--no_items != 0)
|
if (--no_items != 0)
|
||||||
tmp_str.append(",");
|
tmp_str.append(",");
|
||||||
|
@ -2141,8 +2141,8 @@ bool mysql_create_table_internal(THD *thd,
|
|||||||
}
|
}
|
||||||
DBUG_PRINT("info", ("db_type = %d",
|
DBUG_PRINT("info", ("db_type = %d",
|
||||||
ha_legacy_type(part_info->default_engine_type)));
|
ha_legacy_type(part_info->default_engine_type)));
|
||||||
if (part_info->check_partition_info( &engine_type, file,
|
if (part_info->check_partition_info(thd, &engine_type, file,
|
||||||
create_info->max_rows))
|
create_info->max_rows))
|
||||||
goto err;
|
goto err;
|
||||||
part_info->default_engine_type= engine_type;
|
part_info->default_engine_type= engine_type;
|
||||||
|
|
||||||
|
@ -42,12 +42,6 @@
|
|||||||
#include <myisam.h>
|
#include <myisam.h>
|
||||||
#include <myisammrg.h>
|
#include <myisammrg.h>
|
||||||
|
|
||||||
typedef struct p_elem_val
|
|
||||||
{
|
|
||||||
longlong value;
|
|
||||||
bool null_value;
|
|
||||||
} part_elem_value;
|
|
||||||
|
|
||||||
int yylex(void *yylval, void *yythd);
|
int yylex(void *yylval, void *yythd);
|
||||||
|
|
||||||
const LEX_STRING null_lex_str={0,0};
|
const LEX_STRING null_lex_str={0,0};
|
||||||
@ -3712,6 +3706,7 @@ part_func_max:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
lex->part_info->defined_max_value= TRUE;
|
lex->part_info->defined_max_value= TRUE;
|
||||||
|
lex->part_info->curr_part_elem->max_value= TRUE;
|
||||||
lex->part_info->curr_part_elem->range_value= LONGLONG_MAX;
|
lex->part_info->curr_part_elem->range_value= LONGLONG_MAX;
|
||||||
}
|
}
|
||||||
| part_range_func
|
| part_range_func
|
||||||
@ -3727,7 +3722,10 @@ part_func_max:
|
|||||||
part_range_func:
|
part_range_func:
|
||||||
'(' part_bit_expr ')'
|
'(' part_bit_expr ')'
|
||||||
{
|
{
|
||||||
Lex->part_info->curr_part_elem->range_value= $2->value;
|
partition_info *part_info= Lex->part_info;
|
||||||
|
if (!($2->unsigned_flag))
|
||||||
|
part_info->curr_part_elem->signed_flag= TRUE;
|
||||||
|
part_info->curr_part_elem->range_value= $2->value;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
@ -3740,9 +3738,12 @@ part_list_item:
|
|||||||
part_bit_expr
|
part_bit_expr
|
||||||
{
|
{
|
||||||
part_elem_value *value_ptr= $1;
|
part_elem_value *value_ptr= $1;
|
||||||
|
partition_info *part_info= Lex->part_info;
|
||||||
|
if (!value_ptr->unsigned_flag)
|
||||||
|
part_info->curr_part_elem->signed_flag= TRUE;
|
||||||
if (!value_ptr->null_value &&
|
if (!value_ptr->null_value &&
|
||||||
Lex->part_info->curr_part_elem->
|
part_info->curr_part_elem->
|
||||||
list_val_list.push_back((longlong*) &value_ptr->value))
|
list_val_list.push_back(value_ptr))
|
||||||
{
|
{
|
||||||
mem_alloc_error(sizeof(part_elem_value));
|
mem_alloc_error(sizeof(part_elem_value));
|
||||||
YYABORT;
|
YYABORT;
|
||||||
@ -3783,6 +3784,10 @@ part_bit_expr:
|
|||||||
}
|
}
|
||||||
thd->where= save_where;
|
thd->where= save_where;
|
||||||
value_ptr->value= part_expr->val_int();
|
value_ptr->value= part_expr->val_int();
|
||||||
|
value_ptr->unsigned_flag= TRUE;
|
||||||
|
if (!part_expr->unsigned_flag &&
|
||||||
|
value_ptr->value < 0)
|
||||||
|
value_ptr->unsigned_flag= FALSE;
|
||||||
if ((value_ptr->null_value= part_expr->null_value))
|
if ((value_ptr->null_value= part_expr->null_value))
|
||||||
{
|
{
|
||||||
if (Lex->part_info->curr_part_elem->has_null_value)
|
if (Lex->part_info->curr_part_elem->has_null_value)
|
||||||
|
@ -1488,8 +1488,7 @@ int open_table_from_share(THD *thd, TABLE_SHARE *share, const char *alias,
|
|||||||
Fix the partition functions and ensure they are not constant
|
Fix the partition functions and ensure they are not constant
|
||||||
functions
|
functions
|
||||||
*/
|
*/
|
||||||
if (fix_partition_func(thd, share->normalized_path.str, outparam,
|
if (fix_partition_func(thd, outparam, is_create_table))
|
||||||
is_create_table))
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user