BUG#16002: Handle unsigned integer partition functions

parent c9493421
drop table if exists t1;
create table t1 (a bigint unsigned);
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
ERROR 42000: VALUES value must be of same type as partition function near '),
partition p1 values less than (10))' at line 3
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),
partition p1 values in (10));
ERROR 42000: VALUES value must be of same type as partition function near '),
partition p1 values in (10))' at line 3
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (100),
partition p1 values less than MAXVALUE);
insert into t1 values (1);
drop table t1;
create table t1 (a bigint unsigned)
partition by hash (a);
insert into t1 values (0xFFFFFFFFFFFFFFFD);
insert into t1 values (0xFFFFFFFFFFFFFFFE);
select * from t1 where (a + 1) < 10;
......@@ -852,7 +871,7 @@ 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
ERROR HY000: Partition constant is out of partition function domain
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (10));
......
......@@ -557,4 +557,4 @@ 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
ERROR HY000: Partition constant is out of partition function domain
......@@ -9,7 +9,29 @@
drop table if exists t1;
--enable_warnings
create table t1 (a bigint unsigned);
#
# BUG 16002: Handle unsigned integer functions properly
#
--error 1064
create table t1 (a bigint)
partition by range (a)
(partition p0 values less than (0xFFFFFFFFFFFFFFFF),
partition p1 values less than (10));
--error 1064
create table t1 (a bigint)
partition by list (a)
(partition p0 values in (0xFFFFFFFFFFFFFFFF),
partition p1 values in (10));
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (100),
partition p1 values less than MAXVALUE);
insert into t1 values (1);
drop table t1;
create table t1 (a bigint unsigned)
partition by hash (a);
insert into t1 values (0xFFFFFFFFFFFFFFFD);
insert into t1 values (0xFFFFFFFFFFFFFFFE);
select * from t1 where (a + 1) < 10;
......@@ -966,7 +988,7 @@ DROP TABLE t1;
#
#BUG 16002 Erroneus handling of unsigned partition functions
#
--error ER_SIGNED_PARTITION_CONSTANT_ERROR
--error ER_PARTITION_CONST_DOMAIN_ERROR
create table t1 (a bigint unsigned)
partition by list (a)
(partition p0 values in (0-1));
......@@ -978,6 +1000,8 @@ partition by range (a)
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
insert into t1 values (0xFFFFFFFFFFFFFFFF);
drop table t1;
#
#BUG 18750 Problems with partition names
#
......
......@@ -748,7 +748,7 @@ CREATE TABLE t1(a int)
insert into t1 values (10);
drop table t1;
--error ER_SIGNED_PARTITION_CONSTANT_ERROR
--error ER_PARTITION_CONST_DOMAIN_ERROR
create table t1 (a bigint unsigned)
partition by range (a)
(partition p0 values less than (-1));
......@@ -5162,17 +5162,14 @@ void ha_partition::print_error(int error, myf errflag)
{
char buf[100];
longlong value= m_part_info->part_expr->val_int();
if (!m_part_info->part_expr->unsigned_flag ||
m_part_info->part_expr->null_value)
if (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));
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0),"NULL");
}
else
{
ulonglong value= m_part_info->part_expr->val_int();
longlong2str(value, buf, 10);
longlong2str(value, buf,
m_part_info->part_expr->unsigned_flag ? 10 : -10);
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf);
}
}
......
......@@ -36,6 +36,13 @@ enum partition_state {
PART_IS_ADDED= 8
};
/*
This struct is used to contain the value of an element
in the VALUES IN struct. It needs to keep knowledge of
whether it is a signed/unsigned value and whether it is
NULL or not.
*/
typedef struct p_elem_val
{
longlong value;
......@@ -59,8 +66,8 @@ class partition_element :public Sql_alloc {
enum partition_state part_state;
uint16 nodegroup_id;
bool has_null_value;
bool signed_flag;
bool max_value;
bool signed_flag;/* Indicate whether this partition uses signed constants */
bool max_value; /* Indicate whether this partition uses MAXVALUE */
partition_element()
: part_max_rows(0), part_min_rows(0), range_value(0),
......
......@@ -485,10 +485,9 @@ bool partition_info::check_range_constants()
else
{
ulonglong upart_range_value_int;
if ((i != (no_parts - 1)) || !defined_max_value)
upart_range_value_int= part_def->range_value;
else
upart_range_value_int= ULONGLONG_MAX;
if ((i == (no_parts - 1)) && defined_max_value)
part_def->range_value= ULONGLONG_MAX;
upart_range_value_int= part_def->range_value;
if (likely(current_largest_uint < upart_range_value_int))
{
current_largest_uint= upart_range_value_int;
......@@ -572,7 +571,6 @@ bool partition_info::check_list_constants()
uint i;
uint list_index= 0;
part_elem_value *list_value;
bool not_first;
bool result= TRUE;
longlong curr_value, prev_value;
partition_element* part_def;
......@@ -638,6 +636,7 @@ bool partition_info::check_list_constants()
if (fixed)
{
bool first= TRUE;
if (!part_expr->unsigned_flag)
qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
&list_part_cmp);
......@@ -645,15 +644,14 @@ bool partition_info::check_list_constants()
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
{
curr_value= list_array[i].list_value;
if (likely(!not_first || prev_value != curr_value))
if (likely(first || prev_value != curr_value))
{
prev_value= curr_value;
not_first= TRUE;
first= FALSE;
}
else
{
......
......@@ -5826,9 +5826,9 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
ER_PARTITION_NO_TEMPORARY
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"
ER_PARTITION_CONST_DOMAIN_ERROR
eng "Partition constant is out of partition function domain"
swe "Partitionskonstanten r utanfr partitioneringsfunktionens domn"
ER_NULL_IN_VALUES_LESS_THAN
eng "Not allowed to use NULL value in VALUES LESS THAN"
swe "Det r inte tilltet att anvnda NULL-vrden i VALUES LESS THAN"
......
......@@ -819,8 +819,8 @@ int check_signed_flag(partition_info *part_info)
if (part_elem->signed_flag)
{
my_error(ER_SIGNED_PARTITION_CONSTANT_ERROR, MYF(0));
error= ER_SIGNED_PARTITION_CONSTANT_ERROR;
my_error(ER_PARTITION_CONST_DOMAIN_ERROR, MYF(0));
error= ER_PARTITION_CONST_DOMAIN_ERROR;
break;
}
} while (++i < part_info->no_parts);
......@@ -841,8 +841,8 @@ int check_signed_flag(partition_info *part_info)
func_expr The item tree reference of the partition function
table The table object
part_info Reference to partitioning data structure
sub_part Is the table subpartitioned as well
set_up_fields Flag if we are to set-up field arrays
is_sub_part Is the table subpartitioned as well
is_field_to_be_setup Flag if we are to set-up field arrays
RETURN VALUE
TRUE An error occurred, something was wrong with the
......@@ -1376,7 +1376,7 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
fix_partition_func()
thd The thread object
table TABLE object for which partition fields are set-up
create_table_ind Indicator of whether openfrm was called as part of
is_create_table_ind Indicator of whether openfrm was called as part of
CREATE or ALTER TABLE
RETURN VALUE
......@@ -1760,28 +1760,17 @@ static int add_partition_values(File fptr, partition_info *part_info,
if (part_info->part_type == RANGE_PARTITION)
{
err+= add_string(fptr, "VALUES LESS THAN ");
if (p_elem->signed_flag)
if (!p_elem->max_value)
{
if (!p_elem->max_value)
{
err+= add_begin_parenthesis(fptr);
err+= add_begin_parenthesis(fptr);
if (p_elem->signed_flag)
err+= add_int(fptr, p_elem->range_value);
err+= add_end_parenthesis(fptr);
}
else
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
}
else
{
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);
err+= add_end_parenthesis(fptr);
}
else
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
}
else if (part_info->part_type == LIST_PARTITION)
{
......
......@@ -3697,7 +3697,7 @@ opt_part_values:
;
part_func_max:
MAX_VALUE_SYM
max_value_sym
{
LEX *lex= Lex;
if (lex->part_info->defined_max_value)
......@@ -3724,6 +3724,11 @@ part_func_max:
}
;
max_value_sym:
MAX_VALUE_SYM
| '(' MAX_VALUE_SYM ')'
;
part_range_func:
'(' part_bit_expr ')'
{
......
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