[Commits] Rev 4341: MDEV-6179: dynamic columns functions/cast()/convert() doesn't play nice with CREATE/ALTER TABLE in file:///home/bell/maria/bzr/work-maria-5.5-MDEV-6179/

sanja at askmonty.org sanja at askmonty.org
Sun Nov 2 15:31:39 EET 2014


At file:///home/bell/maria/bzr/work-maria-5.5-MDEV-6179/

------------------------------------------------------------
revno: 4341
revision-id: sanja at askmonty.org-20141102133114-v46li6r2goyzhhp7
parent: sanja at askmonty.org-20141031130729-dya4hci39x6zrv89
committer: sanja at askmonty.org
branch nick: work-maria-5.5-MDEV-6179
timestamp: Sun 2014-11-02 14:31:14 +0100
message:
  MDEV-6179: dynamic columns functions/cast()/convert() doesn't play nice with CREATE/ALTER TABLE
  
  Type attributes (length, dec, charset) which parsed to global variables now saved and restored during prsing types which can appeared in a expression.
-------------- next part --------------
=== 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-02 13:31:14 +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-02 13:31:14 +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.cc'
--- a/sql/sql_lex.cc	2014-08-02 19:26:16 +0000
+++ b/sql/sql_lex.cc	2014-11-02 13:31:14 +0000
@@ -462,6 +462,7 @@ void lex_start(THD *thd)
   lex->view_list.empty();
   lex->prepared_stmt_params.empty();
   lex->auxiliary_table_list.empty();
+  lex->save_type_attr.empty();
   lex->unit.next= lex->unit.master=
     lex->unit.link_next= lex->unit.return_to= 0;
   lex->unit.prev= lex->unit.link_prev= 0;

=== 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-02 13:31:14 +0000
@@ -2335,6 +2335,16 @@ protected:
   LEX *m_lex;
 };
 
+struct TYPE_ATTR :public Sql_alloc
+
+{
+  char *length, *dec;
+  CHARSET_INFO *charset;
+  TYPE_ATTR(char *l, char *d, CHARSET_INFO *c):
+    length(l), dec(d), charset(c)
+    {}
+};
+
 /* The state of the lex parsing. This is saved in the THD struct */
 
 struct LEX: public Query_tables_list
@@ -2397,6 +2407,8 @@ struct LEX: public Query_tables_list
   List<Item_func_set_user_var> set_var_list; // in-query assignment list
   List<Item_param>    param_list;
   List<LEX_STRING>    view_list; // view list (list of field names in view)
+  /* used to temporary store old value for type definition in functions */
+  List<TYPE_ATTR>     save_type_attr;
   /*
     A stack of name resolution contexts for the query. This stack is used
     at parse time to set local name resolution contexts for various parts
@@ -2757,6 +2769,18 @@ struct LEX: public Query_tables_list
     }
     return FALSE;
   }
+  inline void push_type_attr()
+  {
+    TYPE_ATTR *attr= new TYPE_ATTR(length, dec, charset);
+    save_type_attr.push_front(attr);
+  }
+  inline void pop_type_attr()
+  {
+    TYPE_ATTR *attr= save_type_attr.pop();
+    length= attr->length;
+    dec= attr->dec;
+    charset= attr->charset;
+  }
 };
 
 

=== 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-02 13:31:14 +0000
@@ -8251,7 +8251,9 @@ dyncol_type:
         ;
 
 dyncall_create_element:
-   expr ',' expr opt_dyncol_type
+   expr ',' expr 
+   { Lex->push_type_attr(); }
+   opt_dyncol_type
    {
      LEX *lex= Lex;
      $$= (DYNCALL_CREATE_DEF *)
@@ -8260,7 +8262,7 @@ dyncall_create_element:
        MYSQL_YYABORT;
      $$->num= $1;
      $$->value= $3;
-     $$->type= (DYNAMIC_COLUMN_TYPE)$4;
+     $$->type= (DYNAMIC_COLUMN_TYPE)$5;
      $$->cs= lex->charset;
      if (lex->length)
        $$->len= strtoul(lex->length, NULL, 10);
@@ -8270,6 +8272,7 @@ dyncall_create_element:
        $$->frac= strtoul(lex->dec, NULL, 10);
      else
        $$->len= 0;
+     lex->pop_type_attr();
    }
 
 dyncall_create_list:
@@ -8382,11 +8385,14 @@ simple_expr:
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
-        | CAST_SYM '(' expr AS cast_type ')'
+        | CAST_SYM '(' expr AS
+          { Lex->push_type_attr(); }
+          cast_type ')'
           {
             LEX *lex= Lex;
-            $$= create_func_cast(thd, $3, $5, lex->length, lex->dec,
+            $$= create_func_cast(thd, $3, $6, lex->length, lex->dec,
                                  lex->charset);
+            lex->pop_type_attr();
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
@@ -8396,10 +8402,14 @@ simple_expr:
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
-        | CONVERT_SYM '(' expr ',' cast_type ')'
+        | CONVERT_SYM '(' expr ','
+          { Lex->push_type_attr(); }
+          cast_type ')'
           {
-            $$= create_func_cast(thd, $3, $5, Lex->length, Lex->dec,
-                                 Lex->charset);
+            LEX *lex= Lex;
+            $$= create_func_cast(thd, $3, $6, lex->length, lex->dec,
+                                 lex->charset);
+            lex->pop_type_attr();
             if ($$ == NULL)
               MYSQL_YYABORT;
           }
@@ -8830,12 +8840,15 @@ function_call_nonkeyword:
               MYSQL_YYABORT;
           }
         |
-          COLUMN_GET_SYM '(' expr ',' expr AS cast_type ')'
+          COLUMN_GET_SYM '(' expr ',' expr AS 
+          { Lex->push_type_attr(); }
+          cast_type ')'
           {
             LEX *lex= Lex;
-            $$= create_func_dyncol_get(thd, $3, $5, $7,
+            $$= create_func_dyncol_get(thd, $3, $5, $8,
                                         lex->length, lex->dec,
                                         lex->charset);
+            lex->pop_type_attr();
             if ($$ == NULL)
               MYSQL_YYABORT;
           }



More information about the commits mailing list