A lot of fixes to make character set work ok, first step to fixing BUG#48163
This commit is contained in:
parent
57d455460d
commit
66f056a64c
@ -1,4 +1,32 @@
|
||||
drop table if exists t1;
|
||||
create table t1 (a int, b char(10), c varchar(25), d datetime)
|
||||
partition by range column_list(a,b,c,d)
|
||||
subpartition by hash (to_seconds(d))
|
||||
subpartitions 4
|
||||
( partition p0 values less than (1, 0, MAXVALUE, 0),
|
||||
partition p1 values less than (1, 'a', MAXVALUE, TO_DAYS('1999-01-01')),
|
||||
partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE),
|
||||
partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
partition_method partition_expression partition_description
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'0',MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'0',MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'0',MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'0',MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
drop table t1;
|
||||
create table t1 (a int, b int)
|
||||
partition by range column_list (a,b)
|
||||
(partition p0 values less than (NULL, maxvalue));
|
||||
@ -8,12 +36,19 @@ partition by list column_list(a,b)
|
||||
( partition p0 values in ((maxvalue, 0)));
|
||||
Got one of the listed errors
|
||||
create table t1 (a int, b int)
|
||||
partition by list column_list (a,b)
|
||||
( partition p0 values in ((0,0)));
|
||||
alter table t1 add partition
|
||||
(partition p1 values in (maxvalue, maxvalue));
|
||||
Got one of the listed errors
|
||||
drop table t1;
|
||||
create table t1 (a int, b int)
|
||||
partition by key (a,a);
|
||||
ERROR HY000: Duplicate partition field name a
|
||||
ERROR HY000: Duplicate partition field name 'a'
|
||||
create table t1 (a int, b int)
|
||||
partition by list column_list(a,a)
|
||||
( partition p values in ((1,1)));
|
||||
ERROR HY000: Duplicate partition field name a
|
||||
ERROR HY000: Duplicate partition field name 'a'
|
||||
create table t1 (a int signed)
|
||||
partition by list (a)
|
||||
( partition p0 values in (1, 3, 5, 7, 9, NULL),
|
||||
@ -61,6 +96,16 @@ partition_method partition_expression partition_description
|
||||
LIST COLUMN_LIST a,b (1,NULL),(2,NULL),(NULL,NULL)
|
||||
LIST COLUMN_LIST a,b (1,1),(2,2)
|
||||
LIST COLUMN_LIST a,b (3,NULL),(NULL,1)
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
/*!50100 PARTITION BY LIST COLUMN_LIST(a,b)
|
||||
(PARTITION p0 VALUES IN ((1,NULL),(2,NULL),(NULL,NULL)) ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES IN ((1,1),(2,2)) ENGINE = MyISAM,
|
||||
PARTITION p2 VALUES IN ((3,NULL),(NULL,1)) ENGINE = MyISAM) */
|
||||
insert into t1 values (3, NULL);
|
||||
insert into t1 values (NULL, 1);
|
||||
insert into t1 values (NULL, NULL);
|
||||
@ -110,6 +155,14 @@ from information_schema.partitions where table_name = "t1";
|
||||
partition_method partition_expression partition_description
|
||||
LIST a 2,1
|
||||
LIST a NULL,4,3
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
/*!50100 PARTITION BY LIST (a)
|
||||
(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES IN (NULL,4,3) ENGINE = MyISAM) */
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (2);
|
||||
insert into t1 values (3);
|
||||
@ -132,6 +185,14 @@ from information_schema.partitions where table_name = "t1";
|
||||
partition_method partition_expression partition_description
|
||||
LIST COLUMN_LIST a 2,1
|
||||
LIST COLUMN_LIST a 4,NULL,3
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
/*!50100 PARTITION BY LIST COLUMN_LIST(a)
|
||||
(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES IN (4,NULL,3) ENGINE = MyISAM) */
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (2);
|
||||
insert into t1 values (3);
|
||||
@ -148,34 +209,6 @@ t1 CREATE TABLE `t1` (
|
||||
(PARTITION p0 VALUES IN (2,1) ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES IN (4,NULL,3) ENGINE = MyISAM) */
|
||||
drop table t1;
|
||||
create table t1 (a int, b char(10), c varchar(25), d datetime)
|
||||
partition by range column_list(a,b,c,d)
|
||||
subpartition by hash (to_seconds(d))
|
||||
subpartitions 4
|
||||
( partition p0 values less than (1, 0, MAXVALUE, 0),
|
||||
partition p1 values less than (1, 'a', MAXVALUE, TO_DAYS('1999-01-01')),
|
||||
partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE),
|
||||
partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
partition_method partition_expression partition_description
|
||||
RANGE COLUMN_LIST a,b,c,d 1,0,MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,0,MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,0,MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,0,MAXVALUE,0
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,730120
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,'a',MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
RANGE COLUMN_LIST a,b,c,d 1,MAXVALUE,MAXVALUE,MAXVALUE
|
||||
drop table t1;
|
||||
create table t1 (a int, b char(10), c varchar(5), d int)
|
||||
partition by range column_list(a,b,c)
|
||||
subpartition by key (c,d)
|
||||
@ -199,6 +232,21 @@ RANGE COLUMN_LIST a,b,c 3,'abc','abc'
|
||||
RANGE COLUMN_LIST a,b,c 4,'abc','abc'
|
||||
RANGE COLUMN_LIST a,b,c 4,'abc','abc'
|
||||
RANGE COLUMN_LIST a,b,c 4,'abc','abc'
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` char(10) DEFAULT NULL,
|
||||
`c` varchar(5) DEFAULT NULL,
|
||||
`d` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
/*!50100 PARTITION BY RANGE COLUMN_LIST(a,b,c)
|
||||
SUBPARTITION BY KEY (c,d)
|
||||
SUBPARTITIONS 3
|
||||
(PARTITION p0 VALUES LESS THAN (1,'abc','abc') ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES LESS THAN (2,'abc','abc') ENGINE = MyISAM,
|
||||
PARTITION p2 VALUES LESS THAN (3,'abc','abc') ENGINE = MyISAM,
|
||||
PARTITION p3 VALUES LESS THAN (4,'abc','abc') ENGINE = MyISAM) */
|
||||
insert into t1 values (1,'a','b',1),(2,'a','b',2),(3,'a','b',3);
|
||||
insert into t1 values (1,'b','c',1),(2,'b','c',2),(3,'b','c',3);
|
||||
insert into t1 values (1,'c','d',1),(2,'c','d',2),(3,'c','d',3);
|
||||
@ -218,6 +266,16 @@ from information_schema.partitions where table_name = "t1";
|
||||
partition_method partition_expression partition_description
|
||||
RANGE COLUMN_LIST a,b,c 1,'A',1
|
||||
RANGE COLUMN_LIST a,b,c 1,'B',1
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` varchar(2) DEFAULT NULL,
|
||||
`c` int(11) DEFAULT NULL
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
/*!50100 PARTITION BY RANGE COLUMN_LIST(a,b,c)
|
||||
(PARTITION p0 VALUES LESS THAN (1,'A',1) ENGINE = MyISAM,
|
||||
PARTITION p1 VALUES LESS THAN (1,'B',1) ENGINE = MyISAM) */
|
||||
insert into t1 values (1, 'A', 1);
|
||||
explain partitions select * from t1 where a = 1 AND b <= 'A' and c = 1;
|
||||
id select_type table partitions type possible_keys key key_len ref rows Extra
|
||||
@ -234,11 +292,21 @@ select * from t1 where a = 'a';
|
||||
a b c
|
||||
a NULL NULL
|
||||
drop table t1;
|
||||
create table t1 (d timestamp)
|
||||
create table t1 (d time)
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than ('2000-01-01'),
|
||||
partition p1 values less than ('2040-01-01'));
|
||||
ERROR HY000: Partition column values of incorrect type
|
||||
create table t1 (d timestamp)
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than ('2000-01-01'),
|
||||
partition p1 values less than ('2040-01-01'));
|
||||
ERROR HY000: Field 'd' is of a not allowed type for this type of partitioning
|
||||
create table t1 (d bit(1))
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than (0),
|
||||
partition p1 values less than (1));
|
||||
ERROR HY000: Field 'd' is of a not allowed type for this type of partitioning
|
||||
create table t1 (a int, b int)
|
||||
partition by range column_list(a,b)
|
||||
(partition p0 values less than (maxvalue, 10));
|
||||
|
@ -8,6 +8,29 @@
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (a int, b char(10), c varchar(25), d datetime)
|
||||
partition by range column_list(a,b,c,d)
|
||||
subpartition by hash (to_seconds(d))
|
||||
subpartitions 4
|
||||
( partition p0 values less than (1, 0, MAXVALUE, 0),
|
||||
partition p1 values less than (1, 'a', MAXVALUE, TO_DAYS('1999-01-01')),
|
||||
partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE),
|
||||
partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
#show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG#48163, Dagger in UCS2 not working as partition value
|
||||
#
|
||||
#create table t1 (a varchar(2) character set ucs2)
|
||||
#partition by list column_list (a)
|
||||
#(partition p0 values in (0x2020),
|
||||
# partition p1 values in (''));
|
||||
#insert into t1 values ('');
|
||||
#drop table t1;
|
||||
|
||||
--error ER_NULL_IN_VALUES_LESS_THAN
|
||||
create table t1 (a int, b int)
|
||||
partition by range column_list (a,b)
|
||||
@ -18,6 +41,13 @@ create table t1 (a int, b int)
|
||||
partition by list column_list(a,b)
|
||||
( partition p0 values in ((maxvalue, 0)));
|
||||
|
||||
create table t1 (a int, b int)
|
||||
partition by list column_list (a,b)
|
||||
( partition p0 values in ((0,0)));
|
||||
--error ER_MAXVALUE_IN_VALUES_IN, ER_PARSE_ERROR
|
||||
alter table t1 add partition
|
||||
(partition p1 values in (maxvalue, maxvalue));
|
||||
drop table t1;
|
||||
#
|
||||
# BUG#47837, Crash when two same fields in column list processing
|
||||
#
|
||||
@ -61,6 +91,7 @@ partition by list column_list(a,b)
|
||||
partition p2 values in ((3, NULL), (NULL, 1)));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
show create table t1;
|
||||
#
|
||||
# BUG#47754 Crash when selecting using NOT BETWEEN for column list partitioning
|
||||
#
|
||||
@ -90,6 +121,7 @@ partition by list (a)
|
||||
partition p1 values in (4, NULL, 3));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
show create table t1;
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (2);
|
||||
insert into t1 values (3);
|
||||
@ -111,6 +143,7 @@ partition by list column_list(a)
|
||||
partition p1 values in (4, NULL, 3));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
show create table t1;
|
||||
insert into t1 values (1);
|
||||
insert into t1 values (2);
|
||||
insert into t1 values (3);
|
||||
@ -121,18 +154,6 @@ insert into t1 values (5);
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
create table t1 (a int, b char(10), c varchar(25), d datetime)
|
||||
partition by range column_list(a,b,c,d)
|
||||
subpartition by hash (to_seconds(d))
|
||||
subpartitions 4
|
||||
( partition p0 values less than (1, 0, MAXVALUE, 0),
|
||||
partition p1 values less than (1, 'a', MAXVALUE, TO_DAYS('1999-01-01')),
|
||||
partition p2 values less than (1, 'a', MAXVALUE, MAXVALUE),
|
||||
partition p3 values less than (1, MAXVALUE, MAXVALUE, MAXVALUE));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
drop table t1;
|
||||
|
||||
create table t1 (a int, b char(10), c varchar(5), d int)
|
||||
partition by range column_list(a,b,c)
|
||||
subpartition by key (c,d)
|
||||
@ -143,6 +164,7 @@ subpartitions 3
|
||||
partition p3 values less than (4,'abc','abc'));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
show create table t1;
|
||||
|
||||
insert into t1 values (1,'a','b',1),(2,'a','b',2),(3,'a','b',3);
|
||||
insert into t1 values (1,'b','c',1),(2,'b','c',2),(3,'b','c',3);
|
||||
@ -158,6 +180,7 @@ partition by range column_list (a, b, c)
|
||||
partition p1 values less than (1, 'B', 1));
|
||||
select partition_method, partition_expression, partition_description
|
||||
from information_schema.partitions where table_name = "t1";
|
||||
show create table t1;
|
||||
insert into t1 values (1, 'A', 1);
|
||||
explain partitions select * from t1 where a = 1 AND b <= 'A' and c = 1;
|
||||
select * from t1 where a = 1 AND b <= 'A' and c = 1;
|
||||
@ -171,11 +194,23 @@ select * from t1 where a = 'a';
|
||||
drop table t1;
|
||||
|
||||
--error ER_WRONG_TYPE_COLUMN_VALUE_ERROR
|
||||
create table t1 (d time)
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than ('2000-01-01'),
|
||||
partition p1 values less than ('2040-01-01'));
|
||||
|
||||
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
|
||||
create table t1 (d timestamp)
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than ('2000-01-01'),
|
||||
partition p1 values less than ('2040-01-01'));
|
||||
|
||||
--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
|
||||
create table t1 (d bit(1))
|
||||
partition by range column_list(d)
|
||||
( partition p0 values less than (0),
|
||||
partition p1 values less than (1));
|
||||
|
||||
create table t1 (a int, b int)
|
||||
partition by range column_list(a,b)
|
||||
(partition p0 values less than (maxvalue, 10));
|
||||
|
@ -1222,6 +1222,8 @@ int prepare_create_field(Create_field *sql_field,
|
||||
uint *blob_columns,
|
||||
int *timestamps, int *timestamps_with_niladic,
|
||||
longlong table_flags);
|
||||
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
|
||||
HA_CREATE_INFO *create_info);
|
||||
bool mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info,
|
||||
@ -1611,6 +1613,11 @@ uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
|
||||
handlerton *old_db_type,
|
||||
bool *partition_changed,
|
||||
uint *fast_alter_partition);
|
||||
char *generate_partition_syntax(partition_info *part_info,
|
||||
uint *buf_length, bool use_sql_alloc,
|
||||
bool show_partition_options,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info);
|
||||
#endif
|
||||
|
||||
/* bits for last argument to remove_table_from_cache() */
|
||||
|
@ -1876,6 +1876,34 @@ int partition_info::fix_func_partition(THD *thd,
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
Get column item with a proper character set according to the field
|
||||
|
||||
SYNOPSIS
|
||||
get_column_item()
|
||||
item Item object to start with
|
||||
field Field for which the item will be compared to
|
||||
|
||||
RETURN VALUES
|
||||
NULL Error
|
||||
item Returned item
|
||||
*/
|
||||
|
||||
Item* partition_info::get_column_item(Item *item, Field *field)
|
||||
{
|
||||
if (field->result_type() == STRING_RESULT &&
|
||||
item->collation.collation != field->charset())
|
||||
{
|
||||
if (!(item= convert_charset_partition_constant(item,
|
||||
field->charset())))
|
||||
{
|
||||
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Evaluate VALUES functions for column list values
|
||||
@ -1921,6 +1949,12 @@ bool partition_info::fix_column_value_functions(THD *thd,
|
||||
{
|
||||
uchar *val_ptr;
|
||||
uint len= field->pack_length();
|
||||
if (!(column_item= get_column_item(column_item,
|
||||
field)))
|
||||
{
|
||||
result= TRUE;
|
||||
goto end;
|
||||
}
|
||||
if (column_item->save_in_field(field, TRUE))
|
||||
{
|
||||
my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0));
|
||||
|
@ -281,6 +281,7 @@ public:
|
||||
bool check_partition_function);
|
||||
void print_no_partition_found(TABLE *table);
|
||||
void print_debug(const char *str, uint*);
|
||||
Item* get_column_item(Item *item, Field *field);
|
||||
int fix_func_partition(THD *thd,
|
||||
part_elem_value *val,
|
||||
partition_element *part_elem,
|
||||
|
@ -6207,7 +6207,7 @@ ER_TOO_MANY_CONCURRENT_TRXS
|
||||
WARN_NON_ASCII_SEPARATOR_NOT_IMPLEMENTED
|
||||
eng "Non-ASCII separator arguments are not fully supported"
|
||||
ER_SAME_NAME_PARTITION_FIELD
|
||||
eng "Duplicate partition field name %-.192s"
|
||||
eng "Duplicate partition field name '%-.192s'"
|
||||
ER_PARTITION_COLUMN_LIST_ERROR
|
||||
eng "Inconsistency in usage of column lists for partitioning"
|
||||
ER_WRONG_TYPE_COLUMN_VALUE_ERROR
|
||||
@ -6220,3 +6220,5 @@ ER_TOO_MANY_VALUES_ERROR
|
||||
eng "Cannot have more than one value for this type of %-.64s partitioning"
|
||||
ER_ROW_SINGLE_PARTITION_FIELD_ERROR
|
||||
eng "Row expressions in VALUES IN only allowed for multi-field column partitioning"
|
||||
ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
|
||||
eng "Field '%-.192s' is of a not allowed type for this type of partitioning"
|
||||
|
@ -150,6 +150,38 @@ static int cmp_rec_and_tuple_prune(part_column_list_val *val,
|
||||
bool tail_is_min);
|
||||
|
||||
#ifdef WITH_PARTITION_STORAGE_ENGINE
|
||||
/*
|
||||
Convert constants in VALUES definition to the character set the
|
||||
corresponding field uses.
|
||||
|
||||
SYNOPSIS
|
||||
convert_charset_partition_constant()
|
||||
item Item to convert
|
||||
cs Character set to convert to
|
||||
|
||||
RETURN VALUE
|
||||
NULL Error
|
||||
item New converted item
|
||||
*/
|
||||
|
||||
Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs)
|
||||
{
|
||||
THD *thd= current_thd;
|
||||
Name_resolution_context *context= &thd->lex->current_select->context;
|
||||
TABLE_LIST *save_list= context->table_list;
|
||||
const char *save_where= thd->where;
|
||||
|
||||
item= item->safe_charset_converter(cs);
|
||||
context->table_list= NULL;
|
||||
thd->where= "convert character set partition constant";
|
||||
if (!item || item->fix_fields(thd, (Item**)NULL))
|
||||
item= NULL;
|
||||
thd->where= save_where;
|
||||
context->table_list= save_list;
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
A support function to check if a name is in a list of strings
|
||||
|
||||
@ -512,7 +544,9 @@ static bool set_up_field_array(TABLE *table,
|
||||
do
|
||||
{
|
||||
field_name= it++;
|
||||
if (!strcmp(field_name, field->field_name))
|
||||
if (!my_strcasecmp(system_charset_info,
|
||||
field_name,
|
||||
field->field_name))
|
||||
break;
|
||||
} while (++inx < num_fields);
|
||||
if (inx == num_fields)
|
||||
@ -1984,11 +2018,67 @@ static int add_partition_options(File fptr, partition_element *p_elem)
|
||||
return err + add_engine(fptr,p_elem->engine_type);
|
||||
}
|
||||
|
||||
static int check_part_field(Create_field *sql_field,
|
||||
bool *need_cs_check)
|
||||
{
|
||||
*need_cs_check= FALSE;
|
||||
if (sql_field->sql_type == MYSQL_TYPE_TIMESTAMP)
|
||||
goto error;
|
||||
if (sql_field->sql_type < MYSQL_TYPE_VARCHAR ||
|
||||
sql_field->sql_type == MYSQL_TYPE_NEWDECIMAL)
|
||||
return FALSE;
|
||||
if (sql_field->sql_type >= MYSQL_TYPE_TINY_BLOB &&
|
||||
sql_field->sql_type <= MYSQL_TYPE_BLOB)
|
||||
{
|
||||
my_error(ER_BLOB_FIELD_IN_PART_FUNC_ERROR, MYF(0));
|
||||
return TRUE;
|
||||
}
|
||||
switch (sql_field->sql_type)
|
||||
{
|
||||
case MYSQL_TYPE_VARCHAR:
|
||||
case MYSQL_TYPE_STRING:
|
||||
case MYSQL_TYPE_VAR_STRING:
|
||||
if (sql_field->length > MAX_STR_SIZE_PF)
|
||||
goto error;
|
||||
*need_cs_check= TRUE;
|
||||
return FALSE;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
error:
|
||||
my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
|
||||
sql_field->field_name);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static Create_field* get_sql_field(char *field_name,
|
||||
Alter_info *alter_info)
|
||||
{
|
||||
List_iterator<Create_field> it(alter_info->create_list);
|
||||
Create_field *sql_field;
|
||||
DBUG_ENTER("get_sql_field");
|
||||
|
||||
while ((sql_field= it++))
|
||||
{
|
||||
if (!(my_strcasecmp(system_charset_info,
|
||||
sql_field->field_name,
|
||||
field_name)))
|
||||
{
|
||||
DBUG_RETURN(sql_field);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
static int add_column_list_values(File fptr, partition_info *part_info,
|
||||
part_elem_value *list_value)
|
||||
part_elem_value *list_value,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info)
|
||||
{
|
||||
int err= 0;
|
||||
uint i;
|
||||
List_iterator<char> it(part_info->part_field_list);
|
||||
uint num_elements= part_info->part_field_list.elements;
|
||||
bool use_parenthesis= (part_info->part_type == LIST_PARTITION &&
|
||||
part_info->num_columns > 1U);
|
||||
@ -1998,6 +2088,7 @@ static int add_column_list_values(File fptr, partition_info *part_info,
|
||||
for (i= 0; i < num_elements; i++)
|
||||
{
|
||||
part_column_list_val *col_val= &list_value->col_val_array[i];
|
||||
char *field_name= it++;
|
||||
if (col_val->max_value)
|
||||
err+= add_string(fptr, partition_keywords[PKW_MAXVALUE].str);
|
||||
else if (col_val->null_value)
|
||||
@ -2011,7 +2102,45 @@ static int add_column_list_values(File fptr, partition_info *part_info,
|
||||
err+= add_string(fptr, "NULL");
|
||||
else
|
||||
{
|
||||
String *res= item_expr->val_str(&str);
|
||||
String *res;
|
||||
CHARSET_INFO *field_cs;
|
||||
|
||||
/*
|
||||
This function is called at a very early stage, even before
|
||||
we have prepared the sql_field objects. Thus we have to
|
||||
find the proper sql_field object and get the character set
|
||||
from that object.
|
||||
*/
|
||||
if (create_info)
|
||||
{
|
||||
Create_field *sql_field;
|
||||
bool need_cs_check= FALSE;
|
||||
|
||||
if (!(sql_field= get_sql_field(field_name,
|
||||
alter_info)))
|
||||
{
|
||||
my_error(ER_FIELD_NOT_FOUND_PART_ERROR, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
if (check_part_field(sql_field, &need_cs_check))
|
||||
return 1;
|
||||
if (need_cs_check)
|
||||
field_cs= get_sql_field_charset(sql_field, create_info);
|
||||
else
|
||||
field_cs= NULL;
|
||||
}
|
||||
else
|
||||
field_cs= part_info->part_field_array[i]->charset();
|
||||
if (field_cs && field_cs != item_expr->collation.collation)
|
||||
{
|
||||
if (!(item_expr= convert_charset_partition_constant(item_expr,
|
||||
field_cs)))
|
||||
{
|
||||
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
res= item_expr->val_str(&str);
|
||||
if (!res)
|
||||
{
|
||||
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
|
||||
@ -2033,7 +2162,9 @@ static int add_column_list_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,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info)
|
||||
{
|
||||
int err= 0;
|
||||
|
||||
@ -2045,7 +2176,8 @@ static int add_partition_values(File fptr, partition_info *part_info,
|
||||
List_iterator<part_elem_value> list_val_it(p_elem->list_val_list);
|
||||
part_elem_value *list_value= list_val_it++;
|
||||
err+= add_begin_parenthesis(fptr);
|
||||
err+= add_column_list_values(fptr, part_info, list_value);
|
||||
err+= add_column_list_values(fptr, part_info, list_value,
|
||||
create_info, alter_info);
|
||||
err+= add_end_parenthesis(fptr);
|
||||
}
|
||||
else
|
||||
@ -2087,7 +2219,8 @@ static int add_partition_values(File fptr, partition_info *part_info,
|
||||
part_elem_value *list_value= list_val_it++;
|
||||
|
||||
if (part_info->column_list)
|
||||
err+= add_column_list_values(fptr, part_info, list_value);
|
||||
err+= add_column_list_values(fptr, part_info, list_value,
|
||||
create_info, alter_info);
|
||||
else
|
||||
{
|
||||
if (!list_value->unsigned_flag)
|
||||
@ -2116,6 +2249,8 @@ end:
|
||||
use_sql_alloc Allocate buffer from sql_alloc if true
|
||||
otherwise use my_malloc
|
||||
show_partition_options Should we display partition options
|
||||
create_info Info generated by parser
|
||||
alter_info Info generated by parser
|
||||
|
||||
RETURN VALUES
|
||||
NULL error
|
||||
@ -2144,7 +2279,9 @@ end:
|
||||
char *generate_partition_syntax(partition_info *part_info,
|
||||
uint *buf_length,
|
||||
bool use_sql_alloc,
|
||||
bool show_partition_options)
|
||||
bool show_partition_options,
|
||||
HA_CREATE_INFO *create_info,
|
||||
Alter_info *alter_info)
|
||||
{
|
||||
uint i,j, tot_num_parts, num_subparts;
|
||||
partition_element *part_elem;
|
||||
@ -2263,7 +2400,8 @@ char *generate_partition_syntax(partition_info *part_info,
|
||||
first= FALSE;
|
||||
err+= add_partition(fptr);
|
||||
err+= add_name_string(fptr, part_elem->partition_name);
|
||||
err+= add_partition_values(fptr, part_info, part_elem);
|
||||
err+= add_partition_values(fptr, part_info, part_elem,
|
||||
create_info, alter_info);
|
||||
if (!part_info->is_sub_partitioned() ||
|
||||
part_info->use_default_subpartitions)
|
||||
{
|
||||
|
@ -67,9 +67,6 @@ bool check_partition_info(partition_info *part_info,handlerton **eng_type,
|
||||
TABLE *table, handler *file, HA_CREATE_INFO *info);
|
||||
void set_linear_hash_mask(partition_info *part_info, uint num_parts);
|
||||
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 show_partition_options);
|
||||
bool partition_key_modified(TABLE *table, const MY_BITMAP *fields);
|
||||
void get_partition_set(const TABLE *table, uchar *buf, const uint index,
|
||||
const key_range *key_spec,
|
||||
@ -96,6 +93,7 @@ bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
|
||||
|
||||
bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
|
||||
bool field_is_partition_charset(Field *field);
|
||||
Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs);
|
||||
|
||||
/*
|
||||
A "Get next" function for partition iterator.
|
||||
|
@ -1465,7 +1465,8 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
|
||||
((part_syntax= generate_partition_syntax(table->part_info,
|
||||
&part_syntax_len,
|
||||
FALSE,
|
||||
show_table_options))))
|
||||
show_table_options,
|
||||
NULL, NULL))))
|
||||
{
|
||||
packet->append(STRING_WITH_LEN("\n/*!50100"));
|
||||
packet->append(part_syntax, part_syntax_len);
|
||||
@ -4847,16 +4848,23 @@ get_partition_column_description(partition_info *part_info,
|
||||
{
|
||||
char buffer[MAX_STR_SIZE_PF];
|
||||
String str(buffer, sizeof(buffer), &my_charset_bin);
|
||||
String *res= col_val->item_expression->val_str(&str);
|
||||
Item *item= col_val->item_expression;
|
||||
|
||||
if (!(item= part_info->get_column_item(item,
|
||||
part_info->part_field_array[i])))
|
||||
{
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
String *res= item->val_str(&str);
|
||||
if (!res)
|
||||
{
|
||||
my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (col_val->item_expression->result_type() == STRING_RESULT)
|
||||
if (item->result_type() == STRING_RESULT)
|
||||
tmp_str.append("'");
|
||||
tmp_str.append(*res);
|
||||
if (col_val->item_expression->result_type() == STRING_RESULT)
|
||||
if (item->result_type() == STRING_RESULT)
|
||||
tmp_str.append("'");
|
||||
}
|
||||
if (i != num_elements - 1)
|
||||
|
@ -1583,7 +1583,9 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
||||
{
|
||||
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
||||
&syntax_len,
|
||||
TRUE, TRUE)))
|
||||
TRUE, TRUE,
|
||||
lpt->create_info,
|
||||
lpt->alter_info)))
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -1675,7 +1677,9 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
|
||||
char *tmp_part_syntax_str;
|
||||
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
||||
&syntax_len,
|
||||
TRUE, TRUE)))
|
||||
TRUE, TRUE,
|
||||
lpt->create_info,
|
||||
lpt->alter_info)))
|
||||
{
|
||||
error= 1;
|
||||
goto err;
|
||||
@ -2494,6 +2498,39 @@ int prepare_create_field(Create_field *sql_field,
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Get character set from field object generated by parser using
|
||||
default values when not set.
|
||||
|
||||
SYNOPSIS
|
||||
get_sql_field_charset()
|
||||
sql_field The sql_field object
|
||||
create_info Info generated by parser
|
||||
|
||||
RETURN VALUES
|
||||
cs Character set
|
||||
*/
|
||||
|
||||
CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
|
||||
HA_CREATE_INFO *create_info)
|
||||
{
|
||||
CHARSET_INFO *cs= sql_field->charset;
|
||||
|
||||
if (!cs)
|
||||
cs= create_info->default_table_charset;
|
||||
/*
|
||||
table_charset is set only in ALTER TABLE t1 CONVERT TO CHARACTER SET csname
|
||||
if we want change character set for all varchar/char columns.
|
||||
But the table charset must not affect the BLOB fields, so don't
|
||||
allow to change my_charset_bin to somethig else.
|
||||
*/
|
||||
if (create_info->table_charset && cs != &my_charset_bin)
|
||||
cs= create_info->table_charset;
|
||||
return cs;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Preparation for table creation
|
||||
|
||||
@ -2557,18 +2594,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
executing a prepared statement for the second time.
|
||||
*/
|
||||
sql_field->length= sql_field->char_length;
|
||||
if (!sql_field->charset)
|
||||
sql_field->charset= create_info->default_table_charset;
|
||||
/*
|
||||
table_charset is set in ALTER TABLE if we want change character set
|
||||
for all varchar/char columns.
|
||||
But the table charset must not affect the BLOB fields, so don't
|
||||
allow to change my_charset_bin to somethig else.
|
||||
*/
|
||||
if (create_info->table_charset && sql_field->charset != &my_charset_bin)
|
||||
sql_field->charset= create_info->table_charset;
|
||||
|
||||
save_cs= sql_field->charset;
|
||||
save_cs= sql_field->charset= get_sql_field_charset(sql_field,
|
||||
create_info);
|
||||
if ((sql_field->flags & BINCMP_FLAG) &&
|
||||
!(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
|
||||
MY_CS_BINSORT,MYF(0))))
|
||||
@ -3617,6 +3644,9 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
}
|
||||
if (check_engine(thd, table_name, create_info))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
set_table_default_charset(thd, create_info, (char*) db);
|
||||
|
||||
db_options= create_info->table_options;
|
||||
if (create_info->row_type == ROW_TYPE_DYNAMIC)
|
||||
db_options|=HA_OPTION_PACK_RECORD;
|
||||
@ -3720,7 +3750,9 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
*/
|
||||
if (!(part_syntax_buf= generate_partition_syntax(part_info,
|
||||
&syntax_len,
|
||||
TRUE, TRUE)))
|
||||
TRUE, TRUE,
|
||||
create_info,
|
||||
alter_info)))
|
||||
goto err;
|
||||
part_info->part_info_string= part_syntax_buf;
|
||||
part_info->part_info_len= syntax_len;
|
||||
@ -3787,8 +3819,6 @@ bool mysql_create_table_no_lock(THD *thd,
|
||||
}
|
||||
#endif
|
||||
|
||||
set_table_default_charset(thd, create_info, (char*) db);
|
||||
|
||||
if (mysql_prepare_create_table(thd, create_info, alter_info,
|
||||
internal_tmp_table,
|
||||
&db_options, file,
|
||||
|
Loading…
x
Reference in New Issue
Block a user