← Back to team overview

maria-developers team mailing list archive

Re: [Commits] Rev 4343: MDEV-6179: dynamic columns functions/cast()/convert() doesn't play nice with CREATE/ALTER TABLE in lp:~maria-captains/maria/5.5

 

Hi, Sergei!

Thank you! The patch is OK.

On 08.11.14 19:54, Sergei Golubchik wrote:
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