[Commits] Rev 4352: MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor in lp:~maria-captains/maria/5.5

Sergei Golubchik serg at mariadb.org
Sat Nov 15 17:57:53 EET 2014


At lp:~maria-captains/maria/5.5

------------------------------------------------------------
revno: 4352
revision-id: sergii at pisem.net-20141115155753-2ecfn06n4umfqq81
parent: sergii at pisem.net-20141113173729-z2mb0j7j8aie16qf
fixes bugs: https://mariadb.atlassian.net/browse/MDEV-6789 https://mariadb.atlassian.net/browse/MDEV-7113
committer: Sergei Golubchik <sergii at pisem.net>
branch nick: 5.5
timestamp: Sat 2014-11-15 16:57:53 +0100
message:
  MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
  MDEV-6789 segfault in Item_func_from_unixtime::get_date on updating table with virtual columns
  
  * prohibit VALUES in partitioning expression
  * prohibit user and system variables in virtual column expressions
  * fix Item_func_date_format to cache locale (for %M/%W to return the same as MONTHNAME/DAYNAME)
  * fix Item_func_from_unixtime to cache time_zone directly, not THD (and not to crash)
  * added tests for other incorrectly allowed (in vcols) functions to see that they don't crash
=== modified file 'mysql-test/r/partition_error.result'
--- a/mysql-test/r/partition_error.result	2014-03-17 12:04:28 +0000
+++ b/mysql-test/r/partition_error.result	2014-11-15 15:57:53 +0000
@@ -1754,3 +1754,8 @@ PARTITION pmax VALUES LESS THAN MAXVALUE
 ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
 DROP TABLE t1;
 End of 5.1 tests
+create table t1 (a int) partition by list (values(a) div 1) (partition p0 values in (0), partition p1 values in (1));
+ERROR HY000: This partition function is not allowed
+create table t1 (a int) partition by list (uuid_short()) (partition p0 values in (0), partition p1 values in (1));
+ERROR 42000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed near ') (partition p0 values in (0), partition p1 values in (1))' at line 1
+End of 5.5 tests

=== added file 'mysql-test/suite/vcol/r/not_supported.result'
--- a/mysql-test/suite/vcol/r/not_supported.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/r/not_supported.result	2014-11-15 15:57:53 +0000
@@ -0,0 +1,66 @@
+set lc_time_names = 'es_MX';
+set time_zone='+10:00';
+set div_precision_increment=20;
+create table t1 (a int, b int, v decimal(20,19) as (a/3));
+create table t2 (a int, b int, v int as (a+ at a));
+ERROR HY000: Function or expression is not allowed for column 'v'
+create table t3 (a int, b int, v int as (a+@@error_count));
+ERROR HY000: Function or expression is not allowed for column 'v'
+create table t4 (a int, b int, v int as (@a:=a));
+ERROR HY000: Function or expression is not allowed for column 'v'
+create table t5 (a int, b int, v varchar(100) as (monthname(a)));
+create table t6 (a int, b int, v varchar(100) as (dayname(a)));
+create table t7 (a int, b int, v varchar(100) as (date_format(a, '%W %a %M %b')));
+create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
+insert t1 (a,b) values (1,2);
+insert t5 (a,b) values (20141010,2);
+insert t6 (a,b) values (20141010,2);
+insert t7 (a,b) values (20141010,2);
+insert t8 (a,b) values (1234567890,2);
+select * from t1;
+a	b	v
+1	2	0.3333333333333333333
+select * from t5;
+a	b	v
+20141010	2	octubre
+select * from t6;
+a	b	v
+20141010	2	viernes
+select * from t7;
+a	b	v
+20141010	2	viernes vie octubre oct
+select * from t8;
+a	b	v
+1234567890	2	2009-02-14 09:31:30
+select * from t1;
+a	b	v
+1	2	0.3333333333333333333
+select * from t5;
+a	b	v
+20141010	2	octubre
+select * from t6;
+a	b	v
+20141010	2	viernes
+select * from t7;
+a	b	v
+20141010	2	viernes vie octubre oct
+select * from t8;
+a	b	v
+1234567890	2	2009-02-14 09:31:30
+flush tables;
+select * from t1;
+a	b	v
+1	2	0.3333333330000000000
+select * from t5;
+a	b	v
+20141010	2	October
+select * from t6;
+a	b	v
+20141010	2	Friday
+select * from t7;
+a	b	v
+20141010	2	Friday Fri October Oct
+select * from t8;
+a	b	v
+1234567890	2	2009-02-14 00:31:30
+drop table t1, t5, t6, t7, t8;

