← Back to team overview

maria-developers team mailing list archive

Re: [Commits] 2846574452e: MDEV-11553 Can't restore a PERSISTENT column that uses DATE_FORMAT()

 

  Hello Sergei,

Ok to push.


One small suggestion. Instead of having a standalone function,
please move get_locale as method in Item.
Something like this:

const MY_LOCALE *Item::get_locale()
{
  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;
}


Thanks!


On 09/22/2017 10:30 PM, serg@xxxxxxxxxxx wrote:
> revision-id: 2846574452e82b9f391ca5d41d5021ac94730dec (base-0.6-627-g2846574452e)
> parent(s): 5a8b6e38967f1e4aa7fe4885e54ee8ea44097e8e
> author: Sergei Golubchik
> committer: Sergei Golubchik
> timestamp: 2017-09-22 20:24:53 +0200
> message:
> 
> MDEV-11553 Can't restore a PERSISTENT column that uses DATE_FORMAT()
> 
> 3-argument form of DATE_FORMAT
> 
> ---
>  mysql-test/r/locale.result                         | 71 +++++++++++++++++++++-
>  .../suite/vcol/r/vcol_blocked_sql_funcs.result     |  2 +
>  .../suite/vcol/r/vcol_supported_sql_funcs.result   | 15 +++++
>  .../suite/vcol/t/vcol_blocked_sql_funcs_main.inc   |  3 +
>  .../suite/vcol/t/vcol_supported_sql_funcs_main.inc |  6 ++
>  mysql-test/t/locale.test                           | 28 +++++++++
>  sql/item_create.cc                                 | 27 +-------
>  sql/item_strfunc.cc                                | 10 +--
>  sql/item_strfunc.h                                 |  4 +-
>  sql/item_timefunc.cc                               | 25 ++++++--
>  sql/item_timefunc.h                                | 27 +++++---
>  sql/lex.h                                          |  1 +
>  sql/sql_yacc.yy                                    | 16 ++++-
>  sql/sql_yacc_ora.yy                                | 16 ++++-
>  14 files changed, 202 insertions(+), 49 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_create.cc b/sql/item_create.cc
> index e0bfe7a4402..88c1ac1f64f 100644
> --- a/sql/item_create.cc
> +++ b/sql/item_create.cc
> @@ -770,19 +770,6 @@ class Create_func_crosses : public Create_func_arg2
>  #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:
> @@ -4023,15 +4010,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*
> @@ -4530,7 +4508,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:
> @@ -6483,7 +6461,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);
>  }
>  
>  
> @@ -6844,7 +6822,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..3e12a545c97 100644
> --- a/sql/item_strfunc.cc
> +++ b/sql/item_strfunc.cc
> @@ -2668,11 +2668,11 @@ String *Item_func_soundex::val_str(String *str)
>  const int FORMAT_MAX_DECIMALS= 30;
>  
>  
> -MY_LOCALE *Item_func_format::get_locale(Item *item)
> +const MY_LOCALE *get_locale(Item *item)
>  {
> -  DBUG_ASSERT(arg_count == 3);
> -  String tmp, *locale_name= args[2]->val_str_ascii(&tmp);
> -  MY_LOCALE *lc;
> +  StringBuffer<MAX_FIELD_WIDTH> tmp;
> +  String *locale_name= item->val_str_ascii(&tmp);
> +  const MY_LOCALE *lc;
>    if (!locale_name ||
>        !(lc= my_locale_by_name(locale_name->c_ptr_safe())))
>    {
> @@ -2712,7 +2712,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();
> diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
> index 685a64816be..542af13df5c 100644
> --- a/sql/item_strfunc.h
> +++ b/sql/item_strfunc.h
> @@ -28,6 +28,7 @@
>  extern size_t username_char_length;
>  
>  class MY_LOCALE;
> +const MY_LOCALE *get_locale(Item *item);
>  
>  class Item_str_func :public Item_func
>  {
> @@ -932,14 +933,13 @@ class Item_func_make_set :public Item_str_func
>  
>  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..5e660c58583 100644
> --- a/sql/item_timefunc.cc
> +++ b/sql/item_timefunc.cc
> @@ -455,7 +455,8 @@ static bool extract_date_time(DATE_TIME_FORMAT *format,
>  */
>  
>  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 @@ bool Item_func_sec_to_time::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
>  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= get_locale(args[2]);
> +  }
>  
>    /*
>      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= get_locale(args[2])))
> +    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 @@ class Item_func_from_days :public Item_datefunc
>  
>  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 @@ class Item_func_date_format :public Item_str_func
>    { 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 a475914d369..54ddd3ae922 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              {}
> _______________________________________________
> commits mailing list
> commits@xxxxxxxxxxx
> https://lists.askmonty.org/cgi-bin/mailman/listinfo/commits
>