1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

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.
This commit is contained in:
Sergei Golubchik
2014-11-08 19:54:42 +01:00
parent b99328bbf8
commit 360c49c1b9
4 changed files with 106 additions and 13 deletions

View File

@ -2430,3 +2430,50 @@ a b
1 1 1 1
unlock tables; unlock tables;
drop table t1,t2; 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;

View File

@ -2021,3 +2021,35 @@ connection default;
select * from t1; select * from t1;
unlock tables; unlock tables;
drop table t1,t2; 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;

View File

@ -105,6 +105,15 @@ struct sys_var_with_base
LEX_STRING base_name; 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 #ifdef MYSQL_SERVER
/* /*
The following hack is needed because mysql_yacc.cc does not define The following hack is needed because mysql_yacc.cc does not define

View File

@ -737,6 +737,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
LEX_STRING lex_str; LEX_STRING lex_str;
LEX_STRING *lex_str_ptr; LEX_STRING *lex_str_ptr;
LEX_SYMBOL symbol; LEX_SYMBOL symbol;
LEX_TYPE lex_type;
Table_ident *table; Table_ident *table;
char *simple_string; char *simple_string;
Item *item; Item *item;
@ -1471,13 +1472,15 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <string> %type <string>
text_string opt_gconcat_separator text_string opt_gconcat_separator
%type <lex_type> field_def
%type <num> %type <num>
type type_with_opt_collate int_type real_type order_dir lock_option type type_with_opt_collate int_type real_type order_dir lock_option
udf_type if_exists opt_local opt_table_options table_options udf_type if_exists opt_local opt_table_options table_options
table_option opt_if_not_exists opt_no_write_to_binlog table_option opt_if_not_exists opt_no_write_to_binlog
opt_temporary all_or_any opt_distinct opt_temporary all_or_any opt_distinct
opt_ignore_leaves fulltext_options spatial_type union_option opt_ignore_leaves fulltext_options spatial_type union_option
start_transaction_opts field_def start_transaction_opts
union_opt select_derived_init option_type2 union_opt select_derived_init option_type2
opt_natural_language_mode opt_query_expansion opt_natural_language_mode opt_query_expansion
opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
@ -5483,11 +5486,11 @@ field_spec:
field_def field_def
{ {
LEX *lex=Lex; LEX *lex=Lex;
if (add_field_to_list(lex->thd, &$1, (enum enum_field_types) $3, if (add_field_to_list(lex->thd, &$1, $3.type,
lex->length,lex->dec,lex->type, $3.length, $3.dec, lex->type,
lex->default_value, lex->on_update_value, lex->default_value, lex->on_update_value,
&lex->comment, &lex->comment,
lex->change,&lex->interval_list,lex->charset, lex->change, &lex->interval_list, $3.charset,
lex->uint_geom_type, lex->uint_geom_type,
lex->vcol_info, lex->option_list)) lex->vcol_info, lex->option_list))
MYSQL_YYABORT; MYSQL_YYABORT;
@ -5495,13 +5498,15 @@ field_spec:
; ;
field_def: field_def:
type opt_attribute {} type opt_attribute
| type opt_generated_always AS '(' virtual_column_func ')' { $$.set($1, Lex->length, Lex->dec, Lex->charset); }
vcol_opt_specifier | type opt_generated_always AS
vcol_opt_attribute { $<lex_type>$.set($1, Lex->length, Lex->dec, Lex->charset); }
'(' virtual_column_func ')' vcol_opt_specifier vcol_opt_attribute
{ {
$$= (enum enum_field_types)MYSQL_TYPE_VIRTUAL; $$= $<lex_type>4;
Lex->vcol_info->set_field_type((enum enum_field_types) $1); 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; LEX *lex=Lex;
if (add_field_to_list(lex->thd,&$3, if (add_field_to_list(lex->thd,&$3,
(enum enum_field_types) $5, $5.type,
lex->length,lex->dec,lex->type, $5.length, $5.dec, lex->type,
lex->default_value, lex->on_update_value, lex->default_value, lex->on_update_value,
&lex->comment, &lex->comment,
$3.str, &lex->interval_list, lex->charset, $3.str, &lex->interval_list, $5.charset,
lex->uint_geom_type, lex->uint_geom_type,
lex->vcol_info, lex->option_list)) lex->vcol_info, lex->option_list))
MYSQL_YYABORT; MYSQL_YYABORT;