At lp:~maria-captains/maria/5.5
------------------------------------------------------------
revno: 4343
revision-id: sergii@xxxxxxxxx-20141108185442-37i07fh0bvm2atjr
parent: sergii@xxxxxxxxx-20141102163302-8ukz7pi4mwsx89n0
committer: Sergei Golubchik <sergii@xxxxxxxxx>
branch nick: 5.5
timestamp: Sat 2014-11-08 19:54:42 +0100
message:
MDEV-6179: dynamic columns functions/cast()/convert() doesn't play nice with CREATE/ALTER TABLE
When parsing a field declaration, grab type information from LEX before it's overwritten
by further rules. Pass type information through the parser stack to the rule that needs it.
=== modified file 'mysql-test/r/create.result'
--- a/mysql-test/r/create.result 2013-05-11 17:31:50 +0000
+++ b/mysql-test/r/create.result 2014-11-08 18:54:42 +0000
@@ -2430,3 +2430,50 @@ a b
1 1
unlock tables;
drop table t1,t2;
+#
+# MDEV-6179: dynamic columns functions/cast()/convert() doesn't
+# play nice with CREATE/ALTER TABLE
+#
+create table t1 (
+color char(32) as (COLUMN_GET(dynamic_cols, 1 as char)) persistent,
+cl char(32) as (COLUMN_GET(COLUMN_ADD(COLUMN_CREATE(1 , 'blue' as char), 2, 'ttt'), i as char)) persistent,
+item_name varchar(32) primary key, -- A common attribute for all items
+i int,
+dynamic_cols blob -- Dynamic columns will be stored here
+);
+INSERT INTO t1(item_name, dynamic_cols, i) VALUES
+('MariaDB T-shirt', COLUMN_CREATE(1, 'blue', 2, 'XL'), 1);
+INSERT INTO t1(item_name, dynamic_cols, i) VALUES
+('Thinkpad Laptop', COLUMN_CREATE(1, 'black', 3, 500), 2);
+select item_name, color, cl from t1;
+item_name color cl
+MariaDB T-shirt blue blue
+Thinkpad Laptop black ttt
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `color` char(32) AS (COLUMN_GET(dynamic_cols, 1 as char)) PERSISTENT,
+ `cl` char(32) AS (COLUMN_GET(COLUMN_ADD(COLUMN_CREATE(1 , 'blue' as char), 2, 'ttt'), i as char)) PERSISTENT,
+ `item_name` varchar(32) NOT NULL,
+ `i` int(11) DEFAULT NULL,
+ `dynamic_cols` blob,
+ PRIMARY KEY (`item_name`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
+create table t1 (
+n int,
+c char(32) as (convert(cast(n as char), char)) persistent
+);
+insert into t1(n) values (1),(2),(3);
+select * from t1;
+n c
+1 1
+2 2
+3 3
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `n` int(11) DEFAULT NULL,
+ `c` char(32) AS (convert(cast(n as char), char)) PERSISTENT
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t1;
=== modified file 'mysql-test/t/create.test'
--- a/mysql-test/t/create.test 2012-12-17 20:34:56 +0000
+++ b/mysql-test/t/create.test 2014-11-08 18:54:42 +0000
@@ -2021,3 +2021,35 @@ connection default;
select * from t1;
unlock tables;
drop table t1,t2;
+
+--echo #
+--echo # MDEV-6179: dynamic columns functions/cast()/convert() doesn't
+--echo # play nice with CREATE/ALTER TABLE
+--echo #
+create table t1 (
+ color char(32) as (COLUMN_GET(dynamic_cols, 1 as char)) persistent,
+ cl char(32) as (COLUMN_GET(COLUMN_ADD(COLUMN_CREATE(1 , 'blue' as char), 2, 'ttt'), i as char)) persistent,
+ item_name varchar(32) primary key, -- A common attribute for all items
+ i int,
+ dynamic_cols blob -- Dynamic columns will be stored here
+);
+INSERT INTO t1(item_name, dynamic_cols, i) VALUES
+ ('MariaDB T-shirt', COLUMN_CREATE(1, 'blue', 2, 'XL'), 1);
+INSERT INTO t1(item_name, dynamic_cols, i) VALUES
+ ('Thinkpad Laptop', COLUMN_CREATE(1, 'black', 3, 500), 2);
+
+select item_name, color, cl from t1;
+show create table t1;
+
+drop table t1;
+
+create table t1 (
+ n int,
+ c char(32) as (convert(cast(n as char), char)) persistent
+);
+insert into t1(n) values (1),(2),(3);
+
+select * from t1;
+show create table t1;
+
+drop table t1;
=== modified file 'sql/sql_lex.h'
--- a/sql/sql_lex.h 2014-08-02 19:26:16 +0000
+++ b/sql/sql_lex.h 2014-11-08 18:54:42 +0000
@@ -105,6 +105,15 @@ struct sys_var_with_base
LEX_STRING base_name;
};
+struct LEX_TYPE
+{
+ enum enum_field_types type;
+ char *length, *dec;
+ CHARSET_INFO *charset;
+ void set(int t, char *l, char *d, CHARSET_INFO *cs)
+ { type= (enum_field_types)t; length= l; dec= d; charset= cs; }
+};
+
#ifdef MYSQL_SERVER
/*
The following hack is needed because mysql_yacc.cc does not define
=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy 2014-08-02 19:26:16 +0000
+++ b/sql/sql_yacc.yy 2014-11-08 18:54:42 +0000
@@ -737,6 +737,7 @@ static bool add_create_index (LEX *lex,
LEX_STRING lex_str;
LEX_STRING *lex_str_ptr;
LEX_SYMBOL symbol;
+ LEX_TYPE lex_type;
Table_ident *table;
char *simple_string;
Item *item;
@@ -1471,13 +1472,15 @@ bool my_yyoverflow(short **a, YYSTYPE **
%type <string>
text_string opt_gconcat_separator
+%type <lex_type> field_def
+
%type <num>
type type_with_opt_collate int_type real_type order_dir lock_option
udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog
opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option
- start_transaction_opts field_def
+ start_transaction_opts
union_opt select_derived_init option_type2
opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
@@ -5483,11 +5486,11 @@ field_spec:
field_def
{
LEX *lex=Lex;
- if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3,
- lex->length,lex->dec,lex->type,
+ if (add_field_to_list(lex->thd, &$1, $3.type,
+ $3.length, $3.dec, lex->type,
lex->default_value, lex->on_update_value,
&lex->comment,
- lex->change,&lex->interval_list,lex->charset,
+ lex->change, &lex->interval_list, $3.charset,
lex->uint_geom_type,
lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
@@ -5495,13 +5498,15 @@ field_spec:
;
field_def:
- type opt_attribute {}
- | type opt_generated_always AS '(' virtual_column_func ')'
- vcol_opt_specifier
- vcol_opt_attribute
- {
- $$= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
- Lex->vcol_info->set_field_type((enum enum_field_types) $1);
+ type opt_attribute
+ { $$.set($1, Lex->length, Lex->dec, Lex->charset); }
+ | type opt_generated_always AS
+ { $<lex_type>$.set($1, Lex->length, Lex->dec, Lex->charset); }
+ '(' virtual_column_func ')' vcol_opt_specifier vcol_opt_attribute
+ {
+ $$= $<lex_type>4;
+ Lex->vcol_info->set_field_type($$.type);
+ $$.type= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
}
;
@@ -6892,11 +6897,11 @@ alter_list_item:
{
LEX *lex=Lex;
if (add_field_to_list(lex->thd,&$3,
- (enum enum_field_types) $5,
- lex->length,lex->dec,lex->type,
+ $5.type,
+ $5.length, $5.dec, lex->type,
lex->default_value, lex->on_update_value,
&lex->comment,
- $3.str, &lex->interval_list, lex->charset,
+ $3.str, &lex->interval_list, $5.charset,
lex->uint_geom_type,
lex->vcol_info, lex->option_list))
MYSQL_YYABORT;
_______________________________________________
commits mailing list
commits@xxxxxxxxxxx
https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits