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:
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
Reference in New Issue
Block a user