diff options
-rw-r--r-- | mysql-test/r/locale.result | 71 | ||||
-rw-r--r-- | mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result | 15 | ||||
-rw-r--r-- | mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc | 3 | ||||
-rw-r--r-- | mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc | 6 | ||||
-rw-r--r-- | mysql-test/t/locale.test | 28 | ||||
-rw-r--r-- | sql/item.cc | 19 | ||||
-rw-r--r-- | sql/item.h | 4 | ||||
-rw-r--r-- | sql/item_create.cc | 27 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 24 | ||||
-rw-r--r-- | sql/item_strfunc.h | 5 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 25 | ||||
-rw-r--r-- | sql/item_timefunc.h | 27 | ||||
-rw-r--r-- | sql/lex.h | 1 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 16 | ||||
-rw-r--r-- | sql/sql_yacc_ora.yy | 16 |
16 files changed, 222 insertions, 67 deletions
diff --git a/mysql-test/r/locale.result b/mysql-test/r/locale.result index a02e80ed21e..b750d038205 100644 --- a/mysql-test/r/locale.result +++ b/mysql-test/r/locale.result @@ -229,15 +229,80 @@ SET lc_time_names=@old_50915_lc_time_names; # End of 10.1 tests # create view v1 as select +date_format('2001-10-02', '%c %b %M') as a, +date_format('2001-10-02', '%c %b %M', 'ru_RU') as a1, format(123456789,2) as b, format(123456789,2,'rm_CH') as b1; select * from v1; -b b1 -123,456,789.00 123'456'789,00 +a a1 b b1 +10 Oct October 10 Окт Октября 123,456,789.00 123'456'789,00 show create view v1; View Create View character_set_client collation_connection -v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select format(123456789,2) AS `b`,format(123456789,2,'rm_CH') AS `b1` utf8 utf8_general_ci +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select date_format('2001-10-02','%c %b %M') AS `a`,date_format('2001-10-02','%c %b %M','ru_RU') AS `a1`,format(123456789,2) AS `b`,format(123456789,2,'rm_CH') AS `b1` utf8 utf8_general_ci drop view v1; # # End of 10.2 tests # +select date_format('2001-01-01', '%w %a %W', 'ro_RO'); +date_format('2001-01-01', '%w %a %W', 'ro_RO') +1 Lu Luni +select date_format('2001-01-03', '%w %a %W', 'ro_RO'); +date_format('2001-01-03', '%w %a %W', 'ro_RO') +3 Mi Miercuri +select date_format('2001-01-05', '%w %a %W', 'ro_RO'); +date_format('2001-01-05', '%w %a %W', 'ro_RO') +5 Vi Vineri +select date_format('2001-01-07', '%w %a %W', 'ro_RO'); +date_format('2001-01-07', '%w %a %W', 'ro_RO') +0 Du Duminică +select date_format('2001-01-01', '%w %a %W', 'de_AT'); +date_format('2001-01-01', '%w %a %W', 'de_AT') +1 Mon Montag +select date_format('2001-02-01', '%w %a %W', 'de_AT'); +date_format('2001-02-01', '%w %a %W', 'de_AT') +4 Don Donnerstag +select date_format('2001-03-01', '%w %a %W', 'de_AT'); +date_format('2001-03-01', '%w %a %W', 'de_AT') +4 Don Donnerstag +select date_format('2001-01-01', '%w %a %W', 'en_US'); +date_format('2001-01-01', '%w %a %W', 'en_US') +1 Mon Monday +select date_format('2001-03-01', '%c %b %M', 'en_US'); +date_format('2001-03-01', '%c %b %M', 'en_US') +3 Mar March +select date_format('2001-01-01', '%w %a %W', 'rm_CH'); +date_format('2001-01-01', '%w %a %W', 'rm_CH') +1 gli glindesdi +select date_format('2001-01-03', '%w %a %W', 'rm_CH'); +date_format('2001-01-03', '%w %a %W', 'rm_CH') +3 me mesemna +select date_format('2001-01-05', '%w %a %W', 'rm_CH'); +date_format('2001-01-05', '%w %a %W', 'rm_CH') +5 ve venderdi +select date_format('2001-01-07', '%w %a %W', 'rm_CH'); +date_format('2001-01-07', '%w %a %W', 'rm_CH') +0 du dumengia +select date_format('2001-02-01', '%c %b %M', 'rm_CH'); +date_format('2001-02-01', '%c %b %M', 'rm_CH') +2 favr favrer +select date_format('2001-04-01', '%c %b %M', 'rm_CH'); +date_format('2001-04-01', '%c %b %M', 'rm_CH') +4 avr avrigl +select date_format('2001-06-01', '%c %b %M', 'rm_CH'); +date_format('2001-06-01', '%c %b %M', 'rm_CH') +6 zercl zercladur +select date_format('2001-08-01', '%c %b %M', 'rm_CH'); +date_format('2001-08-01', '%c %b %M', 'rm_CH') +8 avust avust +select date_format('2001-10-01', '%c %b %M', 'rm_CH'); +date_format('2001-10-01', '%c %b %M', 'rm_CH') +10 oct october +select date_format('2001-12-01', '%c %b %M', 'rm_CH'); +date_format('2001-12-01', '%c %b %M', 'rm_CH') +12 dec december +select date_format('2001-01-06', '%w %a %W', 'de_CH'); +date_format('2001-01-06', '%w %a %W', 'de_CH') +6 Sa Samstag +select date_format('2001-09-01', '%c %b %M', 'de_CH'); +date_format('2001-09-01', '%c %b %M', 'de_CH') +9 Sep September diff --git a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result index 6605f7c99b4..2d5bcfe553d 100644 --- a/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result +++ b/mysql-test/suite/vcol/r/vcol_blocked_sql_funcs.result @@ -247,3 +247,5 @@ ERROR HY000: Expression in the GENERATED ALWAYS AS clause is too big # Constant expression create or replace table t1 (a int as (PI()) PERSISTENT); drop table if exists t1; +create table t1 (a timestamp, b varchar(255) as (date_format(a, '%w %a %m %b')) stored); +ERROR HY000: Function or expression 'date_format()' cannot be used in the GENERATED ALWAYS AS clause of `b` diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result index 3fa4f6e1431..10ab32f9486 100644 --- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result +++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result @@ -2894,6 +2894,21 @@ a b 2012-12-12 Wednesday Wed December Dec drop table t1; set sql_warnings = 0; +# DATE_FORMAT() STORED +set sql_warnings = 1; +create table t1 (a date, b varchar(100) as (date_format(a, '%W %a %M %b', 'de_DE')) STORED); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` date DEFAULT NULL, + `b` varchar(100) GENERATED ALWAYS AS (date_format(`a`,'%W %a %M %b','de_DE')) STORED +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values ('2012-12-12',default); +select * from t1; +a b +2012-12-12 Mittwoch Mi Dezember Dez +drop table t1; +set sql_warnings = 0; # CURRENT_USER() set sql_warnings = 1; create table t1 (a char, b varchar(32) as (current_user())); diff --git a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc index 766d0c7410c..37de02a2b29 100644 --- a/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc +++ b/mysql-test/suite/vcol/t/vcol_blocked_sql_funcs_main.inc @@ -354,3 +354,6 @@ eval create or replace table t1 (a int, b varchar(16384) as (concat(a,'$tmp_long create or replace table t1 (a int as (PI()) PERSISTENT); drop table if exists t1; + +--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED +create table t1 (a timestamp, b varchar(255) as (date_format(a, '%w %a %m %b')) stored); diff --git a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc index dafc42098dd..fa2162e5981 100644 --- a/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc +++ b/mysql-test/suite/vcol/t/vcol_supported_sql_funcs_main.inc @@ -1197,6 +1197,12 @@ let $values1 = '2012-12-12',default; let $rows = 1; --source suite/vcol/inc/vcol_supported_sql_funcs.inc +--echo # DATE_FORMAT() STORED +let $cols = a date, b varchar(100) as (date_format(a, '%W %a %M %b', 'de_DE')) STORED; +let $values1 = '2012-12-12',default; +let $rows = 1; +--source suite/vcol/inc/vcol_supported_sql_funcs.inc + --echo # CURRENT_USER() let $cols = a char, b varchar(32) as (current_user()); let $values1 = 'a', default; diff --git a/mysql-test/t/locale.test b/mysql-test/t/locale.test index 4570b968ecf..a9a507bc387 100644 --- a/mysql-test/t/locale.test +++ b/mysql-test/t/locale.test @@ -144,6 +144,8 @@ SET lc_time_names=@old_50915_lc_time_names; # Item::print create view v1 as select + date_format('2001-10-02', '%c %b %M') as a, + date_format('2001-10-02', '%c %b %M', 'ru_RU') as a1, format(123456789,2) as b, format(123456789,2,'rm_CH') as b1; select * from v1; @@ -153,3 +155,29 @@ drop view v1; --echo # --echo # End of 10.2 tests --echo # + +# +# MDEV-11553 Can't restore a PERSISTENT column that uses DATE_FORMAT() +# +# 3-argument syntax for DATE_FORMAT() +select date_format('2001-01-01', '%w %a %W', 'ro_RO'); +select date_format('2001-01-03', '%w %a %W', 'ro_RO'); +select date_format('2001-01-05', '%w %a %W', 'ro_RO'); +select date_format('2001-01-07', '%w %a %W', 'ro_RO'); +select date_format('2001-01-01', '%w %a %W', 'de_AT'); +select date_format('2001-02-01', '%w %a %W', 'de_AT'); +select date_format('2001-03-01', '%w %a %W', 'de_AT'); +select date_format('2001-01-01', '%w %a %W', 'en_US'); +select date_format('2001-03-01', '%c %b %M', 'en_US'); +select date_format('2001-01-01', '%w %a %W', 'rm_CH'); +select date_format('2001-01-03', '%w %a %W', 'rm_CH'); +select date_format('2001-01-05', '%w %a %W', 'rm_CH'); +select date_format('2001-01-07', '%w %a %W', 'rm_CH'); +select date_format('2001-02-01', '%c %b %M', 'rm_CH'); +select date_format('2001-04-01', '%c %b %M', 'rm_CH'); +select date_format('2001-06-01', '%c %b %M', 'rm_CH'); +select date_format('2001-08-01', '%c %b %M', 'rm_CH'); +select date_format('2001-10-01', '%c %b %M', 'rm_CH'); +select date_format('2001-12-01', '%c %b %M', 'rm_CH'); +select date_format('2001-01-06', '%w %a %W', 'de_CH'); +select date_format('2001-09-01', '%c %b %M', 'de_CH'); diff --git a/sql/item.cc b/sql/item.cc index 4a3847f800e..9dcc81bbae7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1451,6 +1451,25 @@ bool Item::get_seconds(ulonglong *sec, ulong *sec_part) return my_decimal2seconds(dec, sec, sec_part); } +const MY_LOCALE *Item::locale_from_val_str() +{ + StringBuffer<MAX_FIELD_WIDTH> tmp; + String *locale_name= val_str_ascii(&tmp); + const MY_LOCALE *lc; + if (!locale_name || + !(lc= my_locale_by_name(locale_name->c_ptr_safe()))) + { + THD *thd= current_thd; + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_UNKNOWN_LOCALE, + ER_THD(thd, ER_UNKNOWN_LOCALE), + locale_name ? locale_name->c_ptr_safe() : "NULL"); + lc= &my_locale_en_US; + } + return lc; +} + + CHARSET_INFO *Item::default_charset() { return current_thd->variables.collation_connection; diff --git a/sql/item.h b/sql/item.h index 3f8ccb88392..04dad5265d3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -491,6 +491,8 @@ struct find_selective_predicates_list_processor_data List<st_cond_statistic> list; }; +class MY_LOCALE; + class Item_equal; class COND_EQUAL; @@ -644,6 +646,8 @@ public: */ String *val_str() { return val_str(&str_value); } + const MY_LOCALE *locale_from_val_str(); + LEX_CSTRING name; /* Name of item */ /* Original item name (if it was renamed)*/ const char *orig_name; diff --git a/sql/item_create.cc b/sql/item_create.cc index b0b33041383..5f1485a1336 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -783,19 +783,6 @@ protected: #endif -class Create_func_date_format : public Create_func_arg2 -{ -public: - virtual Item *create_2_arg(THD *thd, Item *arg1, Item *arg2); - - static Create_func_date_format s_singleton; - -protected: - Create_func_date_format() {} - virtual ~Create_func_date_format() {} -}; - - class Create_func_datediff : public Create_func_arg2 { public: @@ -4051,15 +4038,6 @@ Create_func_crosses::create_2_arg(THD *thd, Item *arg1, Item *arg2) #endif -Create_func_date_format Create_func_date_format::s_singleton; - -Item* -Create_func_date_format::create_2_arg(THD *thd, Item *arg1, Item *arg2) -{ - return new (thd->mem_root) Item_func_date_format(thd, arg1, arg2, 0); -} - - Create_func_datediff Create_func_datediff::s_singleton; Item* @@ -4558,7 +4536,7 @@ Create_func_from_unixtime::create_native(THD *thd, LEX_CSTRING *name, Item *param_1= item_list->pop(); Item *param_2= item_list->pop(); Item *ut= new (thd->mem_root) Item_func_from_unixtime(thd, param_1); - func= new (thd->mem_root) Item_func_date_format(thd, ut, param_2, 0); + func= new (thd->mem_root) Item_func_date_format(thd, ut, param_2); break; } default: @@ -6511,7 +6489,7 @@ Create_func_time_format Create_func_time_format::s_singleton; Item* Create_func_time_format::create_2_arg(THD *thd, Item *arg1, Item *arg2) { - return new (thd->mem_root) Item_func_date_format(thd, arg1, arg2, 1); + return new (thd->mem_root) Item_func_time_format(thd, arg1, arg2); } @@ -6872,7 +6850,6 @@ static Native_func_registry func_array[] = { { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)}, { { C_STRING_WITH_LEN("CROSSES") }, GEOM_BUILDER(Create_func_crosses)}, { { C_STRING_WITH_LEN("DATEDIFF") }, BUILDER(Create_func_datediff)}, - { { C_STRING_WITH_LEN("DATE_FORMAT") }, BUILDER(Create_func_date_format)}, { { C_STRING_WITH_LEN("DAYNAME") }, BUILDER(Create_func_dayname)}, { { C_STRING_WITH_LEN("DAYOFMONTH") }, BUILDER(Create_func_dayofmonth)}, { { C_STRING_WITH_LEN("DAYOFWEEK") }, BUILDER(Create_func_dayofweek)}, diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 83432f95612..d29e579bcd9 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2668,24 +2668,6 @@ String *Item_func_soundex::val_str(String *str) const int FORMAT_MAX_DECIMALS= 30; -MY_LOCALE *Item_func_format::get_locale(Item *item) -{ - DBUG_ASSERT(arg_count == 3); - String tmp, *locale_name= args[2]->val_str_ascii(&tmp); - MY_LOCALE *lc; - if (!locale_name || - !(lc= my_locale_by_name(locale_name->c_ptr_safe()))) - { - THD *thd= current_thd; - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - ER_UNKNOWN_LOCALE, - ER_THD(thd, ER_UNKNOWN_LOCALE), - locale_name ? locale_name->c_ptr_safe() : "NULL"); - lc= &my_locale_en_US; - } - return lc; -} - void Item_func_format::fix_length_and_dec() { uint32 char_length= args[0]->max_char_length(); @@ -2693,7 +2675,7 @@ void Item_func_format::fix_length_and_dec() collation.set(default_charset()); fix_char_length(char_length + max_sep_count + decimals); if (arg_count == 3) - locale= args[2]->basic_const_item() ? get_locale(args[2]) : NULL; + locale= args[2]->basic_const_item() ? args[2]->locale_from_val_str() : NULL; else locale= &my_locale_en_US; /* Two arguments */ } @@ -2712,7 +2694,7 @@ String *Item_func_format::val_str_ascii(String *str) int dec; /* Number of characters used to represent the decimals, including '.' */ uint32 dec_length; - MY_LOCALE *lc; + const MY_LOCALE *lc; DBUG_ASSERT(fixed == 1); dec= (int) args[1]->val_int(); @@ -2722,7 +2704,7 @@ String *Item_func_format::val_str_ascii(String *str) return NULL; } - lc= locale ? locale : get_locale(args[2]); + lc= locale ? locale : args[2]->locale_from_val_str(); dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS); dec_length= dec ? dec+1 : 0; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index a7cad234893..d73bd0b76d7 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -27,8 +27,6 @@ extern size_t username_char_length; -class MY_LOCALE; - class Item_str_func :public Item_func { protected: @@ -932,14 +930,13 @@ public: class Item_func_format :public Item_str_ascii_func { - MY_LOCALE *locale; + const MY_LOCALE *locale; public: Item_func_format(THD *thd, Item *org, Item *dec): Item_str_ascii_func(thd, org, dec) {} Item_func_format(THD *thd, Item *org, Item *dec, Item *lang): Item_str_ascii_func(thd, org, dec, lang) {} - MY_LOCALE *get_locale(Item *item); String *val_str_ascii(String *); void fix_length_and_dec(); const char *func_name() const { return "format"; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 86bde00cced..189addc767b 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -455,7 +455,8 @@ err: */ static bool make_date_time(DATE_TIME_FORMAT *format, MYSQL_TIME *l_time, - timestamp_type type, MY_LOCALE *locale, String *str) + timestamp_type type, const MY_LOCALE *locale, + String *str) { char intbuff[15]; uint hours_i; @@ -1833,7 +1834,14 @@ overflow: void Item_func_date_format::fix_length_and_dec() { THD* thd= current_thd; - locale= thd->variables.lc_time_names; + if (!is_time_format) + { + if (arg_count < 3) + locale= thd->variables.lc_time_names; + else + if (args[2]->basic_const_item()) + locale= args[2]->locale_from_val_str(); + } /* Must use this_item() in case it's a local SP variable @@ -1875,6 +1883,8 @@ bool Item_func_date_format::eq(const Item *item, bool binary_cmp) const if (this == item) return 1; item_func= (Item_func_date_format*) item; + if (arg_count != item_func->arg_count) + return 0; if (!args[0]->eq(item_func->args[0], binary_cmp)) return 0; /* @@ -1884,6 +1894,8 @@ bool Item_func_date_format::eq(const Item *item, bool binary_cmp) const */ if (!args[1]->eq(item_func->args[1], 1)) return 0; + if (arg_count > 2 && !args[2]->eq(item_func->args[2], 1)) + return 0; return 1; } @@ -1967,15 +1979,18 @@ String *Item_func_date_format::val_str(String *str) String *format; MYSQL_TIME l_time; uint size; - int is_time_flag = is_time_format ? TIME_TIME_ONLY : 0; + const MY_LOCALE *lc= 0; DBUG_ASSERT(fixed == 1); - if (get_arg0_date(&l_time, is_time_flag)) + if (get_arg0_date(&l_time, is_time_format ? TIME_TIME_ONLY : 0)) return 0; if (!(format = args[1]->val_str(str)) || !format->length()) goto null_date; + if (!is_time_format && !(lc= locale) && !(lc= args[2]->locale_from_val_str())) + goto null_date; // invalid locale + if (fixed_length) size=max_length; else @@ -1998,7 +2013,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, - locale, str)) + lc, str)) return str; null_date: diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 7d2fe46b644..20ecb4774b3 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -797,22 +797,24 @@ public: class Item_func_date_format :public Item_str_func { - MY_LOCALE *locale; + const MY_LOCALE *locale; int fixed_length; - const bool is_time_format; String value; +protected: + bool is_time_format; public: - Item_func_date_format(THD *thd, Item *a, Item *b, bool is_time_format_arg): - Item_str_func(thd, a, b), is_time_format(is_time_format_arg) {} + Item_func_date_format(THD *thd, Item *a, Item *b): + Item_str_func(thd, a, b), locale(0), is_time_format(false) {} + Item_func_date_format(THD *thd, Item *a, Item *b, Item *c): + Item_str_func(thd, a, b, c), locale(0), is_time_format(false) {} String *val_str(String *str); - const char *func_name() const - { return is_time_format ? "time_format" : "date_format"; } + const char *func_name() const { return "date_format"; } void fix_length_and_dec(); uint format_length(const String *format); bool eq(const Item *item, bool binary_cmp) const; bool check_vcol_func_processor(void *arg) { - if (is_time_format) + if (arg_count > 2) return false; return mark_unsupported_function(func_name(), "()", arg, VCOL_SESSION_FUNC); } @@ -820,6 +822,17 @@ public: { return get_item_copy<Item_func_date_format>(thd, mem_root, this); } }; +class Item_func_time_format: public Item_func_date_format +{ +public: + Item_func_time_format(THD *thd, Item *a, Item *b): + Item_func_date_format(thd, a, b) { is_time_format= true; } + const char *func_name() const { return "time_format"; } + bool check_vcol_func_processor(void *arg) { return false; } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) + { return get_item_copy<Item_func_time_format>(thd, mem_root, this); } +}; + class Item_func_from_unixtime :public Item_datetimefunc { diff --git a/sql/lex.h b/sql/lex.h index f2dac95fce5..67c3bc8620d 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -726,6 +726,7 @@ static SYMBOL sql_functions[] = { { "CURTIME", SYM(CURTIME)}, { "DATE_ADD", SYM(DATE_ADD_INTERVAL)}, { "DATE_SUB", SYM(DATE_SUB_INTERVAL)}, + { "DATE_FORMAT", SYM(DATE_FORMAT_SYM)}, { "DECODE", SYM(DECODE_SYM)}, { "DENSE_RANK", SYM(DENSE_RANK_SYM)}, { "EXTRACT", SYM(EXTRACT_SYM)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7e89ad91a17..17d6f016b2c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -875,7 +875,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); Comments for TOKENS. For each token, please include in the same line a comment that contains the following tags: - SQL-2011-N : Non Reserved keywird as per SQL-2011 + SQL-2011-N : Non Reserved keyword as per SQL-2011 SQL-2003-R : Reserved keyword as per SQL-2003 SQL-2003-N : Non Reserved keyword as per SQL-2003 SQL-1999-R : Reserved keyword as per SQL-1999 @@ -1010,6 +1010,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DATA_SYM /* SQL-2003-N */ %token DATETIME %token DATE_ADD_INTERVAL /* MYSQL-FUNC */ +%token DATE_FORMAT_SYM /* MYSQL-FUNC */ %token DATE_SUB_INTERVAL /* MYSQL-FUNC */ %token DATE_SYM /* SQL-2003-R */ %token DAY_HOUR_SYM @@ -9806,6 +9807,18 @@ function_call_nonkeyword: if ($$ == NULL) MYSQL_YYABORT; } + | DATE_FORMAT_SYM '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } + | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); + if ($$ == NULL) + MYSQL_YYABORT; + } | DECODE_SYM '(' expr ',' expr ')' { $$= new (thd->mem_root) Item_func_decode(thd, $3, $5); @@ -14719,6 +14732,7 @@ keyword_sp_not_data_type: | CYCLE_SYM {} | DATA_SYM {} | DATAFILE_SYM {} + | DATE_FORMAT_SYM {} | DAY_SYM {} | DECODE_SYM {} | DEFINER_SYM {} diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy index 8d250abd994..052c219a7a4 100644 --- a/sql/sql_yacc_ora.yy +++ b/sql/sql_yacc_ora.yy @@ -284,7 +284,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); Comments for TOKENS. For each token, please include in the same line a comment that contains the following tags: - SQL-2011-N : Non Reserved keywird as per SQL-2011 + SQL-2011-N : Non Reserved keyword as per SQL-2011 SQL-2003-R : Reserved keyword as per SQL-2003 SQL-2003-N : Non Reserved keyword as per SQL-2003 SQL-1999-R : Reserved keyword as per SQL-1999 @@ -419,6 +419,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token DATA_SYM /* SQL-2003-N */ %token DATETIME %token DATE_ADD_INTERVAL /* MYSQL-FUNC */ +%token DATE_FORMAT_SYM /* MYSQL-FUNC */ %token DATE_SUB_INTERVAL /* MYSQL-FUNC */ %token DATE_SYM /* SQL-2003-R */ %token DAY_HOUR_SYM @@ -9462,6 +9463,18 @@ column_default_non_parenthesized_expr: if ($$ == NULL) MYSQL_YYABORT; } + | DATE_FORMAT_SYM '(' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5); + if ($$ == NULL) + MYSQL_YYABORT; + } + | DATE_FORMAT_SYM '(' expr ',' expr ',' expr ')' + { + $$= new (thd->mem_root) Item_func_date_format(thd, $3, $5, $7); + if ($$ == NULL) + MYSQL_YYABORT; + } | DECODE_SYM '(' expr ',' decode_when_list ')' { $5->push_front($3, thd->mem_root); @@ -14893,6 +14906,7 @@ keyword_sp_not_data_type: | CYCLE_SYM {} | DATA_SYM {} | DATAFILE_SYM {} + | DATE_FORMAT_SYM {} | DAY_SYM {} | DECODE_SYM {} | DEFINER_SYM {} |