Commit 360c49c1 authored by Sergei Golubchik's avatar Sergei Golubchik

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.
parent b99328bb
......@@ -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;
......@@ -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;
......@@ -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
......
......@@ -737,6 +737,7 @@ static bool add_create_index (LEX *lex, Key::Keytype type,
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 **b, ulong *yystacksize);
%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
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
{
$$= (enum enum_field_types)MYSQL_TYPE_VIRTUAL;
Lex->vcol_info->set_field_type((enum enum_field_types) $1);
$$= $<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;
......
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