List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:November 14 2008 12:53pm
Subject:bzr commit into mysql-5.0-bugteam branch (Sergey.Glukhov:2714)
Bug#37575
View as plain text  
#At file:///home/gluh/MySQL/mysql-5.0-bug-37575/

 2714 Sergey Glukhov	2008-11-14
      Bug#37575 UCASE fails on monthname
      The MONTHNAME/DAYNAME functions
      returns binary string, so the LOWER/UPPER functions
      are not effective on the result of MONTHNAME/DAYNAME
      call.  
      Character set of the MONTHNAME/DAYNAME function
      result has been changed to connection character set.
modified:
  mysql-test/r/func_time.result
  mysql-test/t/func_time.test
  sql/item_timefunc.cc
  sql/item_timefunc.h
  sql/mysql_priv.h
  sql/mysqld.cc

per-file messages:
  mysql-test/r/func_time.result
    test result
  mysql-test/t/func_time.test
    test case
  sql/item_timefunc.cc
    Item_func_monthname::fix_length_and_dec and
    Item_func_dayname::fix_length_and_dec methods have been
    modified to use connection character set
  sql/item_timefunc.h
    Item_func_monthname::fix_length_and_dec and
    Item_func_dayname::fix_length_and_dec methods have been
    modified to use connection character set
  sql/mysql_priv.h
    MAX_MONTH_NAME_LEN and MAX_DAY_NAME_LEN constants has been defined
    (see the test_lc_time_sz function for initial calculation).
  sql/mysqld.cc
    test_lc_time_sz function have been added.
    The test_lc_time_sz function controls modifications
    of the locale database in debugging mode.
=== modified file 'mysql-test/r/func_time.result'
--- a/mysql-test/r/func_time.result	2008-02-25 10:25:57 +0000
+++ b/mysql-test/r/func_time.result	2008-11-14 11:46:00 +0000
@@ -1308,4 +1308,22 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FRAC_SECOND' at line 1
+SELECT CHARSET(DAYNAME(19700101));
+CHARSET(DAYNAME(19700101))
+latin1
+SELECT CHARSET(MONTHNAME(19700101));
+CHARSET(MONTHNAME(19700101))
+latin1
+SELECT LOWER(DAYNAME(19700101));
+LOWER(DAYNAME(19700101))
+thursday
+SELECT LOWER(MONTHNAME(19700101));
+LOWER(MONTHNAME(19700101))
+january
+SELECT UPPER(DAYNAME(19700101));
+UPPER(DAYNAME(19700101))
+THURSDAY
+SELECT UPPER(MONTHNAME(19700101));
+UPPER(MONTHNAME(19700101))
+JANUARY
 End of 5.0 tests

=== modified file 'mysql-test/t/func_time.test'
--- a/mysql-test/t/func_time.test	2008-02-27 15:12:08 +0000
+++ b/mysql-test/t/func_time.test	2008-11-14 11:46:00 +0000
@@ -829,4 +829,15 @@ SELECT '2008-02-18' + INTERVAL 1 FRAC_SE
 --error ER_PARSE_ERROR
 SELECT '2008-02-18' - INTERVAL 1 FRAC_SECOND;
 
+#
+# Bug#37575: UCASE fails on monthname
+#
+
+SELECT CHARSET(DAYNAME(19700101));
+SELECT CHARSET(MONTHNAME(19700101));
+SELECT LOWER(DAYNAME(19700101));
+SELECT LOWER(MONTHNAME(19700101));
+SELECT UPPER(DAYNAME(19700101));
+SELECT UPPER(MONTHNAME(19700101));
+
 --echo End of 5.0 tests

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2008-01-23 18:48:29 +0000
+++ b/sql/item_timefunc.cc	2008-11-14 11:46:00 +0000
@@ -1036,6 +1036,20 @@ longlong Item_func_month::val_int()
 }
 
 
+void Item_func_monthname::fix_length_and_dec()
+{
+  THD* thd= current_thd;
+  CHARSET_INFO *cs= thd->variables.collation_connection;
+  uint32 repertoire= cs->state;
+  if (!thd->variables.lc_time_names->is_ascii)
+    repertoire|= MY_REPERTOIRE_EXTENDED;
+  collation.set(cs, DERIVATION_EXPLICIT, repertoire);
+  decimals=0;
+  max_length= MAX_MONTH_NAME_LEN * collation.collation->mbmaxlen;
+  maybe_null=1; 
+}
+
+
 String* Item_func_monthname::val_str(String* str)
 {
   DBUG_ASSERT(fixed == 1);
@@ -1050,7 +1064,8 @@ String* Item_func_monthname::val_str(Str
   }
   null_value=0;
   month_name= thd->variables.lc_time_names->month_names->type_names[month-1];
-  str->set(month_name, strlen(month_name), system_charset_info);
+  str->length(0);
+  str->append(month_name, strlen(month_name), collation.collation);
   return str;
 }
 
