List:Commits« Previous MessageNext Message »
From:ahristov Date:August 11 2006 1:29pm
Subject:bk commit into 5.0 tree (andrey:1.2236) BUG#16291
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of andrey. When andrey does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-08-11 15:29:04+02:00, andrey@stripped +1 -0
  Fix for bug#16291: mysqldump corrupts string-constants with non-ascii-chars
  The fix is the part related to stored procedures. There is no test case but one can use this one.
  set names latin1;
  CREATE PROCEDURE `p_test_latin1`() select "öäü";
  --switch the konsole (not mysql) to utf8 to view correctly utf8
  --then switch the connection to utf8
  set names utf8;
  show create procedure p_test_latin1;

  sql/sp.cc@stripped, 2006-08-11 15:29:01+02:00, andrey@stripped +33 -13
    Convert the body of the routine to UTF8, if needed, before storing it into the BLOB.
    If it's not done then the body is encoded with the charset of the client.
    However, we don't store which charset is being used - BIG PROBLEM!
    This fixes bug#16291: "mysqldump corrupts string-constants with non-ascii-chars"
    at least for the part regarding stored routines.

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	andrey
# Host:	example.com
# Root:	/work/mysql-5.0-runtime

--- 1.116/sql/sp.cc	2006-08-11 15:29:14 +02:00
+++ 1.117/sql/sp.cc	2006-08-11 15:29:14 +02:00
@@ -509,6 +509,7 @@
 db_create_routine(THD *thd, int type, sp_head *sp)
 {
   int ret;
+  CHARSET_INFO *scs= system_charset_info;
   TABLE *table;
   char definer[USER_HOST_BUFF_SIZE];
   char old_db_buf[NAME_LEN+1];
@@ -528,6 +529,9 @@
     ret= SP_OPEN_TABLE_FAILED;
   else
   {
+    char body_buf[25 * STRING_BUFFER_USUAL_SIZE];
+    String body_str_utf8(body_buf, sizeof(body_buf), scs);
+
     restore_record(table, s->default_values); // Get default values for fields
 
     /* NOTE: all needed privilege checks have been already done. */
@@ -540,8 +544,7 @@
       goto done;
     }
 
-    if (system_charset_info->cset->numchars(system_charset_info,
-                                            sp->m_name.str,
+    if (system_charset_info->cset->numchars(scs, sp->m_name.str,
                                             sp->m_name.str+sp->m_name.length) >
         table->field[MYSQL_PROC_FIELD_NAME]->char_length())
     {
@@ -553,14 +556,34 @@
       ret= SP_BODY_TOO_LONG;
       goto done;
     }
+    {
+      uint32 offset;
+      if (String::needs_conversion(sp->m_body.length, thd->charset(), scs,
+                                   &offset))
+      {
+        /*
+          Don't create the object here because the memory will be released when
+          the scope is left.
+        */
+        body_str_utf8.length(0);                //make it point to the beginning
+        body_str_utf8.append(sp->m_body.str, sp->m_body.length, thd->charset());
+        DBUG_PRINT("info", ("body=%.*s", body_str_utf8.length(),
+                            body_str_utf8.ptr()));
+        table->field[MYSQL_PROC_FIELD_BODY]->
+                store(body_str_utf8.ptr(), body_str_utf8.length(), scs);
+      }
+      else
+        table->field[MYSQL_PROC_FIELD_BODY]->
+          store(sp->m_body.str, sp->m_body.length, scs);
+    }
     table->field[MYSQL_PROC_FIELD_DB]->
-      store(sp->m_db.str, sp->m_db.length, system_charset_info);
+      store(sp->m_db.str, sp->m_db.length, scs);
     table->field[MYSQL_PROC_FIELD_NAME]->
-      store(sp->m_name.str, sp->m_name.length, system_charset_info);
+      store(sp->m_name.str, sp->m_name.length, scs);
     table->field[MYSQL_PROC_FIELD_TYPE]->
       store((longlong)type);
     table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]->
-      store(sp->m_name.str, sp->m_name.length, system_charset_info);
+      store(sp->m_name.str, sp->m_name.length, scs);
     if (sp->m_chistics->daccess != SP_DEFAULT_ACCESS)
       table->field[MYSQL_PROC_FIELD_ACCESS]->
 	store((longlong)sp->m_chistics->daccess);
@@ -570,26 +593,23 @@
       table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]->
 	store((longlong)sp->m_chistics->suid);
     table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
-      store(sp->m_params.str, sp->m_params.length, system_charset_info);
+      store(sp->m_params.str, sp->m_params.length, scs);
     if (sp->m_type == TYPE_ENUM_FUNCTION)
     {
       String retstr(64);
       sp_returns_type(thd, retstr, sp);
       table->field[MYSQL_PROC_FIELD_RETURNS]->
-	store(retstr.ptr(), retstr.length(), system_charset_info);
+	store(retstr.ptr(), retstr.length(), scs);
     }
-    table->field[MYSQL_PROC_FIELD_BODY]->
-      store(sp->m_body.str, sp->m_body.length, system_charset_info);
     table->field[MYSQL_PROC_FIELD_DEFINER]->
-      store(definer, (uint)strlen(definer), system_charset_info);
+      store(definer, (uint)strlen(definer), scs);
     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time();
     ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time();
     table->field[MYSQL_PROC_FIELD_SQL_MODE]->
       store((longlong)thd->variables.sql_mode);
     if (sp->m_chistics->comment.str)
       table->field[MYSQL_PROC_FIELD_COMMENT]->
-	store(sp->m_chistics->comment.str, sp->m_chistics->comment.length,
-	      system_charset_info);
+	store(sp->m_chistics->comment.str, sp->m_chistics->comment.length, scs);
 
     if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
         !trust_function_creators && mysql_bin_log.is_open())
@@ -629,7 +649,7 @@
       thd->clear_error();
 
       String log_query;
-      log_query.set_charset(system_charset_info);
+      log_query.set_charset(scs);
       log_query.append(STRING_WITH_LEN("CREATE "));
       append_definer(thd, &log_query, &thd->lex->definer->user,
                      &thd->lex->definer->host);
Thread
bk commit into 5.0 tree (andrey:1.2236) BUG#16291ahristov11 Aug