=== added file 'mysql-test/suite/vcol/t/not_supported.test'
--- a/mysql-test/suite/vcol/t/not_supported.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/vcol/t/not_supported.test	2014-11-15 15:57:53 +0000
@@ -0,0 +1,57 @@
+#
+# MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
+#
+
+# the following functions must not be supported in virtual columns.
+# but for compatibility reasons it won't be done in a GA version,
+# we'll only fix most critical issues (inconsistent results, crashes)
+
+connect (con1, localhost, root);
+
+set lc_time_names = 'es_MX';
+set time_zone='+10:00';
+set div_precision_increment=20;
+
+create table t1 (a int, b int, v decimal(20,19) as (a/3));
+--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t2 (a int, b int, v int as (a+ at a));
+--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t3 (a int, b int, v int as (a+@@error_count));
+--error ER_VIRTUAL_COLUMN_FUNCTION_IS_NOT_ALLOWED
+create table t4 (a int, b int, v int as (@a:=a));
+create table t5 (a int, b int, v varchar(100) as (monthname(a)));
+create table t6 (a int, b int, v varchar(100) as (dayname(a)));
+create table t7 (a int, b int, v varchar(100) as (date_format(a, '%W %a %M %b')));
+create table t8 (a int, b int, v varchar(100) as (from_unixtime(a)));
+
+insert t1 (a,b) values (1,2);
+insert t5 (a,b) values (20141010,2);
+insert t6 (a,b) values (20141010,2);
+insert t7 (a,b) values (20141010,2);
+insert t8 (a,b) values (1234567890,2);
+
+select * from t1;
+select * from t5;
+select * from t6;
+select * from t7;
+select * from t8;
+
+disconnect con1;
+connection default;
+
+select * from t1;
+select * from t5;
+select * from t6;
+select * from t7;
+select * from t8;
+
+flush tables;
+
+select * from t1;
+select * from t5;
+select * from t6;
+select * from t7;
+select * from t8;
+
+drop table t1, t5, t6, t7, t8;
+

=== modified file 'mysql-test/t/partition_error.test'
--- a/mysql-test/t/partition_error.test	2014-03-17 12:04:28 +0000
+++ b/mysql-test/t/partition_error.test	2014-11-15 15:57:53 +0000
@@ -2005,3 +2005,14 @@ PARTITION pmax VALUES LESS THAN MAXVALUE
 DROP TABLE t1;
 
 --echo End of 5.1 tests
+
+#
+# MDEV-7113 difference between check_vcol_func_processor and check_partition_func_processor
+#
+--error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int) partition by list (values(a) div 1) (partition p0 values in (0), partition p1 values in (1));
+
+--error ER_PARSE_ERROR
+create table t1 (a int) partition by list (uuid_short()) (partition p0 values in (0), partition p1 values in (1));
+
+--echo End of 5.5 tests

=== modified file 'sql/item.h'
--- a/sql/item.h	2014-08-01 14:51:12 +0000
+++ b/sql/item.h	2014-11-15 15:57:53 +0000
@@ -3939,6 +3939,7 @@ class Item_insert_value : public Item_fi
     return arg->walk(processor, walk_subquery, args) ||
 	    (this->*processor)(args);
   }
+  bool check_partition_func_processor(uchar *int_arg) {return TRUE;}
   bool check_vcol_func_processor(uchar *arg) 
   {
     return trace_unsupported_by_check_vcol_func_processor("values");

=== modified file 'sql/item_func.h'
--- a/sql/item_func.h	2014-08-01 14:51:12 +0000
+++ b/sql/item_func.h	2014-11-15 15:57:53 +0000
@@ -1696,6 +1696,7 @@ class Item_func_set_user_var :public Ite
   bool register_field_in_bitmap(uchar *arg);
   bool set_entry(THD *thd, bool create_if_not_exists);
   void cleanup();
+  bool check_vcol_func_processor(uchar *int_arg) {return TRUE;}
 };
 
 