@@ -1170,6 +1185,20 @@ longlong Item_func_weekday::val_int()
 }
 
 
+void Item_func_dayname::fix_length_and_dec()
+{
+  THD* thd= current_thd;
+  CHARSET_INFO *cs= thd->variables.collation_connection;
+  uint32 repertoire= cs->state;
+  if (!thd->variables.lc_time_names->is_ascii)
+    repertoire|= MY_REPERTOIRE_EXTENDED;
+  collation.set(cs, DERIVATION_EXPLICIT, repertoire);
+  decimals=0;
+  max_length= MAX_DAY_NAME_LEN * collation.collation->mbmaxlen;
+  maybe_null=1; 
+}
+
+
 String* Item_func_dayname::val_str(String* str)
 {
   DBUG_ASSERT(fixed == 1);
@@ -1181,7 +1210,8 @@ String* Item_func_dayname::val_str(Strin
     return (String*) 0;
   
   day_name= thd->variables.lc_time_names->day_names->type_names[weekday];
-  str->set(day_name, strlen(day_name), system_charset_info);
+  str->length(0);
+  str->append(day_name, strlen(day_name), collation.collation);
   return str;
 }
 

=== modified file 'sql/item_timefunc.h'
--- a/sql/item_timefunc.h	2008-01-07 16:55:05 +0000
+++ b/sql/item_timefunc.h	2008-11-14 11:46:00 +0000
@@ -113,13 +113,7 @@ public:
   const char *func_name() const { return "monthname"; }
   String *val_str(String *str);
   enum Item_result result_type () const { return STRING_RESULT; }
-  void fix_length_and_dec() 
-  {
-    collation.set(&my_charset_bin);
-    decimals=0;
-    max_length=10*my_charset_bin.mbmaxlen;
-    maybe_null=1; 
-  }
+  void fix_length_and_dec();
 };
 
 
@@ -277,13 +271,7 @@ class Item_func_dayname :public Item_fun
   const char *func_name() const { return "dayname"; }
   String *val_str(String *str);
   enum Item_result result_type () const { return STRING_RESULT; }
-  void fix_length_and_dec() 
-  { 
-    collation.set(&my_charset_bin);
-    decimals=0; 
-    max_length=9*MY_CHARSET_BIN_MB_MAXLEN;
-    maybe_null=1; 
-  }
+  void fix_length_and_dec();
 };
 
 

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-10-02 11:57:52 +0000
+++ b/sql/mysql_priv.h	2008-11-14 11:46:00 +0000
@@ -122,6 +122,16 @@ enum Derivation
 };
 
 
+/*
+  Maximal number of UTF-8 characters in month/day name
+  over the locale database (see the sql_locale.cc file).
+  Both values should be checked/updated after every
+  modification of that database. The test_lc_time_sz
+  function (see mysqld.cc) controls such modifications.
+*/
+#define MAX_MONTH_NAME_LEN 18
+#define MAX_DAY_NAME_LEN 14
+
 typedef struct my_locale_st
 {
   uint  number;

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-10-09 07:26:42 +0000
+++ b/sql/mysqld.cc	2008-11-14 11:46:00 +0000
@@ -3614,6 +3614,32 @@ void decrement_handler_count()
 #endif /* defined(__NT__) || defined(HAVE_SMEM) */
 
 
+/*
+  Debugging helper function to keep the locale database
+  (see sql_locale.cc) and the MAX_MONTH_NAME_LEN and
+  MAX_DAY_NAME_LEN variable values in consistent state.
+*/
+static void test_lc_time_sz()
+{
+  uint max_month_len= 0;
+  uint max_day_len = 0;
+  for (MY_LOCALE **loc= my_locales; *loc; loc++)
+  {
+    for (const char **month= (*loc)->month_names->type_names; *month; month++)
+      set_if_bigger(max_month_len,
+                    my_numchars_mb(&my_charset_utf8_general_ci,
+                                   *month, *month + strlen(*month)));
+    for (const char **day= (*loc)->day_names->type_names; *day; day++)
+      set_if_bigger(max_day_len,
+                    my_numchars_mb(&my_charset_utf8_general_ci,
+                                   *day, *day + strlen(*day)));
+  }
+  DBUG_ASSERT(max_month_len <= MAX_MONTH_NAME_LEN);
+  DBUG_ASSERT(max_day_len <= MAX_DAY_NAME_LEN);
+  return;
+}
+
+
 #ifndef EMBEDDED_LIBRARY
 #ifdef __WIN__
 int win_main(int argc, char **argv)
@@ -3710,6 +3736,8 @@ int main(int argc, char **argv)
   openlog(libwrapName, LOG_PID, LOG_AUTH);
 #endif
 
+  test_lc_time_sz();
+
   /*
     We have enough space for fiddling with the argv, continue
   */

Thread
bzr commit into mysql-5.0-bugteam branch (Sergey.Glukhov:2714)Bug#37575Sergey Glukhov14 Nov