mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Merge 5.2->5.3
This commit is contained in:
@ -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 @@ public:
|
||||
{
|
||||
return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
|
||||
}
|
||||
uint virtual_col_expr_maxlen()
|
||||
{
|
||||
return 255 - FRM_VCOL_HEADER_SIZE(interval != NULL);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
20
sql/table.cc
20
sql/table.cc
@ -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
|
||||
|
Reference in New Issue
Block a user