@@ -1735,6 +1736,7 @@ class Item_func_get_user_var :public Ite
   {
     return this;
   }
+  bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
 };
 
 
@@ -1817,6 +1819,7 @@ class Item_func_get_system_var :public I
   bool eq(const Item *item, bool binary_cmp) const;
 
   void cleanup();
+  bool check_vcol_func_processor(uchar *int_arg) { return TRUE;}
 };
 
 
@@ -2090,7 +2093,6 @@ class Item_func_uuid_short :public Item_
   longlong val_int();
   void fix_length_and_dec()
   { max_length= 21; unsigned_flag=1; }
-  bool check_partition_func_processor(uchar *int_arg) {return FALSE;}
   bool check_vcol_func_processor(uchar *int_arg) 
   {
     return trace_unsupported_by_check_vcol_func_processor(func_name());

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2014-06-04 17:53:15 +0000
+++ b/sql/item_timefunc.cc	2014-11-15 15:57:53 +0000
@@ -450,16 +450,14 @@ static bool extract_date_time(DATE_TIME_
   Create a formated date/time value in a string.
 */
 
-bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
-		    timestamp_type type, String *str)
+static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
+                           timestamp_type type, MY_LOCALE *locale, String *str)
 {
   char intbuff[15];
   uint hours_i;
   uint weekday;
   ulong length;
   const char *ptr, *end;
-  THD *thd= current_thd;
-  MY_LOCALE *locale= thd->variables.lc_time_names;
 
   str->length(0);
 
@@ -1726,6 +1724,8 @@ bool Item_func_sec_to_time::get_date(MYS
 void Item_func_date_format::fix_length_and_dec()
 {
   THD* thd= current_thd;
+  locale= thd->variables.lc_time_names;
+
   /*
     Must use this_item() in case it's a local SP variable
     (for ->max_length and ->str_value)
@@ -1889,7 +1889,7 @@ String *Item_func_date_format::val_str(S
   if (!make_date_time(&date_time_format, &l_time,
                       is_time_format ? MYSQL_TIMESTAMP_TIME :
                                        MYSQL_TIMESTAMP_DATE,
-                      str))
+                      locale, str))
     return str;
 
 null_date:
@@ -1900,8 +1900,9 @@ String *Item_func_date_format::val_str(S
 
 void Item_func_from_unixtime::fix_length_and_dec()
 { 
-  thd= current_thd;
+  THD *thd= current_thd;
   thd->time_zone_used= 1;
+  tz= thd->variables.time_zone;
   decimals= args[0]->decimals;
   Item_temporal_func::fix_length_and_dec();
 }
@@ -1922,7 +1923,7 @@ bool Item_func_from_unixtime::get_date(M
   if (args[0]->null_value || sign || sec > TIMESTAMP_MAX_VALUE)
     return (null_value= 1);
 
-  thd->variables.time_zone->gmt_sec_to_TIME(ltime, (my_time_t)sec);
+  tz->gmt_sec_to_TIME(ltime, (my_time_t)sec);
 
   ltime->second_part= sec_part;
 

=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h	2014-08-01 14:51:12 +0000
+++ b/sql/item_timefunc.h	2014-11-15 15:57:53 +0000
@@ -688,6 +688,7 @@ class Item_func_from_days :public Item_d
 
 class Item_func_date_format :public Item_str_func
 {
+  MY_LOCALE *locale;
   int fixed_length;
   const bool is_time_format;
   String value;
@@ -705,7 +706,7 @@ class Item_func_date_format :public Item
 
 class Item_func_from_unixtime :public Item_temporal_func
 {
-  THD *thd;
+  Time_zone *tz;
  public:
   Item_func_from_unixtime(Item *a) :Item_temporal_func(a) {}
   const char *func_name() const { return "from_unixtime"; }
@@ -1046,10 +1047,4 @@ class Item_func_last_day :public Item_da
   bool get_date(MYSQL_TIME *res, ulonglong fuzzy_date);
 };
 
-
-/* Function prototypes */
-
-bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time,
-                    timestamp_type type, String *str);
-
 #endif /* ITEM_TIMEFUNC_INCLUDED */



More information about the commits mailing list