Commit 20f3f4a2 authored by Igor Babaev's avatar Igor Babaev

Merge 5.2->5.3

parents e7bfda3b d9c3a3e3
......@@ -146,6 +146,42 @@ table_schema table_name column_name column_type extra
test t2 a int(11)
test t2 b int(11) VIRTUAL
DROP TABLE t1,t2;
create table t1 (
a int not null, b char(2) not null,
c enum('Y','N') as (case when b = 'aa' then 'Y' else 'N' end) persistent
);
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
`b` char(2) NOT NULL,
`c` enum('Y','N') AS (case when b = 'aa' then 'Y' else 'N' end) PERSISTENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1(a,b) values (1,'bb'), (2,'aa'), (3,'cc');
select * from t1;
a b c
1 bb N
2 aa Y
3 cc N
create table t2 (
a int, b int,
c set("y","n")
as (if(a=0,if(b=0,('n,n'),('n,y')),if(b=0,('y,n'),('y,y')))) persistent
);
show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) DEFAULT NULL,
`b` int(11) DEFAULT NULL,
`c` set('y','n') AS (if(a=0,if(b=0,('n,n'),('n,y')),if(b=0,('y,n'),('y,y')))) PERSISTENT
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t2(a,b) values (7,0), (2,3), (0,1);
select * from t2;
a b c
7 0 y,n
2 3 y
0 1 y,n
drop table t1,t2;
create table t1 (a int, b int);
insert into t1 values (3, 30), (4, 20), (1, 20);
create table t2 (c int, d int, v int as (d+1), index idx(c));
......
......@@ -155,6 +155,29 @@ SELECT table_schema, table_name, column_name, column_type, extra
DROP TABLE t1,t2;
#
# Bug mdev-354: virtual columns of ENUM and SET types
#
create table t1 (
a int not null, b char(2) not null,
c enum('Y','N') as (case when b = 'aa' then 'Y' else 'N' end) persistent
);
show create table t1;
insert into t1(a,b) values (1,'bb'), (2,'aa'), (3,'cc');
select * from t1;
create table t2 (
a int, b int,
c set("y","n")
as (if(a=0,if(b=0,('n,n'),('n,y')),if(b=0,('y,n'),('y,y')))) persistent
);
show create table t2;
insert into t2(a,b) values (7,0), (2,3), (0,1);
select * from t2;
drop table t1,t2;
#
# SELECT that uses a virtual column and executed with BKA
#
......
......@@ -2217,6 +2217,10 @@ class Create_field :public Sql_alloc
{
return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
}
uint virtual_col_expr_maxlen()
{
return 255 - FRM_VCOL_HEADER_SIZE(interval != NULL);
}
};
......
......@@ -1257,25 +1257,33 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head,
{
/*
Get virtual column data stored in the .frm file as follows:
byte 1 = 1 (always 1 to allow for future extensions)
byte 1 = 1 | 2
byte 2 = sql_type
byte 3 = flags (as of now, 0 - no flags, 1 - field is physically stored)
byte 4-... = virtual column expression (text data)
[byte 4] = optional interval_id for sql_type (only if byte 1 == 2)
next byte ... = virtual column expression (text data)
*/
vcol_info= new Virtual_column_info();
if ((uint)vcol_screen_pos[0] != 1)
bool opt_interval_id= (uint)vcol_screen_pos[0] == 2;
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
if (opt_interval_id)
interval_nr= (uint)vcol_screen_pos[3];
else if ((uint)vcol_screen_pos[0] != 1)
{
error= 4;
goto free_and_err;
}
field_type= (enum_field_types) (uchar) vcol_screen_pos[1];
fld_stored_in_db= (bool) (uint) vcol_screen_pos[2];
vcol_expr_length= vcol_info_length-(uint)FRM_VCOL_HEADER_SIZE;
vcol_expr_length= vcol_info_length -
(uint)(FRM_VCOL_HEADER_SIZE(opt_interval_id));
if (!(vcol_info->expr_str.str=
(char *)memdup_root(&share->mem_root,
vcol_screen_pos+(uint)FRM_VCOL_HEADER_SIZE,
vcol_screen_pos +
(uint) FRM_VCOL_HEADER_SIZE(opt_interval_id),
vcol_expr_length)))
goto free_and_err;
if (opt_interval_id)
interval_nr= (uint) vcol_screen_pos[3];
vcol_info->expr_str.length= vcol_expr_length;
vcol_screen_pos+= vcol_info_length;
share->vfields++;
......
......@@ -670,18 +670,19 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type,
}
if (field->vcol_info)
{
uint col_expr_maxlen= field->virtual_col_expr_maxlen();
tmp_len=
system_charset_info->cset->charpos(system_charset_info,
field->vcol_info->expr_str.str,
field->vcol_info->expr_str.str +
field->vcol_info->expr_str.length,
VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
col_expr_maxlen);
if (tmp_len < field->vcol_info->expr_str.length)
{
my_error(ER_WRONG_STRING_LENGTH, MYF(0),
field->vcol_info->expr_str.str,"VIRTUAL COLUMN EXPRESSION",
(uint) VIRTUAL_COLUMN_EXPRESSION_MAXLEN);
col_expr_maxlen);
DBUG_RETURN(1);
}
/*
......@@ -690,7 +691,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type,
expressions saved in the frm file for virtual columns.
*/
vcol_info_length+= field->vcol_info->expr_str.length+
(uint)FRM_VCOL_HEADER_SIZE;
FRM_VCOL_HEADER_SIZE(field->interval!=NULL);
}
totlength+= field->length;
......@@ -886,8 +887,9 @@ static bool pack_fields(File file, List<Create_field> &create_fields,
the additional data saved for the virtual field
*/
buff[12]= cur_vcol_expr_len= field->vcol_info->expr_str.length +
(uint)FRM_VCOL_HEADER_SIZE;
vcol_info_length+= cur_vcol_expr_len+(uint)FRM_VCOL_HEADER_SIZE;
FRM_VCOL_HEADER_SIZE(field->interval!=NULL);
vcol_info_length+= cur_vcol_expr_len +
FRM_VCOL_HEADER_SIZE(field->interval!=NULL);
buff[13]= (uchar) MYSQL_TYPE_VIRTUAL;
}
int2store(buff+15, field->comment.length);
......@@ -992,17 +994,20 @@ static bool pack_fields(File file, List<Create_field> &create_fields,
{
/*
Pack each virtual field as follows:
byte 1 = 1 (always 1 to allow for future extensions)
byte 1 = interval_id == 0 ? 1 : 2
byte 2 = sql_type
byte 3 = flags (as of now, 0 - no flags, 1 - field is physically stored)
byte 4-... = virtual column expression (text data)
[byte 4] = possible interval_id for sql_type
next byte ... = virtual column expression (text data)
*/
if (field->vcol_info && field->vcol_info->expr_str.length)
{
buff[0]= (uchar)1;
buff[0]= (uchar)(1 + test(field->interval_id));
buff[1]= (uchar) field->sql_type;
buff[2]= (uchar) field->stored_in_db;
if (my_write(file, buff, 3, MYF_RW))
if (field->interval_id)
buff[3]= (uchar) field->interval_id;
if (my_write(file, buff, 3 + test(field->interval_id), MYF_RW))
DBUG_RETURN(1);
if (my_write(file,
(uchar*) field->vcol_info->expr_str.str,
......
......@@ -217,10 +217,7 @@
#define DEFAULT_KEY_CACHE_NAME "default"
/* The length of the header part for each virtual column in the .frm file */
#define FRM_VCOL_HEADER_SIZE 3
/* Maximum length of the defining expression for a virtual columns */
#define VIRTUAL_COLUMN_EXPRESSION_MAXLEN 255 - FRM_VCOL_HEADER_SIZE
#define FRM_VCOL_HEADER_SIZE(b) (3 + test(b))
/* Include prototypes for unireg */
......
......@@ -75,6 +75,7 @@ int mi_assign_to_key_cache(MI_INFO *info,
in the old key cache.
*/
pthread_mutex_lock(&share->key_cache->op_lock);
if (flush_key_blocks(share->key_cache, share->kfile, &share->dirty_part_map,
FLUSH_RELEASE))
{
......@@ -82,6 +83,7 @@ int mi_assign_to_key_cache(MI_INFO *info,
mi_print_error(info->s, HA_ERR_CRASHED);
mi_mark_crashed(info); /* Mark that table must be checked */
}
pthread_mutex_unlock(&share->key_cache->op_lock);
/*
Flush the new key cache for this file. This is needed to ensure
......
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