summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2012-06-24 09:10:11 -0700
committerIgor Babaev <igor@askmonty.org>2012-06-24 09:10:11 -0700
commit2954ed1ec977dab2e6594343455d100d56051473 (patch)
tree71bfa7a627ca5633dba3fa0bb9d8e21de7589c88
parentf8f65accf99821386ad2cffdf0c3f473e8f33064 (diff)
parent20f3f4a273202ef539314acbbdbb67ab91376ab6 (diff)
downloadmariadb-git-2954ed1ec977dab2e6594343455d100d56051473.tar.gz
Merge 5.3->5.5.
-rw-r--r--mysql-test/suite/vcol/r/vcol_misc.result36
-rw-r--r--mysql-test/suite/vcol/t/vcol_misc.test23
-rw-r--r--sql/field.h4
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/table.cc20
-rw-r--r--sql/unireg.cc23
-rw-r--r--sql/unireg.h5
-rw-r--r--storage/myisam/mi_keycache.c2
8 files changed, 95 insertions, 20 deletions
diff --git a/mysql-test/suite/vcol/r/vcol_misc.result b/mysql-test/suite/vcol/r/vcol_misc.result
index c27b36089c6..17b38b7d7af 100644
--- a/mysql-test/suite/vcol/r/vcol_misc.result
+++ b/mysql-test/suite/vcol/r/vcol_misc.result
@@ -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));
diff --git a/mysql-test/suite/vcol/t/vcol_misc.test b/mysql-test/suite/vcol/t/vcol_misc.test
index 6f576f61513..01404046cde 100644
--- a/mysql-test/suite/vcol/t/vcol_misc.test
+++ b/mysql-test/suite/vcol/t/vcol_misc.test
@@ -156,6 +156,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
#
diff --git a/sql/field.h b/sql/field.h
index dbb2e030f74..3838c924419 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -2244,6 +2244,10 @@ public:
{
return (flags & (BINCMP_FLAG | BINARY_FLAG)) != 0;
}
+ uint virtual_col_expr_maxlen()
+ {
+ return 255 - FRM_VCOL_HEADER_SIZE(interval != NULL);
+ }
private:
const String empty_set_string;
};
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 545e9e3c7b8..efb45f96345 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -990,7 +990,7 @@ class SQL_SELECT :public Sql_alloc {
key_map quick_keys; // Possible quick keys
key_map needed_reg; // Possible quick keys after prev tables.
table_map const_tables,read_tables;
- bool free_cond;
+ bool free_cond; /* Currently not used and always FALSE */
SQL_SELECT();
~SQL_SELECT();
diff --git a/sql/table.cc b/sql/table.cc
index bc7ad0e5831..2a11098caed 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1439,25 +1439,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 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 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++;
diff --git a/sql/unireg.cc b/sql/unireg.cc
index c9b0f91d9f7..edcfe9eb934 100644
--- a/sql/unireg.cc
+++ b/sql/unireg.cc
@@ -726,18 +726,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);
}
/*
@@ -746,7 +747,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;
@@ -949,8 +950,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);
@@ -1055,17 +1057,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,
diff --git a/sql/unireg.h b/sql/unireg.h
index f8317a89c8c..950cfc2cc31 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -162,10 +162,7 @@ typedef struct st_ha_create_information HA_CREATE_INFO;
#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 */
diff --git a/storage/myisam/mi_keycache.c b/storage/myisam/mi_keycache.c
index a2422b71bbf..b45f0efa2f7 100644
--- a/storage/myisam/mi_keycache.c
+++ b/storage/myisam/mi_keycache.c
@@ -76,6 +76,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))
{
@@ -83,6 +84,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