diff options
author | Sergei Golubchik <sergii@pisem.net> | 2014-11-18 15:42:40 +0100 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2014-11-18 15:42:40 +0100 |
commit | 5d0122bd7719d1b6125af43e29908cb71922e646 (patch) | |
tree | d77cdbfb63c1fbee3f8be7808c27d428dd85b7be /sql | |
parent | 84f25c25f260373b54941d9239e8b0d758990601 (diff) | |
download | mariadb-git-5d0122bd7719d1b6125af43e29908cb71922e646.tar.gz |
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
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.h | 1 | ||||
-rw-r--r-- | sql/item_func.h | 4 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 15 | ||||
-rw-r--r-- | sql/item_timefunc.h | 9 |
4 files changed, 14 insertions, 15 deletions
diff --git a/sql/item.h b/sql/item.h index f7ee860390f..57e91e5b3d8 100644 --- a/sql/item.h +++ b/sql/item.h @@ -3939,6 +3939,7 @@ public: 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"); diff --git a/sql/item_func.h b/sql/item_func.h index 49966964fbb..ab0ae5f0bda 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1696,6 +1696,7 @@ public: 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 @@ public: { return this; } + bool check_vcol_func_processor(uchar *int_arg) { return TRUE;} }; @@ -1817,6 +1819,7 @@ public: 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 @@ public: 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()); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 15701658015..59a5f1849f8 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -450,16 +450,14 @@ err: 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 @@ overflow: 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(String *str) 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 @@ null_date: 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(MYSQL_TIME *ltime, 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; diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 455540c4b0d..3a03ee4b27a 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -688,6 +688,7 @@ public: 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 @@ public: 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 @@ public: 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 */ |