summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-04-21 09:52:51 -0400
committerunknown <mikael@c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se>2006-04-21 09:52:51 -0400
commit23f8162cce6343350b8e2d23fd44889a95076817 (patch)
tree82bd468c2b8d05a4d83a36b1e7ed4112d7f23ee7
parentf0a6d276e569c0768cdf01f5adab8d6615cf458a (diff)
parent41395ba7820ec5d3bf67049e6a74964219f97601 (diff)
downloadmariadb-git-23f8162cce6343350b8e2d23fd44889a95076817.tar.gz
Merge mronstrom@bk-internal.mysql.com:/home/bk/bugs/bug16002
into c-870ae253.1238-1-64736c10.cust.bredbandsbolaget.se:/home/pappa/bug16002 sql/ha_partition.cc: Auto merged sql/partition_info.cc: Auto merged sql/sql_partition.cc: Auto merged sql/sql_show.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_yacc.yy: Auto merged mysql-test/r/partition.result: manual merge mysql-test/t/partition.test: manual merge sql/share/errmsg.txt: manual merge
-rw-r--r--mysql-test/r/partition.result20
-rw-r--r--mysql-test/r/partition_error.result4
-rw-r--r--mysql-test/r/partition_range.result12
-rw-r--r--mysql-test/t/partition.test22
-rw-r--r--mysql-test/t/partition_error.test5
-rw-r--r--mysql-test/t/partition_range.test17
-rw-r--r--sql/ha_partition.cc17
-rw-r--r--sql/partition_element.h22
-rw-r--r--sql/partition_info.cc115
-rw-r--r--sql/partition_info.h23
-rw-r--r--sql/share/errmsg.txt3
-rw-r--r--sql/sql_partition.cc455
-rw-r--r--sql/sql_partition.h7
-rw-r--r--sql/sql_show.cc9
-rw-r--r--sql/sql_table.cc4
-rw-r--r--sql/sql_yacc.yy23
-rw-r--r--sql/table.cc3
17 files changed, 558 insertions, 203 deletions
diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result
index 0da071374ea..b76896f720f 100644
--- a/mysql-test/r/partition.result
+++ b/mysql-test/r/partition.result
@@ -1,4 +1,14 @@
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 (
a int not null,
b int not null,
@@ -839,6 +849,16 @@ 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
t1 MyISAM 10 Dynamic 0 0 0 0 0 0 NULL NULL NULL NULL latin1_swedish_ci NULL partitioned
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;
create table t1 (a int)
partition by list (a)
(partition `s1 s2` values in (0));
diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index 1a0b1dd9b3a..cc51b909c51 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -554,3 +554,7 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
insert into t1 values (10);
ERROR HY000: Table has no partition for value 10
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
diff --git a/mysql-test/r/partition_range.result b/mysql-test/r/partition_range.result
index fc9350f5902..4d071c0edc1 100644
--- a/mysql-test/r/partition_range.result
+++ b/mysql-test/r/partition_range.result
@@ -363,3 +363,15 @@ SELECT COUNT(*) FROM t1 WHERE c3 < '2000-12-31';
COUNT(*)
10
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;
diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test
index 272cdc27af6..3714a4a3346 100644
--- a/mysql-test/t/partition.test
+++ b/mysql-test/t/partition.test
@@ -9,6 +9,13 @@
drop table if exists t1;
--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
#
@@ -957,6 +964,21 @@ SHOW TABLE STATUS;
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);
+
+#
#BUG 18750 Problems with partition names
#
create table t1 (a int)
diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test
index 03a2ab41807..dad2d2beda6 100644
--- a/mysql-test/t/partition_error.test
+++ b/mysql-test/t/partition_error.test
@@ -747,3 +747,8 @@ CREATE TABLE t1(a int)
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
insert into t1 values (10);
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));
diff --git a/mysql-test/t/partition_range.test b/mysql-test/t/partition_range.test
index a4d8c3740b7..239c6cc8144 100644
--- a/mysql-test/t/partition_range.test
+++ b/mysql-test/t/partition_range.test
@@ -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';
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;
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 3ee9a2954eb..3014c0317be 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -5161,9 +5161,20 @@ void ha_partition::print_error(int error, myf errflag)
if (error == HA_ERR_NO_PARTITION_FOUND)
{
char buf[100];
- 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));
+ longlong value= m_part_info->part_expr->val_int();
+ if (!m_part_info->part_expr->unsigned_flag ||
+ 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
m_file[0]->print_error(error, errflag);
diff --git a/sql/partition_element.h b/sql/partition_element.h
index d20715d2408..7063e514901 100644
--- a/sql/partition_element.h
+++ b/sql/partition_element.h
@@ -36,15 +36,22 @@ enum partition_state {
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 {
public:
List<partition_element> subpartitions;
- List<longlong> list_val_list;
+ List<part_elem_value> list_val_list;
ulonglong part_max_rows;
ulonglong part_min_rows;
+ longlong range_value;
char *partition_name;
char *tablespace_name;
- longlong range_value;
char* part_comment;
char* data_file_name;
char* index_file_name;
@@ -52,13 +59,16 @@ public:
enum partition_state part_state;
uint16 nodegroup_id;
bool has_null_value;
+ bool signed_flag;
+ bool max_value;
partition_element()
- : part_max_rows(0), part_min_rows(0), partition_name(NULL),
- tablespace_name(NULL), range_value(0), part_comment(NULL),
+ : part_max_rows(0), part_min_rows(0), range_value(0),
+ partition_name(NULL), tablespace_name(NULL), part_comment(NULL),
data_file_name(NULL), index_file_name(NULL),
- engine_type(NULL),part_state(PART_NORMAL),
- nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE)
+ engine_type(NULL), part_state(PART_NORMAL),
+ nodegroup_id(UNDEF_NODEGROUP), has_null_value(FALSE),
+ signed_flag(FALSE), max_value(FALSE)
{
subpartitions.empty();
list_val_list.empty();
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index e2bf37d6ef3..97cac37c00e 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -445,10 +445,12 @@ bool partition_info::check_range_constants()
{
partition_element* part_def;
longlong current_largest_int= LONGLONG_MIN;
+ ulonglong current_largest_uint= 0;
longlong part_range_value_int;
uint i;
List_iterator<partition_element> it(partitions);
bool result= TRUE;
+ bool signed_flag= !part_expr->unsigned_flag;
DBUG_ENTER("partition_info::check_range_constants");
DBUG_PRINT("enter", ("INT_RESULT with %d parts", no_parts));
@@ -463,19 +465,40 @@ bool partition_info::check_range_constants()
do
{
part_def= it++;
- if ((i != (no_parts - 1)) || !defined_max_value)
- part_range_value_int= part_def->range_value;
- else
- part_range_value_int= LONGLONG_MAX;
- if (likely(current_largest_int < part_range_value_int))
+ if (signed_flag)
{
- current_largest_int= part_range_value_int;
- range_int_array[i]= part_range_value_int;
+ if ((i != (no_parts - 1)) || !defined_max_value)
+ 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
{
- my_error(ER_RANGE_NOT_INCREASING_ERROR, MYF(0));
- goto end;
+ 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 (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);
result= FALSE;
@@ -485,8 +508,8 @@ end:
/*
- A support routine for check_list_constants used by qsort to sort the
- constant list expressions.
+ Support routines for check_list_constants used by qsort to sort the
+ constant list expressions. One routine for unsigned and one for signed.
SYNOPSIS
list_part_cmp()
@@ -511,6 +534,18 @@ int partition_info::list_part_cmp(const void* a, const void* b)
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
@@ -536,7 +571,7 @@ bool partition_info::check_list_constants()
{
uint i;
uint list_index= 0;
- longlong *list_value;
+ part_elem_value *list_value;
bool not_first;
bool result= TRUE;
longlong curr_value, prev_value;
@@ -577,7 +612,7 @@ bool partition_info::check_list_constants()
has_null_part_id= i;
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++)
no_list_values++;
} while (++i < no_parts);
@@ -593,33 +628,40 @@ bool partition_info::check_list_constants()
do
{
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++))
{
- list_array[list_index].list_value= *list_value;
+ list_array[list_index].list_value= list_value->value;
list_array[list_index++].partition_id= i;
}
} while (++i < no_parts);
- qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
- &list_part_cmp);
-
- not_first= FALSE;
- i= prev_value= 0; //prev_value initialised to quiet compiler
- do
+ if (fixed)
{
- curr_value= list_array[i].list_value;
- if (likely(!not_first || prev_value != curr_value))
- {
- prev_value= curr_value;
- not_first= TRUE;
- }
+ if (!part_expr->unsigned_flag)
+ qsort((void*)list_array, no_list_values, sizeof(LIST_PART_ENTRY),
+ &list_part_cmp);
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));
- goto end;
- }
- } while (++i < no_list_values);
+ curr_value= list_array[i].list_value;
+ if (likely(!not_first || prev_value != curr_value))
+ {
+ 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;
end:
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)
{
handlerton **engine_array= NULL;
@@ -745,9 +787,12 @@ bool partition_info::check_partition_info(handlerton **eng_type,
list constants.
*/
- if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
- (part_type == LIST_PARTITION && check_list_constants())))
- goto end;
+ if (fixed)
+ {
+ if (unlikely((part_type == RANGE_PARTITION && check_range_constants()) ||
+ (part_type == LIST_PARTITION && check_list_constants())))
+ goto end;
+ }
result= FALSE;
end:
my_free((char*)engine_array,MYF(MY_ALLOW_ZERO_PTR));
diff --git a/sql/partition_info.h b/sql/partition_info.h
index 664c8834b0b..5a2cacd3c71 100644
--- a/sql/partition_info.h
+++ b/sql/partition_info.h
@@ -163,6 +163,7 @@ public:
uint no_subpart_fields;
uint no_full_part_fields;
+ uint has_null_part_id;
/*
This variable is used to calculate the partition id when using
LINEAR KEY/HASH. This functionality is kept in the MySQL Server
@@ -182,7 +183,6 @@ public:
bool fixed;
bool from_openfrm;
bool has_null_value;
- uint has_null_part_id;
partition_info()
@@ -204,19 +204,13 @@ public:
no_parts(0), no_subparts(0),
count_curr_subparts(0), part_error_code(0),
no_list_values(0), no_part_fields(0), no_subpart_fields(0),
- no_full_part_fields(0), linear_hash_mask(0),
- use_default_partitions(TRUE),
- use_default_no_partitions(TRUE),
- use_default_subpartitions(TRUE),
- use_default_no_subpartitions(TRUE),
- default_partitions_setup(FALSE),
- defined_max_value(FALSE),
+ no_full_part_fields(0), has_null_part_id(0), linear_hash_mask(0),
+ use_default_partitions(TRUE), use_default_no_partitions(TRUE),
+ use_default_subpartitions(TRUE), use_default_no_subpartitions(TRUE),
+ default_partitions_setup(FALSE), defined_max_value(FALSE),
list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
- linear_hash_ind(FALSE),
- fixed(FALSE),
- from_openfrm(FALSE),
- has_null_value(FALSE),
- has_null_part_id(0)
+ linear_hash_ind(FALSE), fixed(FALSE), from_openfrm(FALSE),
+ has_null_value(FALSE)
{
all_fields_in_PF.clear_all();
all_fields_in_PPF.clear_all();
@@ -248,10 +242,11 @@ public:
static bool check_engine_mix(handlerton **engine_array, uint no_parts);
bool check_range_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);
private:
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,
uint start_no);
bool set_up_default_subpartitions(handler *file, ulonglong max_rows);
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index d836bd4ff6c..203f58ba108 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5826,6 +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_NULL_IN_VALUES_LESS_THAN
eng "Not allowed to use NULL value in VALUES LESS THAN"
swe "Det är inte tillåtet att använda NULL-värden i VALUES LESS THAN"
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index aae80f07b71..05f99110f61 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -61,7 +61,6 @@ static const char *equal_str= "=";
static const char *end_paren_str= ")";
static const char *begin_paren_str= "(";
static const char *comma_str= ",";
-static char buff[22];
int get_partition_id_list(partition_info *part_info,
uint32 *part_id,
@@ -189,9 +188,9 @@ bool is_name_in_list(char *name,
SYNOPSIS
partition_default_handling()
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
+ is_create_table_ind Is this part of a table creation
+ normalized_path Normalized path name of table and database
RETURN VALUES
TRUE Error
@@ -794,6 +793,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
GET_FIXED_FIELDS_FLAG is set for all fields in the item tree.
This field must always be reset before returning from the function
@@ -802,10 +838,11 @@ end:
SYNOPSIS
fix_fields_part_func()
thd The thread object
- tables A list of one table, the partitioned table
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
RETURN VALUE
TRUE An error occurred, something was wrong with the
@@ -828,26 +865,54 @@ end:
on the field object.
*/
-static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
- Item* func_expr, partition_info *part_info,
- bool is_sub_part)
+bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
+ bool is_sub_part, bool is_field_to_be_setup)
{
+ partition_info *part_info= table->part_info;
+ uint dir_length, home_dir_length;
bool result= TRUE;
- TABLE *table= tables->table;
+ TABLE_LIST tables;
TABLE_LIST *save_table_list, *save_first_table, *save_last_table;
int error;
Name_resolution_context *context;
const char *save_where;
+ char* db_name;
+ char db_name_string[FN_REFLEN];
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();
table->map= 1; //To ensure correct calculation of const item
table->get_fields_in_item_tree= TRUE;
save_table_list= context->table_list;
save_first_table= context->first_name_resolution_table;
save_last_table= context->last_name_resolution_table;
- context->table_list= tables;
- context->first_name_resolution_table= tables;
+ context->table_list= &tables;
+ context->first_name_resolution_table= &tables;
context->last_name_resolution_table= NULL;
func_expr->walk(&Item::change_context_processor, (byte*) context);
save_where= thd->where;
@@ -859,7 +924,8 @@ static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
if (unlikely(error))
{
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;
}
thd->where= save_where;
@@ -869,7 +935,13 @@ static bool fix_fields_part_func(THD *thd, TABLE_LIST *tables,
clear_field_flag(table);
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:
table->get_fields_in_item_tree= FALSE;
table->map= 0; //Restore old value
@@ -1303,7 +1375,6 @@ static uint32 get_part_id_from_linear_hash(longlong hash_value, uint mask,
SYNOPSIS
fix_partition_func()
thd The thread object
- name The name of the partitioned table
table TABLE object for which partition fields are set-up
create_table_ind Indicator of whether openfrm was called as part of
CREATE or ALTER TABLE
@@ -1325,15 +1396,10 @@ NOTES
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 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;
ulong save_set_query_id= thd->set_query_id;
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;
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 ||
thd->lex->sql_command != SQLCOM_CREATE_TABLE)
@@ -1391,9 +1440,8 @@ bool fix_partition_func(THD *thd, const char* name, TABLE *table,
}
else
{
- if (unlikely(fix_fields_part_func(thd, &tables,
- part_info->subpart_expr, part_info,
- TRUE)))
+ if (unlikely(fix_fields_part_func(thd, part_info->subpart_expr,
+ table, TRUE, TRUE)))
goto end;
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
{
- if (unlikely(fix_fields_part_func(thd, &tables, part_info->part_expr,
- part_info, FALSE)))
+ if (unlikely(fix_fields_part_func(thd, part_info->part_expr,
+ table, FALSE, TRUE)))
goto end;
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
{
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)
{
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);
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))
{
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);
set_up_partition_key_maps(table, part_info);
set_up_partition_func_pointers(part_info);
- part_info->fixed= TRUE;
set_up_range_analysis_info(part_info);
result= FALSE;
end:
@@ -1563,6 +1610,7 @@ static int add_hash(File fptr)
static int add_partition(File fptr)
{
+ char buff[22];
strxmov(buff, part_str, space_str, NullS);
return add_string(fptr, buff);
}
@@ -1576,6 +1624,7 @@ static int add_subpartition(File fptr)
static int add_partition_by(File fptr)
{
+ char buff[22];
strxmov(buff, part_str, space_str, by_str, space_str, NullS);
return add_string(fptr, buff);
}
@@ -1631,10 +1680,18 @@ static int add_name_string(File fptr, const char *name)
static int add_int(File fptr, longlong number)
{
+ char buff[32];
llstr(number, 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,
bool should_use_quotes,
const char *keystr)
@@ -1696,28 +1753,43 @@ static int add_partition_options(File fptr, partition_element *p_elem)
}
static int add_partition_values(File fptr, partition_info *part_info,
- partition_element *p_elem)
+ partition_element *p_elem)
{
int err= 0;
if (part_info->part_type == RANGE_PARTITION)
{
err+= add_string(fptr, "VALUES LESS THAN ");
- if (p_elem->range_value != LONGLONG_MAX)
+ if (p_elem->signed_flag)
{
- err+= add_begin_parenthesis(fptr);
- err+= add_int(fptr, p_elem->range_value);
- err+= add_end_parenthesis(fptr);
+ if (!p_elem->max_value)
+ {
+ 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
- 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)
{
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 ");
uint no_items= p_elem->list_val_list.elements;
+
err+= add_begin_parenthesis(fptr);
if (p_elem->has_null_value)
{
@@ -1732,8 +1804,12 @@ static int add_partition_values(File fptr, partition_info *part_info,
i= 0;
do
{
- longlong *list_value= list_val_it++;
- err+= add_int(fptr, *list_value);
+ part_elem_value *list_value= list_val_it++;
+
+ 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))
err+= add_comma(fptr);
} while (++i < no_items);
@@ -2309,15 +2385,15 @@ static uint32 get_part_id_linear_key(partition_info *part_info,
int get_partition_id_list(partition_info *part_info,
- uint32 *part_id,
- longlong *func_value)
+ uint32 *part_id,
+ longlong *func_value)
{
LIST_PART_ENTRY *list_array= part_info->list_array;
int list_index;
- longlong list_value;
int min_list_index= 0;
int max_list_index= part_info->no_list_values - 1;
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");
if (part_info->part_expr->null_value)
@@ -2330,22 +2406,49 @@ int get_partition_id_list(partition_info *part_info,
goto notfound;
}
*func_value= part_func_value;
- while (max_list_index >= min_list_index)
+ if (!unsigned_flag)
{
- 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)
+ longlong list_value;
+ while (max_list_index >= min_list_index)
{
- if (!list_index)
- goto notfound;
- max_list_index= list_index - 1;
+ 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;
+ 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;
- DBUG_RETURN(0);
+ 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;
+ max_list_index= list_index - 1;
+ }
+ else
+ {
+ *part_id= (uint32)list_array[list_index].partition_id;
+ DBUG_RETURN(0);
+ }
}
}
notfound:
@@ -2396,34 +2499,65 @@ uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
- DBUG_ENTER("get_list_array_idx_for_endpoint");
LIST_PART_ENTRY *list_array= part_info->list_array;
uint list_index;
- longlong list_value;
uint min_list_index= 0, max_list_index= part_info->no_list_values - 1;
/* Get the partitioning function value for the endpoint */
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;
- 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)
+ longlong list_value;
+ while (max_list_index >= min_list_index)
{
- if (!list_index)
- goto notfound;
- max_list_index= list_index - 1;
+ 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));
+ }
}
- else
+ notfound_signed:
+ if (list_value < part_func_value)
+ list_index++;
+ DBUG_RETURN(list_index);
+ }
+ else
+ {
+ ulonglong upart_func_value= part_func_value;
+ ulonglong ulist_value;
+ 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);
}
@@ -2437,6 +2571,7 @@ int get_partition_id_range(partition_info *part_info,
uint max_part_id= max_partition;
uint loc_part_id;
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");
if (part_info->part_expr->null_value)
@@ -2444,24 +2579,52 @@ int get_partition_id_range(partition_info *part_info,
*part_id= 0;
DBUG_RETURN(0);
}
- while (max_part_id > min_part_id)
+ *func_value= part_func_value;
+ if (!unsigned_flag)
{
- 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;
+ 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;
+ 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);
}
- 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;
- 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);
DBUG_RETURN(0);
}
@@ -2511,39 +2674,79 @@ uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
bool left_endpoint,
bool include_endpoint)
{
- DBUG_ENTER("get_partition_id_range_for_endpoint");
longlong *range_array= part_info->range_int_array;
uint max_partition= part_info->no_parts - 1;
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
/* Get the partitioning function value for the endpoint */
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;
- 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 (loc_part_id < max_partition &&
- part_func_value >= range_array[loc_part_id+1])
- {
- loc_part_id++;
- }
- if (left_endpoint)
- {
- 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;
+ 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 (loc_part_id < max_partition &&
+ part_func_value >= range_array[loc_part_id+1])
+ {
+ 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++;
+ }
}
- else
+ 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])
+ 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+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++;
+ }
}
DBUG_RETURN(loc_part_id);
}
@@ -4512,8 +4715,8 @@ the generated partition syntax in a correct manner.
tab_part_info->use_default_subpartitions= FALSE;
tab_part_info->use_default_no_subpartitions= FALSE;
}
- if (tab_part_info->check_partition_info((handlerton**)NULL,
- table->file, ULL(0)))
+ if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
+ table->file, ULL(0)))
{
DBUG_RETURN(TRUE);
}
diff --git a/sql/sql_partition.h b/sql/sql_partition.h
index fd2c474236f..9fde3db2883 100644
--- a/sql/sql_partition.h
+++ b/sql/sql_partition.h
@@ -65,9 +65,8 @@ int get_part_for_delete(const byte *buf, const byte *rec0,
partition_info *part_info, uint32 *part_id);
void prune_partition_set(const TABLE *table, part_id_range *part_spec);
bool check_partition_info(partition_info *part_info,handlerton **eng_type,
- handler *file, ulonglong max_rows);
-bool fix_partition_func(THD *thd, const char *name, TABLE *table,
- bool create_table_ind);
+ TABLE *table, handler *file, ulonglong max_rows);
+bool fix_partition_func(THD *thd, TABLE *table, bool create_table_ind);
char *generate_partition_syntax(partition_info *part_info,
uint *buf_length, bool use_sql_alloc,
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,
bool left_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.
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 95433828a1e..3d042a75628 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -3856,8 +3856,8 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
}
else if (part_info->part_type == LIST_PARTITION)
{
- List_iterator<longlong> list_val_it(part_elem->list_val_list);
- longlong *list_value;
+ List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
+ part_elem_value *list_value;
uint no_items= part_elem->list_val_list.elements;
tmp_str.length(0);
tmp_res.length(0);
@@ -3869,7 +3869,10 @@ static int get_schema_partitions_record(THD *thd, struct st_table_list *tables,
}
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);
if (--no_items != 0)
tmp_str.append(",");
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 6cc2ad266e5..846c40d82d5 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2148,8 +2148,8 @@ bool mysql_create_table_internal(THD *thd,
}
DBUG_PRINT("info", ("db_type = %d",
ha_legacy_type(part_info->default_engine_type)));
- if (part_info->check_partition_info( &engine_type, file,
- create_info->max_rows))
+ if (part_info->check_partition_info(thd, &engine_type, file,
+ create_info->max_rows))
goto err;
part_info->default_engine_type= engine_type;
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 2f91472ad2d..9e2fa96fec7 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -42,12 +42,6 @@
#include <myisam.h>
#include <myisammrg.h>
-typedef struct p_elem_val
-{
- longlong value;
- bool null_value;
-} part_elem_value;
-
int yylex(void *yylval, void *yythd);
const LEX_STRING null_lex_str={0,0};
@@ -3712,6 +3706,7 @@ part_func_max:
YYABORT;
}
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;
}
| part_range_func
@@ -3732,7 +3727,10 @@ part_func_max:
part_range_func:
'(' 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;
}
;
@@ -3745,9 +3743,12 @@ part_list_item:
part_bit_expr
{
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 &&
- Lex->part_info->curr_part_elem->
- list_val_list.push_back((longlong*) &value_ptr->value))
+ part_info->curr_part_elem->
+ list_val_list.push_back(value_ptr))
{
mem_alloc_error(sizeof(part_elem_value));
YYABORT;
@@ -3788,6 +3789,10 @@ part_bit_expr:
}
thd->where= save_where;
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 (Lex->part_info->curr_part_elem->has_null_value)
diff --git a/sql/table.cc b/sql/table.cc
index 41621a19900..7252940eb27 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -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
functions
*/
- if (fix_partition_func(thd, share->normalized_path.str, outparam,
- is_create_table))
+ if (fix_partition_func(thd, outparam, is_create_table))
goto err;
}
#endif