List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:December 22 2006 12:04pm
Subject:bk commit into 5.0 tree (anozdrin:1.2321) BUG#11986
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of alik. When alik 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-12-22 14:04:43+03:00, anozdrin@booka. +43 -0
  Patch for the following bugs:
    - BUG#11986: Stored routines and triggers can fail if the code
      has a non-ascii symbol
    - BUG#16291: mysqldump corrupts string-constants with non-ascii-chars
    - BUG#25212: Character set of string constant is ignored (stored routines)
    - BUG#25221: Character set of string constant is ignored (triggers)
  
  General overview
  ----------------
  
  There were 2 general problems that caused these bugs:
  1. Character set of definition-query for views, triggers, stored routines
     was lost.
  2. mysqldump outputs query in client character set, which can be
     inappropriate to encode definition-query.
  
  1. No query-definition-character set.
  
  We execute/process objects in the following way:
  
    - Stored routines are stored in the connection cache. In other words,
      stored routines are compiled at first execution in the user connection.
  
    - Triggers are compiled when the table is loaded.
  
  The problem here was that character set of original query could be different
  from the actual character set at the next compilation.
  
  The fix is to store character set and use it each time we compile the
  object. Actually, three character sets should be kept: client character
  set, connection character set and server character set.
  
  2. Wrong mysqldump-output.
  
  The problem here was that we tried to recode definition query to the
  mysqldump-client character set. Moreover, we stored queries in different
  character sets for different objects (views, for one, used UTF8, triggers
  used original character set).
  
  The solution is
    - to store definition queries in the original character set;
    - to change SHOW CREATE statement to output definition query in the
      binary character set (i.e. without any conversion);
    - to dump special statements to switch character set to original one
      before dumping definition-query.
  
  Fix in details
  --------------
  
  1. Stored routines.
  
    - Add client_cs, connection_cs, server_cs columns (as char(32)) to
      mysql.proc table to store client-character-set,
      connection-character-set, server-character-set respectively.
  
    - Store definition context (three character sets) in these fields when
      stored routine is created.
  
    - Switch client, connection and server character sets each time when
      definition query is parsed (i.e. stored routine is compiled).
  
    - In order to provide backward compatibility, assume that the query is in
      UTF8 if there is no definition context for a stored routine. Also, throw a
      warning in this case.
  
    - Add client_cs, connection_cs, server_cs columns in
      INFORMATION_SCHEMA.ROUTINES pseudo-table to show client, connection and
      server character sets respectively.
  
    - Add client_cs, connection_cs, server_cs columns in SHOW PROCEDURE |
      FUNCTION STATUS statement to show client, connection and server
      character sets respectively.
  
    - Add client_cs, connection_cs, server_cs columns in SHOW CREATE
      PROCEDURE | FUNCTION statement to show client, connection and server
      character sets respectively.
  
    - Change character set of Create-column (definition query) in SHOW CREATE
      PROCEDURE | FUNCTION statement to binary to show definition query
      without any conversion.
  
  2. Triggers.
  
    - Store client, connection and server character sets in TRG-file.
  
    - Switch client, connection and server character sets each time when
      triggers for a table are parsed (loaded and compiled). 
  
    - In order to provide backward compatibility, assume that the query is in
      UTF8 if there is no definition context for a trigger. Also, throw a
      warning in this case.
  
    - Add client_cs, connection_cs, server_cs columns in
      INFORMATION_SCHEMA.TRIGGERS pseudo-table to show client, connection and
      server character sets respectively.
  
    - Add client_cs, connection_cs, server_cs columns in SHOW TRIGGERS
      statement to show client, connection and server character sets
      respectively.
  
  3. Views
  
    - Store client, connection and server character sets in FRM-file.
  
    - Store view-definition-query in the original character set in FRM-file.
  
    - Switch client, connection and server character sets each time when
      definition query is parsed and the view is executed.
  
    - In order to provide backward compatibility, assume that the query is in
      UTF8 if there is no definition context for a stored routine. Also, throw a
      warning in this case.
  
    - Add client_cs, connection_cs, server_cs columns in
      INFORMATION_SCHEMA.VIEWS pseudo-table to show client, connection and
      server character sets respectively.
  
    - Add client_cs, connection_cs, server_cs columns in SHOW CREATE
      VIEW statement to show client, connection and server character sets
      respectively.
  
    - Change character set of Create-column (definition query) in SHOW CREATE
      VIEW statement to binary to show definition query without any
      conversion.
  
  4. mysqldump
  
     - The patch fixes only dumps for views and stored routines, because
       triggers do not have SHOW CREATE statement.
  
     - Dump of definition query should be done as follows:
       - Save current character sets (client, connection, server);
       - Switch character sets to the definition query character sets;
       - Dump definition query (CREATE-statement);
       - Restore character sets.
  
  Not fixed problems
  ------------------
  
    - mysqldump does not dump triggers correctly.
      Fix: introduce SHOW CREATE TRIGGER.
  
    - INFORMATION_SCHEMA does not show definition query correctly.
      Fix: convert each definition query to UTF8 when showing in
      INFORMATION_SCHEMA (INFORMATION_SCHEMA must be in UTF8 accorging to The
      Standard). The problem here is that defintion query can contain
      character-set-introducers, i.e. it can have symbols from several
      character sets.
  
    - SHOW TRIGGERS does not work correctly
      Fix: this will be fixed as soon as the problem with INFORMATION_SCHEMA
      is fixed.

  client/mysqldump.c@stripped, 2006-12-22 14:04:36+03:00, anozdrin@booka. +41 -9
    Set original character set and collation before dumping definition query.

  mysql-test/lib/init_db.sql@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +3 -0
    Added columns for mysql.proc.

  mysql-test/r/func_in.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/grant.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +12 -12
    Updated result file.

  mysql-test/r/information_schema.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +35 -32
    Updated result file.

  mysql-test/r/information_schema_db.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/lowercase_view.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +6 -6
    Updated result file.

  mysql-test/r/mysqldump.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +282 -26
    Updated result file.

  mysql-test/r/rpl_ddl.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +26 -14
    Updated result file.

  mysql-test/r/rpl_sp.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +16 -16
    Updated result file.

  mysql-test/r/rpl_trigger.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +3 -3
    Updated result file.

  mysql-test/r/rpl_view.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/show_check.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +20 -20
    Updated result file.

  mysql-test/r/skip_grants.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/sp-destruct.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/sp-error.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +6 -6
    Updated result file.

  mysql-test/r/sp-security.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +8 -8
    Updated result file.

  mysql-test/r/sp.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +46 -19
    Updated result file.

  mysql-test/r/sql_mode.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +4 -4
    Updated result file.

  mysql-test/r/system_mysql_db.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +3 -0
    Updated result file.

  mysql-test/r/temp_table.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +2 -2
    Updated result file.

  mysql-test/r/trigger-compat.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +3 -3
    Updated result file.

  mysql-test/r/trigger-grant.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +9 -9
    Updated result file.

  mysql-test/r/trigger.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +37 -5
    Updated result file.

  mysql-test/r/view.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +110 -80
    Updated result file.

  mysql-test/r/view_grant.result@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +28 -28
    Updated result file.

  mysql-test/t/information_schema.test@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +1 -1
    Provide values for 3 new columns.

  mysql-test/t/mysqldump.test@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +77 -3
    Add test case for BUG#16291.

  mysql-test/t/sp.test@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +61 -1
    Add test case for BUG#25212.

  mysql-test/t/trigger.test@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +66 -0
    Add test case for BUG#25221.

  mysql-test/t/view.test@stripped, 2006-12-22 14:04:37+03:00, anozdrin@booka. +18 -6
    Make the test less dependent on environment.

  scripts/mysql_create_system_tables.sh@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +3 -0
    Add 3 columns to mysql.proc.

  scripts/mysql_fix_privilege_tables.sql@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +3 -0
    Add 3 columns to mysql.proc.

  sql/share/errmsg.txt@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +24 -0
    Add error messages.

  sql/sp.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +139 -15
    Store original query charsets (definition context) in mysql.proc and
    use it to compile SP each time. Show definition context in I_S.ROUTINES,
    SHOW CREATE PROCEDURE | FUNCTION, SHOW PROCEDURE STATUS.

  sql/sp_head.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +61 -4
    Store original query charsets (definition context) in mysql.proc and
    use it to compile SP each time. Show definition context in I_S.ROUTINES,
    SHOW CREATE PROCEDURE | FUNCTION, SHOW PROCEDURE STATUS.

  sql/sp_head.h@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +3 -0
    Store original query charsets (definition context) in mysql.proc and
    use it to compile SP each time. Show definition context in I_S.ROUTINES,
    SHOW CREATE PROCEDURE | FUNCTION, SHOW PROCEDURE STATUS.

  sql/sql_show.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +90 -9
    Show definition context in I_S.ROUTINES, I_S.VIEWS, I_S.TRIGGERS;

  sql/sql_trigger.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +262 -12
    Store original query charsets (definition context) in TRG-file and
    use it when parsing (compiling) the triggers each time. Show definition
    context in I_S.TRIGGERS, SHOW TRIGGERS.

  sql/sql_trigger.h@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +16 -2
    Store original query charsets (definition context) in TRG-file and
    use it when parsing (compiling) the triggers each time. Show definition
    context in I_S.TRIGGERS, SHOW TRIGGERS.

  sql/sql_view.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +130 -7
    Store original query charsets (definition context) in FRM-file and
    use it when parsing and executing the view each time. Show definition
    context in I_S.TRIGGERS, SHOW VIEWS, SHOW CREATE VIEW.

  sql/table.cc@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +22 -0
    Auxilary functions.

  sql/table.h@stripped, 2006-12-22 14:04:39+03:00, anozdrin@booka. +31 -0
    1. Introduce auxiliry structure to store original-query-charsets
       (query definition context).
    2. Add necessary attributes to handle definition context in TABLE_LIST
       structure.

# 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:	anozdrin
# Host:	booka.
# Root:	/home/alik/Documents/MySQL/devel/5.0-rt-charsets

--- 1.250/client/mysqldump.c	2006-12-22 14:04:50 +03:00
+++ 1.251/client/mysqldump.c	2006-12-22 14:04:50 +03:00
@@ -1471,13 +1471,24 @@ static uint dump_routines_for_db(char *d
               we need to change sql_mode only for the CREATE
               PROCEDURE/FUNCTION otherwise we may need to re-quote routine_name
             */;
-            fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/;;\n",
-                    row[1] /* sql_mode */);
-            fprintf(sql_file, "/*!50003 %s */;;\n",
-                    (query_str != NULL ? query_str : row[2]));
             fprintf(sql_file,
-                    "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/"
-                    ";;\n");
+                    "/*!50003 SET SESSION SQL_MODE=\"%s\"*/;;\n"
+                    "SET @saved_cs_client = @@character_set_client;\n"
+                    "SET @saved_cs_results = @@character_set_results;\n"
+                    "SET @saved_cs_connection = @@character_set_connection;\n"
+                    "SET @saved_cs_server = @@character_set_server;\n"
+                    "SET character_set_client = %s;\n"
+                    "SET character_set_results = %s;\n"
+                    "SET character_set_connection = %s;\n"
+                    "SET character_set_server = %s;\n"
+                    "/*!50003 %s */;;\n"
+                    "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;\n",
+                    (const char *) row[1],
+                    (const char *) row[3],
+                    (const char *) row[3],
+                    (const char *) row[4],
+                    (const char *) row[5],
+                    (const char *) (query_str != NULL ? query_str : row[2]));
 
             my_free(query_str, MYF(MY_ALLOW_ZERO_PTR));
           }
@@ -3573,8 +3584,9 @@ static my_bool get_view_structure(char *
 
 
   my_snprintf(query, sizeof(query),
-              "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE "            \
-              "FROM information_schema.views "                          \
+              "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE, "
+              "       CLIENT_CS, CONNECTION_CS, SERVER_CS "
+              "FROM information_schema.views "
               "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
   if (mysql_query(mysql, query))
   {
@@ -3661,7 +3673,27 @@ static my_bool get_view_structure(char *
     }
 
     /* Dump view structure to file */
-    fprintf(sql_file, "/*!50001 %s */;\n", ds_view.str);
+
+    fprintf(sql_file,
+            "SET @saved_cs_client = @@character_set_client;\n"
+            "SET @saved_cs_results = @@character_set_results;\n"
+            "SET @saved_cs_connection = @@character_set_connection;\n"
+            "SET @saved_cs_server = @@character_set_server;\n"
+            "SET character_set_client = %s;\n"
+            "SET character_set_results = %s;\n"
+            "SET character_set_connection = %s;\n"
+            "SET character_set_server = %s;\n"
+            "/*!50001 %s */;\n"
+            "SET character_set_server = @saved_cs_client;\n"
+            "SET character_set_results = @saved_cs_results;\n"
+            "SET character_set_connection = @saved_cs_connection;\n"
+            "SET character_set_server = @saved_cs_server;\n",
+            (const char *) row[3],
+            (const char *) row[3],
+            (const char *) row[4],
+            (const char *) row[5],
+            (const char *) ds_view.str);
+
     check_io(sql_file);
     mysql_free_result(table_res);
     dynstr_free(&ds_view);

--- 1.332/sql/sql_show.cc	2006-12-22 14:04:50 +03:00
+++ 1.333/sql/sql_show.cc	2006-12-22 14:04:50 +03:00
@@ -418,6 +418,10 @@ mysqld_show_create(THD *thd, TABLE_LIST 
   }
 
   buffer.length(0);
+
+  if (table_list->view)
+    buffer.set_charset(table_list->view_def_ctx.client_cs);
+
   if ((table_list->view ?
        view_store_create_info(thd, table_list, &buffer) :
        store_create_info(thd, table_list, &buffer)))
@@ -429,6 +433,12 @@ mysqld_show_create(THD *thd, TABLE_LIST 
     field_list.push_back(new Item_empty_string("View",NAME_LEN));
     field_list.push_back(new Item_empty_string("Create View",
                                                max(buffer.length(),1024)));
+    field_list.push_back(new Item_empty_string("Client CS",
+                                               MY_CS_NAME_SIZE));
+    field_list.push_back(new Item_empty_string("Connection CS",
+                                               MY_CS_NAME_SIZE));
+    field_list.push_back(new Item_empty_string("Server CS",
+                                               MY_CS_NAME_SIZE));
   }
   else
   {
@@ -452,10 +462,29 @@ mysqld_show_create(THD *thd, TABLE_LIST 
     else
       protocol->store(table_list->table->alias, system_charset_info);
   }
-  protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
+
+  if (table_list->view)
+  {
+    protocol->store(buffer.ptr(), buffer.length(), &my_charset_bin);
+
+    protocol->store(table_list->view_def_ctx.client_cs->csname,
+                    strlen(table_list->view_def_ctx.client_cs->csname),
+                    system_charset_info);
+
+    protocol->store(table_list->view_def_ctx.connection_cs->csname,
+                    strlen(table_list->view_def_ctx.connection_cs->csname),
+                    system_charset_info);
+
+    protocol->store(table_list->view_def_ctx.server_cs->csname,
+                    strlen(table_list->view_def_ctx.server_cs->csname),
+                    system_charset_info);
+  }
+  else
+    protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
 
   if (protocol->write())
     DBUG_RETURN(TRUE);
+
   send_eof(thd);
   DBUG_RETURN(FALSE);
 }
@@ -692,7 +721,7 @@ append_identifier(THD *thd, String *pack
 
   if (q == EOF)
   {
-    packet->append(name, length, system_charset_info);
+    packet->append(name, length, packet->charset());
     return;
   }
 
@@ -710,7 +739,7 @@ append_identifier(THD *thd, String *pack
     uchar chr= (uchar) *name;
     length= my_mbcharlen(system_charset_info, chr);
     /*
-      my_mbcharlen can retur 0 on a wrong multibyte
+      my_mbcharlen can return 0 on a wrong multibyte
       sequence. It is possible when upgrading from 4.0,
       and identifier contains some accented characters.
       The manual says it does not work. So we'll just
@@ -720,7 +749,7 @@ append_identifier(THD *thd, String *pack
       length= 1;
     if (length == 1 && chr == (uchar) quote_char)
       packet->append(&quote_char, 1, system_charset_info);
-    packet->append(name, length, packet->charset());
+    packet->append(name, length, system_charset_info);
   }
   packet->append(&quote_char, 1, system_charset_info);
 }
@@ -2977,6 +3006,16 @@ bool store_schema_proc(THD *thd, TABLE *
       get_field(thd->mem_root, proc_table->field[15], &tmp_string);
       table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
       table->field[19]->store(definer.ptr(), definer.length(), cs);
+
+      get_field(thd->mem_root, proc_table->field[16], &tmp_string);
+      table->field[20]->store(tmp_string.ptr(), tmp_string.length(), cs);
+
+      get_field(thd->mem_root, proc_table->field[17], &tmp_string);
+      table->field[21]->store(tmp_string.ptr(), tmp_string.length(), cs);
+
+      get_field(thd->mem_root, proc_table->field[18], &tmp_string);
+      table->field[22]->store(tmp_string.ptr(), tmp_string.length(), cs);
+
       return schema_table_store_record(thd, table);
     }
   }
@@ -3184,6 +3223,19 @@ static int get_schema_views_record(THD *
       table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
     else
       table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
+
+    table->field[8]->store(tables->view_def_ctx.client_cs->csname,
+                           strlen(tables->view_def_ctx.client_cs->csname),
+                           cs);
+
+    table->field[9]->store(tables->view_def_ctx.connection_cs->csname,
+                           strlen(tables->view_def_ctx.connection_cs->csname),
+                           cs);
+
+    table->field[10]->store(tables->view_def_ctx.server_cs->csname,
+                            strlen(tables->view_def_ctx.server_cs->csname),
+                            cs);
+
     if (schema_table_store_record(thd, table))
       DBUG_RETURN(1);
     if (res)
@@ -3277,7 +3329,10 @@ static bool store_trigger(THD *thd, TABL
                           enum trg_action_time_type timing,
                           LEX_STRING *trigger_stmt,
                           ulong sql_mode,
-                          LEX_STRING *definer_buffer)
+                          LEX_STRING *definer_buffer,
+                          LEX_STRING *client_cs_name,
+                          LEX_STRING *connection_cs_name,
+                          LEX_STRING *server_cs_name)
 {
   CHARSET_INFO *cs= system_charset_info;
   byte *sql_mode_str;
@@ -3302,7 +3357,14 @@ static bool store_trigger(THD *thd, TABL
                                                        sql_mode,
                                                        &sql_mode_len);
   table->field[17]->store((const char*)sql_mode_str, sql_mode_len, cs);
-  table->field[18]->store((const char *)definer_buffer->str, definer_buffer->length, cs);
+  table->field[18]->store((const char *)definer_buffer->str,
+                          definer_buffer->length, cs);
+  table->field[19]->store((const char *)client_cs_name->str,
+                          client_cs_name->length, cs);
+  table->field[20]->store((const char *)connection_cs_name->str,
+                          connection_cs_name->length, cs);
+  table->field[21]->store((const char *)server_cs_name->str,
+                          server_cs_name->length, cs);
   return schema_table_store_record(thd, table);
 }
 
@@ -3338,19 +3400,29 @@ static int get_schema_triggers_record(TH
         ulong sql_mode;
         char definer_holder[USER_HOST_BUFF_SIZE];
         LEX_STRING definer_buffer;
+        LEX_STRING client_cs_name;
+        LEX_STRING connection_cs_name;
+        LEX_STRING server_cs_name;
+
         definer_buffer.str= definer_holder;
         if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
                                        (enum trg_action_time_type)timing,
                                        &trigger_name, &trigger_stmt,
                                        &sql_mode,
-                                       &definer_buffer))
+                                       &definer_buffer,
+                                       &client_cs_name,
+                                       &connection_cs_name,
+                                       &server_cs_name))
           continue;
 
         if (store_trigger(thd, table, base_name, file_name, &trigger_name,
                          (enum trg_event_type) event,
                          (enum trg_action_time_type) timing, &trigger_stmt,
                          sql_mode,
-                         &definer_buffer))
+                         &definer_buffer,
+                         &client_cs_name,
+                         &connection_cs_name,
+                         &server_cs_name))
           DBUG_RETURN(1);
       }
     }
@@ -3788,7 +3860,7 @@ int make_character_sets_old_format(THD *
 
 int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
 {
-  int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, -1};
+  int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, 20, 21, 22, -1};
   int *field_num= fields_arr;
   ST_FIELD_INFO *field_info;
   Name_resolution_context *context= &thd->lex->select_lex.context;
@@ -4116,6 +4188,9 @@ ST_FIELD_INFO proc_fields_info[]=
   {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, 0},
   {"ROUTINE_COMMENT", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment"},
   {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer"},
+  {"CLIENT_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Client CS"},
+  {"CONNECTION_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Connection CS"},
+  {"SERVER_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Server CS"},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
@@ -4151,6 +4226,9 @@ ST_FIELD_INFO view_fields_info[]=
   {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0},
   {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0},
   {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"CLIENT_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"CONNECTION_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0},
+  {"SERVER_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 
@@ -4272,6 +4350,9 @@ ST_FIELD_INFO triggers_fields_info[]=
   {"CREATED", 0, MYSQL_TYPE_TIMESTAMP, 0, 1, "Created"},
   {"SQL_MODE", 65535, MYSQL_TYPE_STRING, 0, 0, "sql_mode"},
   {"DEFINER", 65535, MYSQL_TYPE_STRING, 0, 0, "Definer"},
+  {"CLIENT_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Client CS"},
+  {"CONNECTION_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Connection CS"},
+  {"SERVER_CS", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Server CS"},
   {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
 };
 

--- 1.238/sql/table.cc	2006-12-22 14:04:50 +03:00
+++ 1.239/sql/table.cc	2006-12-22 14:04:50 +03:00
@@ -3058,3 +3058,25 @@ Item_subselect *st_table_list::containin
 template class List<String>;
 template class List_iterator<String>;
 #endif
+
+
+/*****************************************************************************
+  Query charset context.
+*****************************************************************************/
+
+bool switch_query_ctx(THD *thd, const st_query_ctx *ctx)
+{
+  thd->variables.character_set_client= ctx->client_cs;
+  thd->variables.collation_connection= ctx->connection_cs;
+  thd->variables.collation_server= ctx->server_cs;
+
+  thd->update_charset();
+}
+
+
+bool save_current_query_ctx(THD *thd, st_query_ctx *ctx)
+{
+  ctx->client_cs= thd->variables.character_set_client;
+  ctx->connection_cs= thd->variables.collation_connection;
+  ctx->server_cs= thd->variables.collation_server;
+}

--- 1.135/sql/table.h	2006-12-22 14:04:50 +03:00
+++ 1.136/sql/table.h	2006-12-22 14:04:50 +03:00
@@ -25,6 +25,18 @@ class st_select_lex;
 class COND_EQUAL;
 class Security_context;
 
+/* Query charset context. */
+
+struct st_query_ctx
+{
+  CHARSET_INFO *client_cs;
+  CHARSET_INFO *connection_cs;
+  CHARSET_INFO *server_cs;
+};
+
+bool switch_query_ctx(THD *thd, const st_query_ctx *ctx);
+bool save_current_query_ctx(THD *thd, st_query_ctx *ctx);
+
 /* Order clause list element */
 
 typedef struct st_order {
@@ -638,6 +650,25 @@ typedef struct st_table_list
     used for implicit LOCK TABLES only and won't be used in real statement.
   */
   bool          prelocking_placeholder;
+
+  /*
+    Character set context, used for parsing and executing the view.
+
+    Charset name attributes (LEX_STRING) are required only to be able to
+    use existing parser to load view-definition file. As soon as the parser
+    parsed the file, charset-attributes are initialized and character set
+    names are redundant.
+
+    Character set names MUST NOT be used for any purposes but the parsing.
+  */
+
+  LEX_STRING view_client_cs_name;
+  LEX_STRING view_connection_cs_name;
+  LEX_STRING view_server_cs_name;
+
+  st_query_ctx view_def_ctx;
+
+  /* End of character ser context. */
 
   void calc_md5(char *buffer);
   void set_underlying_merge();

--- 1.74/sql/share/errmsg.txt	2006-12-22 14:04:50 +03:00
+++ 1.75/sql/share/errmsg.txt	2006-12-22 14:04:50 +03:00
@@ -5634,3 +5634,27 @@ ER_WRONG_STRING_LENGTH
 ER_NON_INSERTABLE_TABLE  
 	eng "The target table %-.100s of the %s is not insertable-into"
 
+ER_VIEW_NO_DEF_CONTEXT
+  eng "View `%-.64s`.`%-.64s` has no definition context (character set information). Non-ascii symbols can be lost. Set appropriate character set and collation manually and recreate the view"
+ER_VIEW_UNKNOWN_CLIENT_CHARSET
+  eng "Unknown client character set `%-.64s` for view `%-.64s`.`%-.64s'"
+ER_VIEW_UNKNOWN_CONNECTION_CHARSET
+  eng "Unknown connection character set `%-.64s` for view `%-.64s`.`%-.64s'"
+ER_VIEW_UNKNOWN_SERVER_CHARSET
+  eng "Unknown server character set `%-.64s` for view `%-.64s`.`%-.64s'"
+
+ER_SR_NO_DEF_CONTEXT
+  eng "Stored routine `%.-64s`.`%-.64s` has no definition context (field `%-.64s` is empty or NULL). Non-ascii symbols can be lost. Set appropriate character set and collation manually and recreate the routine"
+ER_SR_UNKNOWN_CHARSET
+  eng "Unknown character set `%-.64s' in field `%-.64s` for stored routine `%-.64s`.`%-.64s`"
+
+ER_TRG_CORRUPTED_FILE
+  eng "Corrupted TRG-file for table `%-.64s`.`%-.64s`"
+ER_TRG_NO_DEF_CONTEXT
+  eng "Triggers for table `%-.64s`.`%-.64s` has no definition context (character set information). Non-ascii symbols can be lost. Set appropriate character set and collation manually and recreate triggers for the table"
+ER_TRG_UNKNOWN_CLIENT_CHARSET
+  eng "Unknown client character set `%-.64s` in TRG file for table `%-.64s`.`%-.64s`"
+ER_TRG_UNKNOWN_CONNECTION_CHARSET
+  eng "Unknown connection character set `%-.64s` in TRG file for table `%-.64s`.`%-.64s`"
+ER_TRG_UNKNOWN_SERVER_CHARSET
+  eng "Unknown server character set `%-.64s` in TRG file for table `%-.64s`.`%-.64s`"

--- 1.4/mysql-test/r/trigger-compat.result	2006-12-22 14:04:50 +03:00
+++ 1.5/mysql-test/r/trigger-compat.result	2006-12-22 14:04:50 +03:00
@@ -33,9 +33,9 @@ Warnings:
 Warning	1454	No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
 
 SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
-TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER
-NULL	mysqltest_db1	wl2818_trg1	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2 VALUES(CURRENT_USER())	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		
-NULL	mysqltest_db1	wl2818_trg2	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2 VALUES(CURRENT_USER())	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		mysqltest_dfn@localhost
+TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER	CLIENT_CS	CONNECTION_CS	SERVER_CS
+NULL	mysqltest_db1	wl2818_trg1	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2 VALUES(CURRENT_USER())	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL			latin1	latin1	latin1
+NULL	mysqltest_db1	wl2818_trg2	INSERT	NULL	mysqltest_db1	t1	0	NULL	INSERT INTO t2 VALUES(CURRENT_USER())	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		mysqltest_dfn@localhost	latin1	latin1	latin1
 DROP TRIGGER wl2818_trg1;
 Warnings:
 Warning	1454	No definer attribute for trigger 'mysqltest_db1'.'wl2818_trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.

--- 1.6/mysql-test/r/trigger-grant.result	2006-12-22 14:04:50 +03:00
+++ 1.7/mysql-test/r/trigger-grant.result	2006-12-22 14:04:50 +03:00
@@ -81,9 +81,9 @@ Note	1449	There is no 'mysqltest_nonexs'
 INSERT INTO t1 VALUES(6);
 ERROR 42000: Access denied; you need the SUPER privilege for this operation
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-trg1	INSERT	t1	SET @new_sum = 0	BEFORE	NULL		mysqltest_inv@localhost
-trg2	INSERT	t1	SET @new_sum = 0	AFTER	NULL		mysqltest_nonexs@localhost
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+trg1	INSERT	t1	SET @new_sum = 0	BEFORE	NULL		mysqltest_inv@localhost	latin1	latin1	latin1
+trg2	INSERT	t1	SET @new_sum = 0	AFTER	NULL		mysqltest_nonexs@localhost	latin1	latin1	latin1
 DROP TRIGGER trg1;
 DROP TRIGGER trg2;
 CREATE TRIGGER trg1 BEFORE INSERT ON t1
@@ -113,12 +113,12 @@ Warnings:
 Warning	1454	No definer attribute for trigger 'mysqltest_db1'.'trg1'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger.
 
 SELECT * FROM INFORMATION_SCHEMA.TRIGGERS ORDER BY trigger_name;
-TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER
-NULL	mysqltest_db1	trg1	INSERT	NULL	mysqltest_db1	t1	0	NULL	SET @a = 1	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		
-NULL	mysqltest_db1	trg2	INSERT	NULL	mysqltest_db1	t1	0	NULL	SET @a = 2	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		@
-NULL	mysqltest_db1	trg3	UPDATE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 3	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		@abc@def@@
-NULL	mysqltest_db1	trg4	UPDATE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 4	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		@hostname
-NULL	mysqltest_db1	trg5	DELETE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 5	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		@abcdef@@@hostname
+TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER	CLIENT_CS	CONNECTION_CS	SERVER_CS
+NULL	mysqltest_db1	trg1	INSERT	NULL	mysqltest_db1	t1	0	NULL	SET @a = 1	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL			latin1	latin1	latin1
+NULL	mysqltest_db1	trg2	INSERT	NULL	mysqltest_db1	t1	0	NULL	SET @a = 2	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		@	latin1	latin1	latin1
+NULL	mysqltest_db1	trg3	UPDATE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 3	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		@abc@def@@	latin1	latin1	latin1
+NULL	mysqltest_db1	trg4	UPDATE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 4	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		@hostname	latin1	latin1	latin1
+NULL	mysqltest_db1	trg5	DELETE	NULL	mysqltest_db1	t1	0	NULL	SET @a = 5	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		@abcdef@@@hostname	latin1	latin1	latin1
 
 ---> connection: default
 DROP USER mysqltest_dfn@localhost;

--- 1.11/mysql-test/r/lowercase_view.result	2006-12-22 14:04:50 +03:00
+++ 1.12/mysql-test/r/lowercase_view.result	2006-12-22 14:04:50 +03:00
@@ -6,8 +6,8 @@ use MySQLTest;
 create table TaB (Field int);
 create view ViE as select * from TAb;
 show create table VIe;
-View	Create View
-vie	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vie` AS select `tab`.`Field` AS `Field` from `tab`
+View	Create View	Client CS	Connection CS	Server CS
+vie	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `vie` AS select `tab`.`Field` AS `Field` from `tab`	latin1	latin1	latin1
 drop database MySQLTest;
 use test;
 create table t1Aa (col1 int);
@@ -118,8 +118,8 @@ drop table t1Aa,t2Aa;
 create table t1Aa (col1 int);
 create view v1Aa as select col1 from t1Aa as AaA;
 show create view v1AA;
-View	Create View
-v1aa	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1aa` AS select `aaa`.`col1` AS `col1` from `t1aa` `AaA`
+View	Create View	Client CS	Connection CS	Server CS
+v1aa	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1aa` AS select `aaa`.`col1` AS `col1` from `t1aa` `AaA`	latin1	latin1	latin1
 drop view v1AA;
 select Aaa.col1 from t1Aa as AaA;
 col1
@@ -127,7 +127,7 @@ create view v1Aa as select Aaa.col1 from
 drop view v1AA;
 create view v1Aa as select AaA.col1 from t1Aa as AaA;
 show create view v1AA;
-View	Create View
-v1aa	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1aa` AS select `aaa`.`col1` AS `col1` from `t1aa` `AaA`
+View	Create View	Client CS	Connection CS	Server CS
+v1aa	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1aa` AS select `aaa`.`col1` AS `col1` from `t1aa` `AaA`	latin1	latin1	latin1
 drop view v1AA;
 drop table t1Aa;

--- 1.8/mysql-test/r/rpl_view.result	2006-12-22 14:04:50 +03:00
+++ 1.9/mysql-test/r/rpl_view.result	2006-12-22 14:04:50 +03:00
@@ -99,8 +99,8 @@ Field	Type	Null	Key	Default	Extra
 a	int(11)	YES		NULL	
 b	decimal(32,0)	YES		NULL	
 show create table v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,sum(`t1`.`b`) AS `b` from `t1` group by `t1`.`a`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,sum(`t1`.`b`) AS `b` from `t1` group by `t1`.`a`	latin1	latin1	latin1
 select * from v1;
 a	b
 1	6

--- 1.185/mysql-test/r/view.result	2006-12-22 14:04:50 +03:00
+++ 1.186/mysql-test/r/view.result	2006-12-22 14:04:51 +03:00
@@ -34,11 +34,11 @@ c
 6
 11
 show create table v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`	latin1	latin1	latin1
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (`t1`.`b` + 1) AS `c` from `t1`	latin1	latin1	latin1
 show create view t1;
 ERROR HY000: 'test.t1' is not VIEW
 drop table t1;
@@ -57,8 +57,8 @@ Warnings:
 Note	1003	select (`test`.`t1`.`b` + 1) AS `c` from `test`.`t1`
 create algorithm=temptable view v2 (c) as select b+1 from t1;
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t1`.`b` + 1) AS `c` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t1`.`b` + 1) AS `c` from `t1`	latin1	latin1	latin1
 select c from v2;
 c
 3
@@ -567,8 +567,8 @@ set sql_mode='ansi';
 create table t1 ("a*b" int);
 create view v1 as select "a*b" from t1;
 show create view v1;
-View	Create View
-v1	CREATE VIEW "v1" AS select "t1"."a*b" AS "a*b" from "t1"
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE VIEW "v1" AS select "t1"."a*b" AS "a*b" from "t1"	latin1	latin1	latin1
 drop view v1;
 drop table t1;
 set sql_mode=default;
@@ -669,8 +669,8 @@ drop view v1;
 drop table t1;
 CREATE VIEW v1 (f1,f2,f3,f4) AS SELECT connection_id(), pi(), current_user(), version();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select connection_id() AS `f1`,pi() AS `f2`,current_user() AS `f3`,version() AS `f4`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select connection_id() AS `f1`,pi() AS `f2`,current_user() AS `f3`,version() AS `f4`	latin1	latin1	latin1
 drop view v1;
 create table t1 (s1 int);
 create table t2 (s2 int);
@@ -703,14 +703,14 @@ create table t2 (a int);
 create view v1 as select a from t1;
 create view v2 as select a from t2 where a in (select a from v1);
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` AS `a` from `v1`)
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` AS `a` from `v1`)	latin1	latin1	latin1
 drop view v2, v1;
 drop table t1, t2;
 CREATE VIEW `v 1` AS select 5 AS `5`;
 show create view `v 1`;
-View	Create View
-v 1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v 1` AS select 5 AS `5`
+View	Create View	Client CS	Connection CS	Server CS
+v 1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v 1` AS select 5 AS `5`	latin1	latin1	latin1
 drop view `v 1`;
 create database mysqltest;
 create table mysqltest.t1 (a int, b int);
@@ -777,15 +777,15 @@ select * from v3;
 a	b
 1	1
 show create view v3;
-View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from (`v1` join `v2`) where (`v1`.`col1` = `v2`.`col1`)
+View	Create View	Client CS	Connection CS	Server CS
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `v1`.`col1` AS `a`,`v2`.`col1` AS `b` from (`v1` join `v2`) where (`v1`.`col1` = `v2`.`col1`)	latin1	latin1	latin1
 drop view v3, v2, v1;
 drop table t2, t1;
 create function `f``1` () returns int return 5;
 create view v1 as select test.`f``1` ();
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`f``1`() AS `test.``f````1`` ()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`f``1`() AS `test.``f````1`` ()`	latin1	latin1	latin1
 select * from v1;
 test.`f``1` ()
 5
@@ -801,11 +801,11 @@ drop function x;
 create table t2 (col1 char collate latin1_german2_ci);
 create view v2 as select col1 collate latin1_german1_ci from t2;
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `t2`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `t2`	latin1	latin1	latin1
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `t2`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select (`t2`.`col1` collate latin1_german1_ci) AS `col1 collate latin1_german1_ci` from `t2`	latin1	latin1	latin1
 drop view v2;
 drop table t2;
 create table t1 (a int);
@@ -831,17 +831,24 @@ drop view v1;
 drop table t1;
 create view v1 as select 99999999999999999999999999999999999999999999999999999 as col1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 99999999999999999999999999999999999999999999999999999 AS `col1`	latin1	latin1	latin1
 drop view v1;
-create table t (c char);
-create view v as select c from t;
-insert into v values ('');
-select * from v;
-c
-
-drop view v;
-drop table t;
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+SET names utf8;
+create table tü (cü char);
+create view vü as select cü from tü;
+insert into vü values ('ü');
+select * from vü;
+cü
+drop view vü;
+drop table tü;
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
 create table t1 (a int, b int);
 insert into t1 values (1,2), (1,3), (2,4), (2,5), (3,10);
 create view v1(c) as select a+1 from t1 where b >= 4;
@@ -852,8 +859,8 @@ drop view v1;
 drop table t1;
 create view v1 as select cast(1 as char(3));
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(1 as char(3) charset latin1) AS `cast(1 as char(3))`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select cast(1 as char(3) charset latin1) AS `cast(1 as char(3))`	latin1	latin1	latin1
 select * from v1;
 cast(1 as char(3))
 1
@@ -1183,20 +1190,20 @@ drop table t1;
 create table t1 (a int);
 create view v1 as select * from t1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`	latin1	latin1	latin1
 alter algorithm=undefined view v1 as select * from t1 with check option;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` WITH CASCADED CHECK OPTION
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` WITH CASCADED CHECK OPTION	latin1	latin1	latin1
 alter algorithm=merge view v1 as select * from t1 with cascaded check option;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` WITH CASCADED CHECK OPTION
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` WITH CASCADED CHECK OPTION	latin1	latin1	latin1
 alter algorithm=temptable view v1 as select * from t1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`	latin1	latin1	latin1
 drop view v1;
 drop table t1;
 create table t1 (s1 int);
@@ -1867,25 +1874,25 @@ create table t1 (a timestamp default now
 create table t2 (b timestamp default now());
 create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,(`t1`.`a` < now()) AS `t1.a < now()` from (`t1` join `t2`) where (`t1`.`a` < now())
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t2`.`b` AS `b`,(`t1`.`a` < now()) AS `t1.a < now()` from (`t1` join `t2`) where (`t1`.`a` < now())	latin1	latin1	latin1
 drop view v1;
 drop table t1, t2;
 CREATE TABLE t1 ( a varchar(50) );
 CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = current_user())
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = current_user())	latin1	latin1	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = version())
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = version())	latin1	latin1	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = database())
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` = database())	latin1	latin1	latin1
 DROP VIEW v1;
 DROP TABLE t1;
 CREATE TABLE t1 (col1 time);
@@ -1975,8 +1982,8 @@ drop table t1;
 create table t1 (s1 int);
 create view v1 as select var_samp(s1) from t1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select var_samp(`t1`.`s1`) AS `var_samp(s1)` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select var_samp(`t1`.`s1`) AS `var_samp(s1)` from `t1`	latin1	latin1	latin1
 drop view v1;
 drop table t1;
 set sql_mode='strict_all_tables';
@@ -2232,16 +2239,16 @@ CREATE TABLE t1 (date DATE NOT NULL);
 INSERT INTO  t1 VALUES ('2005-09-06');
 CREATE VIEW v1 AS SELECT DAYNAME(date) FROM t1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select dayname(`t1`.`date`) AS `DAYNAME(date)` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select dayname(`t1`.`date`) AS `DAYNAME(date)` from `t1`	latin1	latin1	latin1
 CREATE VIEW v2 AS SELECT DAYOFWEEK(date) FROM t1;
 SHOW CREATE VIEW v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select dayofweek(`t1`.`date`) AS `DAYOFWEEK(date)` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select dayofweek(`t1`.`date`) AS `DAYOFWEEK(date)` from `t1`	latin1	latin1	latin1
 CREATE VIEW v3 AS SELECT WEEKDAY(date) FROM t1;
 SHOW CREATE VIEW v3;
-View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select weekday(`t1`.`date`) AS `WEEKDAY(date)` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select weekday(`t1`.`date`) AS `WEEKDAY(date)` from `t1`	latin1	latin1	latin1
 SELECT DAYNAME('2005-09-06');
 DAYNAME('2005-09-06')
 Tuesday
@@ -2396,13 +2403,13 @@ Error	1347	'test.v1' is not BASE TABLE
 DROP VIEW v1;
 create definer = current_user() sql security invoker view v1 as select 1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`	latin1	latin1	latin1
 drop view v1;
 create definer = current_user sql security invoker view v1 as select 1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`	latin1	latin1	latin1
 drop view v1;
 create table t1 (id INT, primary key(id));
 insert into t1 values (1),(2);
@@ -2431,8 +2438,8 @@ end;
 //
 call p1();
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`	latin1	latin1	latin1
 drop view v1;
 drop procedure p1;
 CREATE VIEW v1 AS SELECT 42 AS Meaning;
@@ -2537,8 +2544,8 @@ drop table t1; 
 show create view v1; 
 drop view v1;
 //
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`id` AS `id` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `test`.`t1`.`id` AS `id` from `t1`	latin1	latin1	latin1
 create table t1(f1 int, f2 int);
 create view v1 as select ta.f1 as a, tb.f1 as b from t1 ta, t1 tb where ta.f1=tb
 .f1 and ta.f2=tb.f2;
@@ -2654,8 +2661,8 @@ CREATE VIEW v1 AS
 SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
 FROM t1 GROUP BY id, t;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second) AS `t`,count(0) AS `COUNT(*)` from `t1` group by `t1`.`id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second)
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second) AS `t`,count(0) AS `COUNT(*)` from `t1` group by `t1`.`id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second)	latin1	latin1	latin1
 SELECT * FROM v1;
 id	t	COUNT(*)
 DROP VIEW v1;
@@ -2682,8 +2689,8 @@ CREATE VIEW v1 AS
 SELECT (year(now())-year(DOB)) AS Age
 FROM t1 HAVING Age < 75;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (year(now()) - year(`t1`.`DOB`)) AS `Age` from `t1` having (`Age` < 75)
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select (year(now()) - year(`t1`.`DOB`)) AS `Age` from `t1` having (`Age` < 75)	latin1	latin1	latin1
 SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75;
 Age
 42
@@ -2810,12 +2817,12 @@ DROP TABLE t1;
 CREATE TABLE t1 (x INT, y INT);
 CREATE ALGORITHM=TEMPTABLE SQL SECURITY INVOKER VIEW v1 AS SELECT x FROM t1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x` from `t1`	latin1	latin1	latin1
 ALTER VIEW v1 AS SELECT x, y FROM t1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x`,`t1`.`y` AS `y` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select `t1`.`x` AS `x`,`t1`.`y` AS `y` from `t1`	latin1	latin1	latin1
 DROP VIEW v1;
 DROP TABLE t1;
 CREATE TABLE t1 (s1 char);
@@ -2875,8 +2882,8 @@ USE test;
 create table t1 (f1 datetime);
 create view v1 as select * from t1 where f1 between now() and now() + interval 1 minute;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute))
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1` where (`t1`.`f1` between now() and (now() + interval 1 minute))	latin1	latin1	latin1
 drop view v1;
 drop table t1;
 DROP TABLE IF EXISTS t1;
@@ -2952,8 +2959,8 @@ t2.ver = (SELECT MAX(t.ver) FROM t2 t WH
 SHOW WARNINGS;
 Level	Code	Message
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=MERGE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk` from (`t1` join `t2` on(((`t2`.`fk` = `t1`.`pk`) and (`t2`.`ver` = (select max(`t`.`ver`) AS `MAX(t.ver)` from `t2` `t` where (`t`.`org` = `t2`.`org`))))))	latin1	latin1	latin1
 DROP VIEW v1;
 DROP TABLE t1, t2;
 DROP FUNCTION IF EXISTS f1;
@@ -3020,7 +3027,30 @@ SELECT * FROM v1;
 TheEnd
 TheEnd
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'The\ZEnd' AS `TheEnd`	latin1	latin1	latin1
+DROP VIEW v1;
+DROP VIEW IF EXISTS v1;
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+SET names utf8;
+CREATE VIEW v1 AS SELECT 'абв';
+SHOW CREATE VIEW v1;
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'абв' AS `абв`	utf8	utf8	latin1
+SELECT * FROM v1;
+абв
+абв
+DROP VIEW v1;
+SHOW CREATE VIEW v1;
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'абв' AS `абв`	utf8	utf8	latin1
+SELECT * FROM v1;
+абв
+абв
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
 DROP VIEW v1;
 End of 5.0 tests.

--- 1.9/mysql-test/r/skip_grants.result	2006-12-22 14:04:51 +03:00
+++ 1.10/mysql-test/r/skip_grants.result	2006-12-22 14:04:51 +03:00
@@ -35,8 +35,8 @@ SELECT 3;
 CREATE DEFINER=a@'' FUNCTION f3() RETURNS INT
 RETURN 3;
 SHOW CREATE VIEW v3;
-View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`a`@`` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`c` AS `c` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`a`@`` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`c` AS `c` from `t1`	latin1	latin1	latin1
 SHOW CREATE PROCEDURE p3;
 Procedure	sql_mode	Create Procedure
 p3		CREATE DEFINER=`a`@`` PROCEDURE `p3`()

--- 1.171/mysql-test/t/view.test	2006-12-22 14:04:51 +03:00
+++ 1.172/mysql-test/t/view.test	2006-12-22 14:04:51 +03:00
@@ -748,12 +748,23 @@ drop view v1;
 #
 # VIEWs with national characters
 #
-create table t (c char);
-create view v as select c from t;
-insert into v values ('');
-select * from v;
-drop view v;
-drop table t;
+
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+
+SET names utf8;
+
+create table tü (cü char);
+create view vü as select cü from tü;
+insert into vü values ('ü');
+select * from vü;
+drop view vü;
+drop table tü;
+
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
 
 #
 # problem with used_tables() of outer reference resolved in VIEW
@@ -2974,5 +2985,6 @@ SELECT * FROM v1;
 SHOW CREATE VIEW v1;
 
 DROP VIEW v1;
+
 
 --echo End of 5.0 tests.

--- 1.99/sql/sql_view.cc	2006-12-22 14:04:51 +03:00
+++ 1.100/sql/sql_view.cc	2006-12-22 14:04:51 +03:00
@@ -598,8 +598,8 @@ err:
 
 /* index of revision number in following table */
 static const int revision_number_position= 8;
-/* index of last required parameter for making view */
-static const int required_view_parameters= 10;
+/* number of required parameters for making view */
+static const int required_view_parameters= 15;
 /* number of backups */
 static const int num_view_backups= 3;
 
@@ -646,6 +646,15 @@ static File_option view_parameters[]=
  {{(char*) STRING_WITH_LEN("source")},
   my_offsetof(TABLE_LIST, source),
   FILE_OPTIONS_ESTRING},
+ {{(char*) STRING_WITH_LEN("client_cs_name")},
+  my_offsetof(TABLE_LIST, view_client_cs_name),
+  FILE_OPTIONS_STRING},
+ {{(char*) STRING_WITH_LEN("connection_cs_name")},
+  my_offsetof(TABLE_LIST, view_connection_cs_name),
+  FILE_OPTIONS_STRING},
+ {{(char*) STRING_WITH_LEN("server_cs_name")},
+  my_offsetof(TABLE_LIST, view_server_cs_name),
+  FILE_OPTIONS_STRING},
  {{NullS, 0},			0,
   FILE_OPTIONS_STRING}
 };
@@ -673,7 +682,7 @@ static int mysql_register_view(THD *thd,
 {
   LEX *lex= thd->lex;
   char buff[4096];
-  String str(buff,(uint32) sizeof(buff), system_charset_info);
+  String str(buff,(uint32) sizeof(buff), thd->charset());
   char md5[MD5_BUFF_LENGTH];
   bool can_be_merged;
   char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
@@ -802,7 +811,30 @@ static int mysql_register_view(THD *thd,
       }
     }
   }
+
 loop_out:
+
+  /* Set view definition context. */
+
+  view->view_def_ctx.client_cs= thd->charset();
+  view->view_def_ctx.connection_cs= thd->variables.collation_connection;
+  view->view_def_ctx.server_cs= thd->variables.collation_server;
+
+  /* Set character set names in order to save view definition file. */
+
+  view->view_client_cs_name.str=
+    (char *) view->view_def_ctx.client_cs->csname;
+  view->view_client_cs_name.length= strlen(view->view_client_cs_name.str);
+
+  view->view_connection_cs_name.str=
+    (char *) view->view_def_ctx.connection_cs->csname;
+  view->view_connection_cs_name.length=
+    strlen(view->view_connection_cs_name.str);
+
+  view->view_server_cs_name.str=
+    (char *) view->view_def_ctx.server_cs->csname;
+  view->view_server_cs_name.length= strlen(view->view_server_cs_name.str);
+
   /*
     Check that table of main select do not used in subqueries.
 
@@ -863,6 +895,7 @@ bool mysql_make_view(THD *thd, File_pars
   TABLE_LIST *top_view= table->top_table();
   int res;
   bool result;
+
   DBUG_ENTER("mysql_make_view");
   DBUG_PRINT("info", ("table: 0x%lx (%s)", (ulong) table, table->table_name));
 
@@ -963,6 +996,80 @@ bool mysql_make_view(THD *thd, File_pars
   /*TODO: md5 test here and warning if it is differ */
 
   /*
+    Initialize view definition context by character set names loaded from
+    the view definition file. Use UTF8 character set if view definition
+    file is of old version and does not contain the character set names.
+  */
+
+  if (!table->view_client_cs_name.str ||
+      !table->view_client_cs_name.length ||
+      !table->view_connection_cs_name.str ||
+      !table->view_connection_cs_name.length ||
+      !table->view_server_cs_name.str ||
+      !table->view_server_cs_name.length)
+  {
+    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                        ER_VIEW_NO_DEF_CONTEXT,
+                        ER(ER_VIEW_NO_DEF_CONTEXT),
+                        (const char *) table->db,
+                        (const char *) table->table_name);
+
+    table->view_def_ctx.client_cs= system_charset_info;
+    table->view_def_ctx.connection_cs= system_charset_info;
+    table->view_def_ctx.server_cs= system_charset_info;
+  }
+  else
+  {
+    table->view_def_ctx.client_cs=
+      get_charset_by_csname(table->view_client_cs_name.str,
+                            MY_CS_PRIMARY, MYF(0));
+
+    if (!table->view_def_ctx.client_cs)
+    {
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                          ER_VIEW_UNKNOWN_CLIENT_CHARSET,
+                          ER(ER_VIEW_UNKNOWN_CLIENT_CHARSET),
+                          (const char *) table->view_client_cs_name.str,
+                          (const char *) table->db,
+                          (const char *) table->table_name);
+
+      table->view_def_ctx.client_cs= system_charset_info;
+    }
+
+    table->view_def_ctx.connection_cs=
+      get_charset_by_csname(table->view_connection_cs_name.str,
+                            MY_CS_PRIMARY, MYF(0));
+
+    if (!table->view_def_ctx.connection_cs)
+    {
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                          ER_VIEW_UNKNOWN_CONNECTION_CHARSET,
+                          ER(ER_VIEW_UNKNOWN_CONNECTION_CHARSET),
+                          (const char *) table->view_connection_cs_name.str,
+                          (const char *) table->db,
+                          (const char *) table->table_name);
+
+      table->view_def_ctx.connection_cs= system_charset_info;
+    }
+
+    table->view_def_ctx.server_cs=
+      get_charset_by_csname(table->view_server_cs_name.str,
+                            MY_CS_PRIMARY, MYF(0));
+
+    if (!table->view_def_ctx.server_cs)
+    {
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                          ER_VIEW_UNKNOWN_SERVER_CHARSET,
+                          ER(ER_VIEW_UNKNOWN_SERVER_CHARSET),
+                          (const char *) table->view_server_cs_name.str,
+                          (const char *) table->db,
+                          (const char *) table->table_name);
+
+      table->view_def_ctx.server_cs= system_charset_info;
+    }
+  }
+
+  /*
     TODO: TABLE mem root should be used here when VIEW will be stored in
     TABLE cache
 
@@ -973,7 +1080,12 @@ bool mysql_make_view(THD *thd, File_pars
   view_select= &lex->select_lex;
   view_select->select_number= ++thd->select_number;
   {
-    ulong save_mode= thd->variables.sql_mode;
+    st_query_ctx saved_view_def_ctx;
+    ulong save_mode;
+
+    /* Switch SQL mode. */
+
+    save_mode= thd->variables.sql_mode;
     /* switch off modes which can prevent normal parsing of VIEW
       - MODE_REAL_AS_FLOAT            affect only CREATE TABLE parsing
       + MODE_PIPES_AS_CONCAT          affect expression parsing
@@ -1000,12 +1112,23 @@ bool mysql_make_view(THD *thd, File_pars
     */
     thd->variables.sql_mode&= ~(MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
                                 MODE_IGNORE_SPACE | MODE_NO_BACKSLASH_ESCAPES);
-    CHARSET_INFO *save_cs= thd->variables.character_set_client;
-    thd->variables.character_set_client= system_charset_info;
+
+    /* Switch query context. */
+
+    save_current_query_ctx(thd, &saved_view_def_ctx);
+    switch_query_ctx(thd, &table->view_def_ctx);
+
+    /* Parse the query. */
+
     res= MYSQLparse((void *)thd);
-    thd->variables.character_set_client= save_cs;
+
+    /* Restore environment. */
+
+    switch_query_ctx(thd, &saved_view_def_ctx);
+
     thd->variables.sql_mode= save_mode;
   }
+
   if (!res && !thd->is_fatal_error)
   {
     TABLE_LIST *view_tables= lex->query_tables;

--- 1.50/mysql-test/r/trigger.result	2006-12-22 14:04:51 +03:00
+++ 1.51/mysql-test/r/trigger.result	2006-12-22 14:04:51 +03:00
@@ -600,9 +600,9 @@ select @a;
 @a
 10
 show triggers;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-t1_bi	INSERT	t1	set new."t1 column" = 5	BEFORE	#	REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI	root@localhost
-t1_af	INSERT	t1	set @a=10	AFTER	#		root@localhost
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+t1_bi	INSERT	t1	set new."t1 column" = 5	BEFORE	#	REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI	root@localhost	latin1	latin1	latin1
+t1_af	INSERT	t1	set @a=10	AFTER	#		root@localhost	latin1	latin1	latin1
 drop table t1;
 set sql_mode="traditional";
 create table t1 (a date);
@@ -622,8 +622,8 @@ t1	CREATE TABLE `t1` (
   `a` date default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show triggers;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-t1_bi	INSERT	t1	set new.a = '2004-01-00'	BEFORE	#		root@localhost
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+t1_bi	INSERT	t1	set new.a = '2004-01-00'	BEFORE	#		root@localhost	latin1	latin1	latin1
 drop table t1;
 create table t1 (id int);
 create trigger t1_ai after insert on t1 for each row reset query cache;
@@ -1278,4 +1278,36 @@ a	b
 2	b
 3	c
 drop table t1;
+DROP TABLE IF EXISTS t1;
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+SET NAMES utf8;
+CREATE TABLE t1(a int, b varchar(32));
+INSERT INTO t1 VALUES(1, CHARSET('xxx'));
+SELECT * FROM t1;
+a	b
+1	utf8
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1
+FOR EACH ROW
+SET NEW.b = CHARSET('a');
+SET NAMES koi8r;
+INSERT INTO t1 VALUES(2, 'xxx');
+SELECT * FROM t1;
+a	b
+1	utf8
+2	utf8
+SET NAMES cp1251;
+ALTER TABLE t1 ADD COLUMN fake INT;
+ALTER TABLE t1 DROP COLUMN fake;
+INSERT INTO t1 VALUES(3, 'xxx');
+SELECT * FROM t1;
+a	b
+1	utf8
+2	utf8
+3	utf8
+DROP TABLE t1;
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
 End of 5.0 tests

--- 1.56/mysql-test/t/trigger.test	2006-12-22 14:04:51 +03:00
+++ 1.57/mysql-test/t/trigger.test	2006-12-22 14:04:51 +03:00
@@ -1547,4 +1547,70 @@ select * from t1;
 
 drop table t1;
 
+#
+# BUG#25221: Character set of string constant is ignored
+#
+
+# Prepare environment (set character set to UTF8 just to avoid ambiguity with
+# initial settings).
+
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+
+SET NAMES utf8;
+
+CREATE TABLE t1(a int, b varchar(32));
+
+# Put the example record -- all records must have the same b-value.
+
+INSERT INTO t1 VALUES(1, CHARSET('xxx'));
+
+SELECT * FROM t1;
+
+# Create trigger with a text literal. From now on CHARSET(<text literal>) must
+# return utf8.
+
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1
+  FOR EACH ROW
+    SET NEW.b = CHARSET('a');
+
+# Set character set to another one (let it be koi8r), initiate the first
+# trigger compilation, execute the trigger and analyze the results.
+
+SET NAMES koi8r;
+
+INSERT INTO t1 VALUES(2, 'xxx');
+
+SELECT * FROM t1;
+
+# Set character set to another one (cp1251).
+
+SET NAMES cp1251;
+
+# Flush trigger cache (invalidate the trigger to forget its executable code).
+# ALTER TABLE statement is used only for flushing purposes.
+
+ALTER TABLE t1 ADD COLUMN fake INT;
+ALTER TABLE t1 DROP COLUMN fake;
+
+# Initiate the second trigger compilation. Execute the trigger and analyze
+# the results.
+
+INSERT INTO t1 VALUES(3, 'xxx');
+
+SELECT * FROM t1;
+
+# That's all - cleanup.
+
+DROP TABLE t1;
+
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
+
 --echo End of 5.0 tests

--- 1.59/sql/sql_trigger.cc	2006-12-22 14:04:51 +03:00
+++ 1.60/sql/sql_trigger.cc	2006-12-22 14:04:51 +03:00
@@ -35,20 +35,35 @@ const char * const triggers_file_ext= ".
 static File_option triggers_file_parameters[]=
 {
   {
-    {(char *) STRING_WITH_LEN("triggers") },
+    { (char *) STRING_WITH_LEN("triggers") },
     my_offsetof(class Table_triggers_list, definitions_list),
     FILE_OPTIONS_STRLIST
   },
   {
-    {(char *) STRING_WITH_LEN("sql_modes") },
+    { (char *) STRING_WITH_LEN("sql_modes") },
     my_offsetof(class Table_triggers_list, definition_modes_list),
     FILE_OPTIONS_ULLLIST
   },
   {
-    {(char *) STRING_WITH_LEN("definers") },
+    { (char *) STRING_WITH_LEN("definers") },
     my_offsetof(class Table_triggers_list, definers_list),
     FILE_OPTIONS_STRLIST
   },
+  {
+    { (char *) STRING_WITH_LEN("client_cs_names") },
+    my_offsetof(class Table_triggers_list, client_cs_names_list),
+    FILE_OPTIONS_STRLIST
+  },
+  {
+    { (char *) STRING_WITH_LEN("connection_cs_names") },
+    my_offsetof(class Table_triggers_list, connection_cs_names_list),
+    FILE_OPTIONS_STRLIST
+  },
+  {
+    { (char *) STRING_WITH_LEN("server_cs_names") },
+    my_offsetof(class Table_triggers_list, server_cs_names_list),
+    FILE_OPTIONS_STRLIST
+  },
   { { 0, 0 }, 0, FILE_OPTIONS_STRING }
 };
 
@@ -65,7 +80,7 @@ File_option sql_modes_parameters=
   .trg file.
 */
 
-static const int TRG_NUM_REQUIRED_PARAMETERS= 4;
+static const int TRG_NUM_REQUIRED_PARAMETERS= 6;
 
 /*
   Structure representing contents of .TRN file which are used to support
@@ -364,6 +379,9 @@ bool Table_triggers_list::create_trigger
   LEX_STRING *trg_definer;
   Item_trigger_field *trg_field;
   struct st_trigname trigname;
+  LEX_STRING *trg_client_cs_name;
+  LEX_STRING *trg_connection_cs_name;
+  LEX_STRING *trg_server_cs_name;
 
 
   /* Trigger must be in the same schema as target table. */
@@ -506,6 +524,34 @@ bool Table_triggers_list::create_trigger
       definers_list.push_back(trg_definer, &table->mem_root))
     goto err_with_cleanup;
 
+  trg_client_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                sizeof (LEX_STRING));
+
+  if (!trg_client_cs_name ||
+      client_cs_names_list.push_back(trg_client_cs_name, &table->mem_root))
+  {
+    goto err_with_cleanup;
+  }
+
+  trg_connection_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                    sizeof (LEX_STRING));
+
+  if (!trg_connection_cs_name ||
+      connection_cs_names_list.push_back(
+        trg_connection_cs_name, &table->mem_root))
+  {
+    goto err_with_cleanup;
+  }
+
+  trg_server_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                sizeof (LEX_STRING));
+
+  if (!trg_server_cs_name ||
+      server_cs_names_list.push_back(trg_server_cs_name, &table->mem_root))
+  {
+    goto err_with_cleanup;
+  }
+
   *trg_sql_mode= thd->variables.sql_mode;
 
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -547,6 +593,20 @@ bool Table_triggers_list::create_trigger
   }
 
   /*
+    Fill character set information.
+  */
+
+  trg_client_cs_name->str= (char *) thd->charset()->csname;
+  trg_client_cs_name->length= strlen(trg_client_cs_name->str);
+
+  trg_connection_cs_name->str=
+    (char *) thd->variables.collation_connection->csname;
+  trg_connection_cs_name->length= strlen(trg_connection_cs_name->str);
+
+  trg_server_cs_name->str= (char *) thd->variables.collation_server->csname;
+  trg_server_cs_name->length= strlen(trg_server_cs_name->str);
+
+  /*
     Create well-formed trigger definition query. Original query is not
     appropriated, because definer-clause can be not truncated.
   */
@@ -690,6 +750,9 @@ bool Table_triggers_list::drop_trigger(T
   List_iterator<LEX_STRING>      it_def(definitions_list);
   List_iterator<ulonglong>       it_mod(definition_modes_list);
   List_iterator<LEX_STRING>      it_definer(definers_list);
+  List_iterator<LEX_STRING>      it_client_cs_name(client_cs_names_list);
+  List_iterator<LEX_STRING>      it_connection_cs_name(connection_cs_names_list);
+  List_iterator<LEX_STRING>      it_server_cs_name(server_cs_names_list);
   char path[FN_REFLEN];
 
   stmt_query->append(thd->query, thd->query_length);
@@ -699,6 +762,9 @@ bool Table_triggers_list::drop_trigger(T
     it_def++;
     it_mod++;
     it_definer++;
+    it_client_cs_name++;
+    it_connection_cs_name++;
+    it_server_cs_name++;
 
     if (my_strcasecmp(table_alias_charset, lex->spname->m_name.str,
                       name->str) == 0)
@@ -710,6 +776,9 @@ bool Table_triggers_list::drop_trigger(T
       it_def.remove();
       it_mod.remove();
       it_definer.remove();
+      it_client_cs_name.remove();
+      it_connection_cs_name.remove();
+      it_server_cs_name.remove();
 
       if (definitions_list.is_empty())
       {
@@ -868,9 +937,13 @@ bool Table_triggers_list::check_n_load(T
         we should initialize the list for safety:
           - sql_modes;
           - definers;
+          - character sets (client, connection, server);
       */
       triggers->definition_modes_list.empty();
       triggers->definers_list.empty();
+      triggers->client_cs_names_list.empty();
+      triggers->connection_cs_names_list.empty();
+      triggers->server_cs_names_list.empty();
 
       if (parser->parse((gptr)triggers, &table->mem_root,
                         triggers_file_parameters,
@@ -940,10 +1013,87 @@ bool Table_triggers_list::check_n_load(T
         it.rewind();
       }
 
+      if (!triggers->definitions_list.is_empty() &&
+          (triggers->client_cs_names_list.is_empty() ||
+           triggers->connection_cs_names_list.is_empty() ||
+           triggers->server_cs_names_list.is_empty()))
+      {
+        /*
+          It is old file format => we should fill lists of character sets.
+        */
+
+        LEX_STRING *trg_client_cs_name;
+        LEX_STRING *trg_connection_cs_name;
+        LEX_STRING *trg_server_cs_name;
+
+        if (!triggers->client_cs_names_list.is_empty() ||
+            !triggers->connection_cs_names_list.is_empty() ||
+            !triggers->server_cs_names_list.is_empty())
+        {
+          my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
+                   (const char *) db,
+                   (const char *) table_name);
+
+          DBUG_RETURN(1); // EOM
+        }
+
+        push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                            ER_TRG_NO_DEF_CONTEXT,
+                            ER(ER_TRG_NO_DEF_CONTEXT),
+                            (const char*) db,
+                            (const char*) table_name);
+
+        trg_client_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                      sizeof (LEX_STRING));
+        trg_connection_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                          sizeof (LEX_STRING));
+        trg_server_cs_name= (LEX_STRING *) alloc_root(&table->mem_root,
+                                                      sizeof (LEX_STRING));
+
+        if (!trg_client_cs_name ||
+            !trg_connection_cs_name ||
+            !trg_server_cs_name)
+        {
+          DBUG_RETURN(1); // EOM
+        }
+
+        /* Default character set is UTF8. */
+
+        trg_client_cs_name->str= (char *) system_charset_info->csname;
+        trg_client_cs_name->length= strlen(trg_client_cs_name->str);
+
+        trg_connection_cs_name->str= trg_client_cs_name->str;
+        trg_connection_cs_name->length= trg_client_cs_name->length;
+
+        trg_server_cs_name->str= trg_client_cs_name->str;
+        trg_server_cs_name->length= trg_client_cs_name->length;
+
+        while (it++)
+        {
+          if (triggers->client_cs_names_list.push_back(
+                trg_client_cs_name, &table->mem_root) ||
+              triggers->connection_cs_names_list.push_back(
+                trg_connection_cs_name, &table->mem_root) ||
+              triggers->server_cs_names_list.push_back(
+                trg_server_cs_name, &table->mem_root))
+          {
+            DBUG_RETURN(1); // EOM
+          }
+        }
+
+        it.rewind();
+      }
+
       DBUG_ASSERT(triggers->definition_modes_list.elements ==
                   triggers->definitions_list.elements);
       DBUG_ASSERT(triggers->definers_list.elements ==
                   triggers->definitions_list.elements);
+      DBUG_ASSERT(triggers->client_cs_names_list.elements ==
+                  triggers->definitions_list.elements);
+      DBUG_ASSERT(triggers->connection_cs_names_list.elements ==
+                  triggers->definitions_list.elements);
+      DBUG_ASSERT(triggers->server_cs_names_list.elements ==
+                  triggers->definitions_list.elements);
 
       table->triggers= triggers;
 
@@ -967,6 +1117,9 @@ bool Table_triggers_list::check_n_load(T
 
       List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
       List_iterator_fast<LEX_STRING> it_definer(triggers->definers_list);
+      List_iterator_fast<LEX_STRING> it_client_cs_name(triggers->client_cs_names_list);
+      List_iterator_fast<LEX_STRING> it_connection_cs_name(triggers->connection_cs_names_list);
+      List_iterator_fast<LEX_STRING> it_server_cs_name(triggers->server_cs_names_list);
       LEX *old_lex= thd->lex, lex;
       sp_rcontext *save_spcont= thd->spcont;
       ulong save_sql_mode= thd->variables.sql_mode;
@@ -980,13 +1133,82 @@ bool Table_triggers_list::check_n_load(T
       while ((trg_create_str= it++))
       {
         trg_sql_mode= itm++;
-        LEX_STRING *trg_definer= it_definer++;
 
         thd->variables.sql_mode= (ulong)*trg_sql_mode;
         lex_start(thd, (uchar*)trg_create_str->str, trg_create_str->length);
 
 	thd->spcont= 0;
-        if (MYSQLparse((void *)thd) || thd->is_fatal_error)
+
+        LEX_STRING *trg_definer= it_definer++;
+        LEX_STRING *trg_client_cs_name= it_client_cs_name++;
+        LEX_STRING *trg_connection_cs_name= it_connection_cs_name++;
+        LEX_STRING *trg_server_cs_name= it_server_cs_name++;
+
+        CHARSET_INFO *client_cs=
+          get_charset_by_csname(
+            trg_client_cs_name->str, MY_CS_PRIMARY, MYF(0));
+
+        CHARSET_INFO *connection_cs=
+          get_charset_by_csname(
+            trg_connection_cs_name->str, MY_CS_PRIMARY, MYF(0));
+
+        CHARSET_INFO *server_cs=
+          get_charset_by_csname(
+            trg_server_cs_name->str, MY_CS_PRIMARY, MYF(0));
+
+        if (!client_cs)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                              ER_TRG_UNKNOWN_CLIENT_CHARSET,
+                              ER(ER_TRG_UNKNOWN_CLIENT_CHARSET),
+                              (const char *) trg_client_cs_name->str,
+                              (const char *) db,
+                              (const char *) table_name);
+
+          DBUG_RETURN(1);
+        }
+
+        if (!connection_cs)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                              ER_TRG_UNKNOWN_CONNECTION_CHARSET,
+                              ER(ER_TRG_UNKNOWN_CONNECTION_CHARSET),
+                              (const char *) trg_connection_cs_name->str,
+                              (const char *) db,
+                              (const char *) table_name);
+
+          DBUG_RETURN(1);
+        }
+
+        if (!server_cs)
+        {
+          push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
+                              ER_TRG_UNKNOWN_SERVER_CHARSET,
+                              ER(ER_TRG_UNKNOWN_SERVER_CHARSET),
+                              (const char *) trg_server_cs_name->str,
+                              (const char *) db,
+                              (const char *) table_name);
+
+          DBUG_RETURN(1);
+        }
+
+        st_query_ctx saved_def_ctx;
+        st_query_ctx *def_ctx=
+          (st_query_ctx *) alloc_root(&table->mem_root,
+                                      sizeof (st_query_ctx));
+
+        def_ctx->client_cs= client_cs;
+        def_ctx->connection_cs= connection_cs;
+        def_ctx->server_cs= server_cs;
+
+        save_current_query_ctx(thd, &saved_def_ctx);
+        switch_query_ctx(thd, def_ctx);
+
+        int parse_status= MYSQLparse((void *)thd);
+
+        switch_query_ctx(thd, &saved_def_ctx);
+
+        if (parse_status || thd->is_fatal_error)
         {
           /*
             Free lex associated resources.
@@ -998,8 +1220,11 @@ bool Table_triggers_list::check_n_load(T
 
         lex.sphead->set_info(0, 0, &lex.sp_chistics, *trg_sql_mode);
 
-        triggers->bodies[lex.trg_chistics.event]
-                             [lex.trg_chistics.action_time]= lex.sphead;
+        int event= lex.trg_chistics.event;
+        int action_time= lex.trg_chistics.action_time;
+
+        triggers->bodies[event][action_time]= lex.sphead;
+        triggers->def_ctx[event][action_time]= def_ctx;
 
         if (!trg_definer->length)
         {
@@ -1140,7 +1365,10 @@ bool Table_triggers_list::get_trigger_in
                                            LEX_STRING *trigger_name,
                                            LEX_STRING *trigger_stmt,
                                            ulong *sql_mode,
-                                           LEX_STRING *definer)
+                                           LEX_STRING *definer,
+                                           LEX_STRING *client_cs_name,
+                                           LEX_STRING *connection_cs_name,
+                                           LEX_STRING *server_cs_name)
 {
   sp_head *body;
   DBUG_ENTER("get_trigger_info");
@@ -1161,6 +1389,18 @@ bool Table_triggers_list::get_trigger_in
                                body->m_definer_host.str, NullS) - definer->str;
     }
 
+    client_cs_name->str=
+      (char *) def_ctx[event][time_type]->client_cs->csname;
+    client_cs_name->length= strlen(client_cs_name->str);
+
+    connection_cs_name->str=
+      (char *) def_ctx[event][time_type]->connection_cs->csname;
+    connection_cs_name->length= strlen(connection_cs_name->str);
+
+    server_cs_name->str=
+      (char *) def_ctx[event][time_type]->server_cs->csname;
+    server_cs_name->length= strlen(server_cs_name->str);
+
     DBUG_RETURN(0);
   }
   DBUG_RETURN(1);
@@ -1556,9 +1796,19 @@ bool Table_triggers_list::process_trigge
     }
 
     thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER);
-    err_status= sp_trigger->execute_trigger
-      (thd, table->s->db, table->s->table_name,
-       &subject_table_grants[event][time_type]);
+
+    /*
+      NOTE: there is no need to switch query context (character sets) here,
+      because compiled code contains all necessary charset information.
+    */
+
+    err_status=
+      sp_trigger->execute_trigger(
+        thd,
+        table->s->db,
+        table->s->table_name,
+        &subject_table_grants[event][time_type]);
+
     thd->restore_sub_statement_state(&statement_state);
   }
 

--- 1.22/sql/sql_trigger.h	2006-12-22 14:04:51 +03:00
+++ 1.23/sql/sql_trigger.h	2006-12-22 14:04:51 +03:00
@@ -18,7 +18,7 @@
 /*
   This class holds all information about triggers of table.
 
-  QQ: Will it be merged into TABLE in future ?
+  QQ: Will it be merged into TABLE in the future ?
 */
 
 class Table_triggers_list: public Sql_alloc
@@ -83,12 +83,23 @@ public:
 
   List<LEX_STRING>  definers_list;
 
+  /* Character set context, used for parsing and executing triggers. */
+
+  List<LEX_STRING> client_cs_names_list;
+  List<LEX_STRING> connection_cs_names_list;
+  List<LEX_STRING> server_cs_names_list;
+
+  st_query_ctx *def_ctx[TRG_EVENT_MAX][TRG_ACTION_MAX];
+
+  /* End of character ser context. */
+
   Table_triggers_list(TABLE *table_arg):
     record1_field(0), table(table_arg)
   {
     bzero((char *)bodies, sizeof(bodies));
     bzero((char *)trigger_fields, sizeof(trigger_fields));
     bzero((char *)&subject_table_grants, sizeof(subject_table_grants));
+    bzero((char *)def_ctx, sizeof(def_ctx));
   }
   ~Table_triggers_list();
 
@@ -101,7 +112,10 @@ public:
                         trg_action_time_type time_type,
                         LEX_STRING *trigger_name, LEX_STRING *trigger_stmt,
                         ulong *sql_mode,
-                        LEX_STRING *definer);
+                        LEX_STRING *definer,
+                        LEX_STRING *client_cs_name,
+                        LEX_STRING *connection_cs_name,
+                        LEX_STRING *server_cs_name);
 
   static bool check_n_load(THD *thd, const char *db, const char *table_name,
                            TABLE *table, bool names_only);

--- 1.18/mysql-test/r/rpl_sp.result	2006-12-22 14:04:51 +03:00
+++ 1.19/mysql-test/r/rpl_sp.result	2006-12-22 14:04:51 +03:00
@@ -17,21 +17,21 @@ insert into t1 values (b);
 insert into t1 values (unix_timestamp());
 end|
 select * from mysql.proc where name='foo' and db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 mysqltest1	foo	PROCEDURE	foo	SQL	CONTAINS_SQL	NO	DEFINER			begin
 declare b int;
 set b = 8;
 insert into t1 values (b);
 insert into t1 values (unix_timestamp());
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 select * from mysql.proc where name='foo' and db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 mysqltest1	foo	PROCEDURE	foo	SQL	CONTAINS_SQL	NO	DEFINER			begin
 declare b int;
 set b = 8;
 insert into t1 values (b);
 insert into t1 values (unix_timestamp());
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 set timestamp=1000000000;
 call foo();
 select * from t1;
@@ -115,15 +115,15 @@ select * from t2;
 a
 20
 select * from mysql.proc where name="foo4" and db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 mysqltest1	foo4	PROCEDURE	foo4	SQL	CONTAINS_SQL	YES	DEFINER			begin
 insert into t2 values(20),(20);
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 drop procedure foo4;
 select * from mysql.proc where name="foo4" and db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 select * from mysql.proc where name="foo4" and db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 drop procedure foo;
 drop procedure foo2;
 drop procedure foo3;
@@ -202,16 +202,16 @@ select fn3();
 fn3()
 0
 select * from mysql.proc where db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 mysqltest1	fn1	FUNCTION	fn1	SQL	NO_SQL	NO	DEFINER		int(11)	begin
 return unix_timestamp();
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 mysqltest1	fn2	FUNCTION	fn2	SQL	NO_SQL	NO	DEFINER		int(11)	begin
 return unix_timestamp();
-end	zedjzlcsjhd@localhost	#	#		
+end	zedjzlcsjhd@localhost	#	#			latin1	latin1	latin1
 mysqltest1	fn3	FUNCTION	fn3	SQL	READS_SQL_DATA	NO	DEFINER		int(11)	begin
 return 0;
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 select * from t1;
 a
 1000000000
@@ -220,16 +220,16 @@ select * from t1;
 a
 1000000000
 select * from mysql.proc where db='mysqltest1';
-db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment
+db	name	type	specific_name	language	sql_data_access	is_deterministic	security_type	param_list	returns	body	definer	created	modified	sql_mode	comment	client_cs	connection_cs	server_cs
 mysqltest1	fn1	FUNCTION	fn1	SQL	NO_SQL	NO	DEFINER		int(11)	begin
 return unix_timestamp();
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 mysqltest1	fn2	FUNCTION	fn2	SQL	NO_SQL	NO	DEFINER		int(11)	begin
 return unix_timestamp();
-end	zedjzlcsjhd@localhost	#	#		
+end	zedjzlcsjhd@localhost	#	#			latin1	latin1	latin1
 mysqltest1	fn3	FUNCTION	fn3	SQL	READS_SQL_DATA	NO	DEFINER		int(11)	begin
 return 0;
-end	root@localhost	#	#		
+end	root@localhost	#	#			latin1	latin1	latin1
 delete from t2;
 alter table t2 add unique (a);
 drop function fn1;

--- 1.116/mysql-test/r/information_schema.result	2006-12-22 14:04:51 +03:00
+++ 1.117/mysql-test/r/information_schema.result	2006-12-22 14:04:51 +03:00
@@ -256,11 +256,11 @@ parameter_style	sql_data_access	dtd_iden
 SQL	CONTAINS SQL	NULL
 SQL	CONTAINS SQL	int(11)
 show procedure status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	sel2	PROCEDURE	root@localhost	#	#	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	sel2	PROCEDURE	root@localhost	#	#	DEFINER		latin1	latin1	latin1
 show function status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	sub1	FUNCTION	root@localhost	#	#	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	sub1	FUNCTION	root@localhost	#	#	DEFINER		latin1	latin1	latin1
 select a.ROUTINE_NAME from information_schema.ROUTINES a,
 information_schema.SCHEMATA b where
 a.ROUTINE_SCHEMA = b.SCHEMA_NAME;
@@ -319,8 +319,8 @@ Function	sql_mode	Create Function
 sub2		CREATE DEFINER=`mysqltest_1`@`localhost` FUNCTION `sub2`(i int) RETURNS int(11)
 return i+1
 show function status like "sub2";
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	sub2	FUNCTION	mysqltest_1@localhost	#	#	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	sub2	FUNCTION	mysqltest_1@localhost	#	#	DEFINER		latin1	latin1	latin1
 drop function sub2;
 show create procedure sel2;
 Procedure	sql_mode	Create Procedure
@@ -368,12 +368,12 @@ latin1_spanish_ci
 show keys from v4;
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
 select * from information_schema.views where TABLE_NAME like "v%";
-TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE
-NULL	test	v0	/* ALGORITHM=UNDEFINED */ select `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata`	NONE	NO	root@localhost	DEFINER
-NULL	test	v1	/* ALGORITHM=UNDEFINED */ select `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1')	NONE	NO	root@localhost	DEFINER
-NULL	test	v2	/* ALGORITHM=UNDEFINED */ select `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2')	NONE	NO	root@localhost	DEFINER
-NULL	test	v3	/* ALGORITHM=UNDEFINED */ select `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%')	NONE	NO	root@localhost	DEFINER
-NULL	test	v4	/* ALGORITHM=UNDEFINED */ select `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%')	NONE	NO	root@localhost	DEFINER
+TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE	CLIENT_CS	CONNECTION_CS	SERVER_CS
+NULL	test	v0	/* ALGORITHM=UNDEFINED */ select `schemata`.`SCHEMA_NAME` AS `c` from `information_schema`.`schemata`	NONE	NO	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v1	/* ALGORITHM=UNDEFINED */ select `tables`.`TABLE_NAME` AS `c` from `information_schema`.`tables` where (`tables`.`TABLE_NAME` = _utf8'v1')	NONE	NO	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v2	/* ALGORITHM=UNDEFINED */ select `columns`.`COLUMN_NAME` AS `c` from `information_schema`.`columns` where (`columns`.`TABLE_NAME` = _utf8'v2')	NONE	NO	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v3	/* ALGORITHM=UNDEFINED */ select `character_sets`.`CHARACTER_SET_NAME` AS `c` from `information_schema`.`character_sets` where (`character_sets`.`CHARACTER_SET_NAME` like _utf8'latin1%')	NONE	NO	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v4	/* ALGORITHM=UNDEFINED */ select `collations`.`COLLATION_NAME` AS `c` from `information_schema`.`collations` where (`collations`.`COLLATION_NAME` like _utf8'latin1%')	NONE	NO	root@localhost	DEFINER	latin1	latin1	latin1
 drop view v0, v1, v2, v3, v4;
 create table t1 (a int);
 grant select,update,insert on t1 to mysqltest_1@localhost;
@@ -463,10 +463,10 @@ create view v1 (c) as select a from t1 w
 create view v2 (c) as select a from t1 WITH LOCAL CHECK OPTION;
 create view v3 (c) as select a from t1 WITH CASCADED CHECK OPTION;
 select * from information_schema.views;
-TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE
-NULL	test	v1	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	CASCADED	YES	root@localhost	DEFINER
-NULL	test	v2	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	LOCAL	YES	root@localhost	DEFINER
-NULL	test	v3	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	CASCADED	YES	root@localhost	DEFINER
+TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE	CLIENT_CS	CONNECTION_CS	SERVER_CS
+NULL	test	v1	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	CASCADED	YES	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v2	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	LOCAL	YES	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v3	/* ALGORITHM=UNDEFINED */ select `test`.`t1`.`a` AS `c` from `test`.`t1`	CASCADED	YES	root@localhost	DEFINER	latin1	latin1	latin1
 grant select (a) on test.t1 to joe@localhost with grant option;
 select * from INFORMATION_SCHEMA.COLUMN_PRIVILEGES;
 GRANTEE	TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	COLUMN_NAME	PRIVILEGE_TYPE	IS_GRANTABLE
@@ -567,6 +567,9 @@ proc	created	timestamp
 proc	modified	timestamp
 proc	sql_mode	set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE')
 proc	comment	char(64)
+proc	client_cs	char(32)
+proc	connection_cs	char(32)
+proc	server_cs	char(32)
 drop table t115;
 create procedure p108 () begin declare c cursor for select data_type
 from information_schema.columns;  open c; open c; end;//
@@ -681,13 +684,13 @@ select constraint_name from information_
 where table_schema='test';
 constraint_name
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `test`.`t1`.`f1` AS `c` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `test`.`t1`.`f1` AS `c` from `t1`	latin1	latin1	latin1
 Warnings:
 Warning	1356	View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 show create table v3;
-View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `test`.`sub1`(1) AS `c`
+View	Create View	Client CS	Connection CS	Server CS
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `test`.`sub1`(1) AS `c`	latin1	latin1	latin1
 Warnings:
 Warning	1356	View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
 drop view v2;
@@ -823,39 +826,39 @@ set @fired:= "Yes";
 end if;
 end|
 show triggers;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 trg1	INSERT	t1	begin
 if new.j > 10 then
 set new.j := 10;
 end if;
-end	BEFORE	NULL		root@localhost
+end	BEFORE	NULL		root@localhost	latin1	latin1	latin1
 trg2	UPDATE	t1	begin
 if old.i % 2 = 0 then
 set new.j := -1;
 end if;
-end	BEFORE	NULL		root@localhost
+end	BEFORE	NULL		root@localhost	latin1	latin1	latin1
 trg3	UPDATE	t1	begin
 if new.j = -1 then
 set @fired:= "Yes";
 end if;
-end	AFTER	NULL		root@localhost
+end	AFTER	NULL		root@localhost	latin1	latin1	latin1
 select * from information_schema.triggers;
-TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER
+TRIGGER_CATALOG	TRIGGER_SCHEMA	TRIGGER_NAME	EVENT_MANIPULATION	EVENT_OBJECT_CATALOG	EVENT_OBJECT_SCHEMA	EVENT_OBJECT_TABLE	ACTION_ORDER	ACTION_CONDITION	ACTION_STATEMENT	ACTION_ORIENTATION	ACTION_TIMING	ACTION_REFERENCE_OLD_TABLE	ACTION_REFERENCE_NEW_TABLE	ACTION_REFERENCE_OLD_ROW	ACTION_REFERENCE_NEW_ROW	CREATED	SQL_MODE	DEFINER	CLIENT_CS	CONNECTION_CS	SERVER_CS
 NULL	test	trg1	INSERT	NULL	test	t1	0	NULL	begin
 if new.j > 10 then
 set new.j := 10;
 end if;
-end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		root@localhost
+end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		root@localhost	latin1	latin1	latin1
 NULL	test	trg2	UPDATE	NULL	test	t1	0	NULL	begin
 if old.i % 2 = 0 then
 set new.j := -1;
 end if;
-end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		root@localhost
+end	ROW	BEFORE	NULL	NULL	OLD	NEW	NULL		root@localhost	latin1	latin1	latin1
 NULL	test	trg3	UPDATE	NULL	test	t1	0	NULL	begin
 if new.j = -1 then
 set @fired:= "Yes";
 end if;
-end	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		root@localhost
+end	ROW	AFTER	NULL	NULL	OLD	NEW	NULL		root@localhost	latin1	latin1	latin1
 drop trigger trg1;
 drop trigger trg2;
 drop trigger trg3;
@@ -1107,7 +1110,7 @@ drop table t1;
 use mysql;
 INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
 'NO','DEFINER','','','BEGIN\r\n  \r\nEND','root@%','2006-03-02 18:40:03',
-'2006-03-02 18:40:03','','');
+'2006-03-02 18:40:03','','', 'latin1', 'latin1', 'latin1');
 select routine_name from information_schema.routines;
 routine_name
 
@@ -1120,9 +1123,9 @@ create definer = mysqltest_1@localhost
 sql security definer view v2 as select 1;
 select * from information_schema.views
 where table_name='v1' or table_name='v2';
-TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE
-NULL	test	v1		NONE	YES	root@localhost	DEFINER
-NULL	test	v2	/* ALGORITHM=UNDEFINED */ select 1 AS `1`	NONE	NO	mysqltest_1@localhost	DEFINER
+TABLE_CATALOG	TABLE_SCHEMA	TABLE_NAME	VIEW_DEFINITION	CHECK_OPTION	IS_UPDATABLE	DEFINER	SECURITY_TYPE	CLIENT_CS	CONNECTION_CS	SERVER_CS
+NULL	test	v1		NONE	YES	root@localhost	DEFINER	latin1	latin1	latin1
+NULL	test	v2	/* ALGORITHM=UNDEFINED */ select 1 AS `1`	NONE	NO	mysqltest_1@localhost	DEFINER	latin1	latin1	latin1
 drop view v1, v2;
 drop table t1;
 drop user mysqltest_1@localhost;

--- 1.87/mysql-test/t/information_schema.test	2006-12-22 14:04:51 +03:00
+++ 1.88/mysql-test/t/information_schema.test	2006-12-22 14:04:51 +03:00
@@ -819,7 +819,7 @@ drop table t1;
 use mysql;
 INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
 'NO','DEFINER','','','BEGIN\r\n  \r\nEND','root@%','2006-03-02 18:40:03',
-'2006-03-02 18:40:03','','');
+'2006-03-02 18:40:03','','', 'latin1', 'latin1', 'latin1');
 select routine_name from information_schema.routines;
 delete from proc where name='';
 use test;

--- 1.9/mysql-test/r/information_schema_db.result	2006-12-22 14:04:51 +03:00
+++ 1.10/mysql-test/r/information_schema_db.result	2006-12-22 14:04:51 +03:00
@@ -123,8 +123,8 @@ show fields from testdb_1.v1;
 Field	Type	Null	Key	Default	Extra
 f1	char(4)	YES		NULL	
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`testdb_2`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v2` AS select `v1`.`f1` AS `f1` from `testdb_1`.`v1`	latin1	latin1	latin1
 show create view testdb_1.v1;
 ERROR 42000: SHOW VIEW command denied to user 'testdb_2'@'localhost' for table 'v1'
 select table_name from information_schema.columns a 

--- 1.35/mysql-test/r/sql_mode.result	2006-12-22 14:04:51 +03:00
+++ 1.36/mysql-test/r/sql_mode.result	2006-12-22 14:04:51 +03:00
@@ -469,12 +469,12 @@ create table t1 (a int);
 create table t2 (a int);
 create view v1 as select a from t1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`	latin1	latin1	latin1
 SET @@SQL_MODE='ANSI_QUOTES';
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER="root"@"localhost" SQL SECURITY DEFINER VIEW "v1" AS select "t1"."a" AS "a" from "t1"
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER="root"@"localhost" SQL SECURITY DEFINER VIEW "v1" AS select "t1"."a" AS "a" from "t1"	latin1	latin1	latin1
 create view v2 as select a from t2 where a in (select a from v1);
 drop view v2, v1;
 drop table t1, t2;

--- 1.19/mysql-test/r/view_grant.result	2006-12-22 14:04:51 +03:00
+++ 1.20/mysql-test/r/view_grant.result	2006-12-22 14:04:51 +03:00
@@ -25,8 +25,8 @@ ERROR 42000: CREATE VIEW command denied 
 create view v2 as select * from mysqltest.t2;
 ERROR 42000: ANY command denied to user 'mysqltest_1'@'localhost' for table 't2'
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1`	latin1	latin1	latin1
 grant create view,drop,select on test.* to mysqltest_1@localhost;
 use test;
 alter view v1 as select * from mysqltest.t1;
@@ -125,28 +125,28 @@ explain select c from mysqltest.v1;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	system	NULL	NULL	NULL	NULL	0	const row not found
 show create view mysqltest.v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v1` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`	latin1	latin1	latin1
 explain select c from mysqltest.v2;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	0	const row not found
 2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
 show create view mysqltest.v2;
-View	Create View
-v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v2` AS select (`mysqltest`.`t1`.`a` + 1) AS `c`,(`mysqltest`.`t1`.`b` + 1) AS `d` from `mysqltest`.`t1`	latin1	latin1	latin1
 explain select c from mysqltest.v3;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t2	system	NULL	NULL	NULL	NULL	0	const row not found
 show create view mysqltest.v3;
-View	Create View
-v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
+View	Create View	Client CS	Connection CS	Server CS
+v3	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v3` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`	latin1	latin1	latin1
 explain select c from mysqltest.v4;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	0	const row not found
 2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
 show create view mysqltest.v4;
-View	Create View
-v4	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`
+View	Create View	Client CS	Connection CS	Server CS
+v4	CREATE ALGORITHM=TEMPTABLE DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest`.`v4` AS select (`mysqltest`.`t2`.`a` + 1) AS `c`,(`mysqltest`.`t2`.`b` + 1) AS `d` from `mysqltest`.`t2`	latin1	latin1	latin1
 revoke all privileges on mysqltest.* from mysqltest_1@localhost;
 delete from mysql.user where user='mysqltest_1';
 drop database mysqltest;
@@ -315,8 +315,8 @@ grant select on mysqltest.t1 to mysqltes
 grant create view,select on test.* to mysqltest_1@localhost;
 create view v1 as select * from mysqltest.t1;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_1`@`localhost` SQL SECURITY DEFINER VIEW `test`.`v1` AS select `mysqltest`.`t1`.`a` AS `a`,`mysqltest`.`t1`.`b` AS `b` from `mysqltest`.`t1`	latin1	latin1	latin1
 revoke select on mysqltest.t1 from mysqltest_1@localhost;
 select * from v1;
 ERROR HY000: View 'test.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
@@ -483,15 +483,15 @@ grant all on test.* to 'test14256'@'%';
 use test;
 create view v1 as select 42;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42`	latin1	latin1	latin1
 select definer into @v1def1 from information_schema.views
 where table_schema = 'test' and table_name='v1';
 drop view v1;
 create definer=`test14256`@`%` view v1 as select 42;
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`test14256`@`%` SQL SECURITY DEFINER VIEW `v1` AS select 42 AS `42`	latin1	latin1	latin1
 select definer into @v1def2 from information_schema.views
 where table_schema = 'test' and table_name='v1';
 drop view v1;
@@ -507,8 +507,8 @@ use mysqltest;
 CREATE TABLE t1 (i INT);
 CREATE VIEW  v1 AS SELECT * FROM t1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1`	latin1	latin1	latin1
 GRANT SELECT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost;
 use mysqltest;
 LOCK TABLES v1 READ;
@@ -526,11 +526,11 @@ create definer=some_user@localhost sql s
 Warnings:
 Note	1449	There is no 'some_user'@'localhost' registered
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`	latin1	latin1	latin1
 show create view v2;
-View	Create View
-v2	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v2	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v2` AS select 1 AS `1`	latin1	latin1	latin1
 drop view v1;
 drop view v2;
 CREATE DATABASE mysqltest1;
@@ -609,8 +609,8 @@ CREATE DEFINER = 'no-such-user'@localhos
 Warnings:
 Note	1449	There is no 'no-such-user'@'localhost' registered
 SHOW CREATE VIEW v;
-View	Create View
-v	CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `t1`.`a` AS `a` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v	CREATE ALGORITHM=UNDEFINED DEFINER=`no-such-user`@`localhost` SQL SECURITY DEFINER VIEW `v` AS select `t1`.`a` AS `a` from `t1`	latin1	latin1	latin1
 Warnings:
 Note	1449	There is no 'no-such-user'@'localhost' registered
 SELECT * FROM v;
@@ -626,14 +626,14 @@ CREATE TABLE t1 (f1 INTEGER);
 CREATE VIEW view1 AS
 SELECT * FROM t1;
 SHOW CREATE VIEW view1;
-View	Create View
-view1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+view1	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view1` AS select `t1`.`f1` AS `f1` from `t1`	latin1	latin1	latin1
 CREATE VIEW view2 AS
 SELECT * FROM view1;
 # Here comes a suspicious warning
 SHOW CREATE VIEW view2;
-View	Create View
-view2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1`
+View	Create View	Client CS	Connection CS	Server CS
+view2	CREATE ALGORITHM=UNDEFINED DEFINER=`mysqltest_db1`@`localhost` SQL SECURITY DEFINER VIEW `view2` AS select `view1`.`f1` AS `f1` from `view1`	latin1	latin1	latin1
 # But the view view2 is usable
 SELECT * FROM view2;
 f1

--- 1.14/mysql-test/lib/init_db.sql	2006-12-22 14:04:51 +03:00
+++ 1.15/mysql-test/lib/init_db.sql	2006-12-22 14:04:51 +03:00
@@ -555,5 +555,8 @@ CREATE TABLE proc (
                         'HIGH_NOT_PRECEDENCE'
                     ) DEFAULT '' NOT NULL,
   comment           char(64) collate utf8_bin DEFAULT '' NOT NULL,
+  client_cs         char(32),
+  connection_cs     char(32),
+  server_cs         char(32),
   PRIMARY KEY (db,name,type)
 ) character set utf8 comment='Stored Procedures';

--- 1.11/mysql-test/r/rpl_ddl.result	2006-12-22 14:04:51 +03:00
+++ 1.12/mysql-test/r/rpl_ddl.result	2006-12-22 14:04:51 +03:00
@@ -1128,6 +1128,9 @@ Modified	#
 Created	#
 Security_type	DEFINER
 Comment	
+Client CS	latin1
+Connection CS	latin1
+Server CS	latin1
 	-------- switch to slave -------
 SHOW PROCEDURE STATUS LIKE 'p1';
 Db	mysqltest1
@@ -1138,6 +1141,9 @@ Modified	#
 Created	#
 Security_type	DEFINER
 Comment	
+Client CS	latin1
+Connection CS	latin1
+Server CS	latin1
 
 ######## ALTER PROCEDURE p1 COMMENT "I have been altered"  ########
 
@@ -1194,6 +1200,9 @@ Modified	#
 Created	#
 Security_type	DEFINER
 Comment	I have been altered
+Client CS	latin1
+Connection CS	latin1
+Server CS	latin1
 	-------- switch to slave -------
 SHOW PROCEDURE STATUS LIKE 'p1';
 Db	mysqltest1
@@ -1204,6 +1213,9 @@ Modified	#
 Created	#
 Security_type	DEFINER
 Comment	I have been altered
+Client CS	latin1
+Connection CS	latin1
+Server CS	latin1
 
 ######## DROP PROCEDURE p1  ########
 
@@ -1302,13 +1314,13 @@ flush logs;
 
 -------- switch to master -------
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`	latin1	latin1	latin1
 
 -------- switch to slave -------
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`	latin1	latin1	latin1
 
 ######## ALTER VIEW v1 AS select f1 from t1  ########
 
@@ -1357,13 +1369,13 @@ flush logs;
 
 -------- switch to master -------
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`	latin1	latin1	latin1
 
 -------- switch to slave -------
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`f1` AS `f1` from `t1`	latin1	latin1	latin1
 
 ######## DROP VIEW IF EXISTS v1  ########
 
@@ -1465,13 +1477,13 @@ flush logs;
 
 -------- switch to master -------
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-trg1	INSERT	t1	SET @a:=1	BEFORE	NULL		root@localhost
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+trg1	INSERT	t1	SET @a:=1	BEFORE	NULL		root@localhost	latin1	latin1	latin1
 
 -------- switch to slave -------
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-trg1	INSERT	t1	SET @a:=1	BEFORE	NULL		root@localhost
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+trg1	INSERT	t1	SET @a:=1	BEFORE	NULL		root@localhost	latin1	latin1	latin1
 
 ######## DROP TRIGGER trg1  ########
 
@@ -1520,11 +1532,11 @@ flush logs;
 
 -------- switch to master -------
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 
 -------- switch to slave -------
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 
 ######## CREATE USER user1@localhost  ########
 

--- 1.29/mysql-test/r/func_in.result	2006-12-22 14:04:51 +03:00
+++ 1.30/mysql-test/r/func_in.result	2006-12-22 14:04:51 +03:00
@@ -225,8 +225,8 @@ a
 46
 CREATE VIEW v1 AS SELECT * FROM t1 WHERE a NOT IN (45);
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` <> 45)
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1` where (`t1`.`a` <> 45)	latin1	latin1	latin1
 SELECT * FROM v1;
 a
 44

--- 1.82/mysql-test/r/show_check.result	2006-12-22 14:04:51 +03:00
+++ 1.83/mysql-test/r/show_check.result	2006-12-22 14:04:51 +03:00
@@ -570,48 +570,48 @@ DROP VIEW IF EXISTS v1;
 DROP PROCEDURE IF EXISTS p1;
 CREATE VIEW v1 AS SELECT 1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select 1 AS `1`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_CACHE 1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_NO_CACHE 1;
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache 1 AS `1`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_CACHE NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_NO_CACHE NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_NO_CACHE SQL_CACHE NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE VIEW v1 AS SELECT SQL_CACHE SQL_NO_CACHE SQL_CACHE NOW();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache now() AS `NOW()`	binary	binary	latin1
 DROP VIEW v1;
 CREATE PROCEDURE p1()
 BEGIN
@@ -622,8 +622,8 @@ DROP PREPARE stmt;
 END |
 CALL p1();
 SHOW CREATE VIEW v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1`	binary	binary	latin1
 DROP PROCEDURE p1;
 DROP VIEW v1;
 SHOW TABLES FROM no_such_database;

--- 1.21/mysql-test/r/temp_table.result	2006-12-22 14:04:51 +03:00
+++ 1.22/mysql-test/r/temp_table.result	2006-12-22 14:04:51 +03:00
@@ -111,8 +111,8 @@ v1	CREATE TEMPORARY TABLE `v1` (
   `A` varchar(19) NOT NULL default ''
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'This is view' AS `A`
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _latin1'This is view' AS `A`	latin1	latin1	latin1
 drop view v1;
 select * from v1;
 A

--- 1.60/mysql-test/r/grant.result	2006-12-22 14:04:51 +03:00
+++ 1.61/mysql-test/r/grant.result	2006-12-22 14:04:51 +03:00
@@ -893,11 +893,11 @@ ERROR 42000: SHOW VIEW command denied to
 SHOW CREATE TABLE mysqltest2.v_yn;
 ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v_yn'
 SHOW CREATE TABLE mysqltest2.v_ny;
-View	Create View
-v_ny	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn`
+View	Create View	Client CS	Connection CS	Server CS
+v_ny	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn`	latin1	latin1	latin1
 SHOW CREATE VIEW  mysqltest2.v_ny;
-View	Create View
-v_ny	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn`
+View	Create View	Client CS	Connection CS	Server CS
+v_ny	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_ny` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn`	latin1	latin1	latin1
 SHOW CREATE TABLE mysqltest3.t_nn;
 ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 't_nn'
 SHOW CREATE VIEW  mysqltest3.t_nn;
@@ -914,17 +914,17 @@ t_nn	CREATE TABLE `t_nn` (
 SHOW CREATE VIEW  mysqltest2.t_nn;
 ERROR HY000: 'mysqltest2.t_nn' is not VIEW
 SHOW CREATE VIEW mysqltest2.v_yy;
-View	Create View
-v_yy	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55)
+View	Create View	Client CS	Connection CS	Server CS
+v_yy	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55)	latin1	latin1	latin1
 SHOW CREATE TABLE mysqltest2.v_yy;
-View	Create View
-v_yy	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55)
+View	Create View	Client CS	Connection CS	Server CS
+v_yy	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `mysqltest2`.`v_yy` AS select `mysqltest2`.`t_nn`.`c1` AS `c1` from `mysqltest2`.`t_nn` where (`mysqltest2`.`t_nn`.`c1` = 55)	latin1	latin1	latin1
 SHOW CREATE TABLE mysqltest2.v_nn;
-View	Create View
-v_nn	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn`
+View	Create View	Client CS	Connection CS	Server CS
+v_nn	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn`	latin1	latin1	latin1
 SHOW CREATE VIEW  mysqltest2.v_nn;
-View	Create View
-v_nn	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn`
+View	Create View	Client CS	Connection CS	Server CS
+v_nn	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v_nn` AS select `t_nn`.`c1` AS `c1` from `t_nn`	latin1	latin1	latin1
 SHOW CREATE TABLE mysqltest2.t_nn;
 Table	Create Table
 t_nn	CREATE TABLE `t_nn` (

--- 1.11/mysql-test/r/rpl_trigger.result	2006-12-22 14:04:51 +03:00
+++ 1.12/mysql-test/r/rpl_trigger.result	2006-12-22 14:04:51 +03:00
@@ -865,8 +865,8 @@ Tables_in_test (t_)
 t1
 t2
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
-trg1	INSERT	t1	INSERT INTO t2 VALUES(CURRENT_USER())	AFTER	NULL		
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
+trg1	INSERT	t1	INSERT INTO t2 VALUES(CURRENT_USER())	AFTER	NULL			latin1	latin1	latin1
 SELECT * FROM t1;
 c
 1
@@ -892,7 +892,7 @@ RESET SLAVE;
 SHOW TABLES LIKE 't_';
 Tables_in_test (t_)
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 RESET MASTER;
 START SLAVE;
 

--- 1.34/scripts/mysql_fix_privilege_tables.sql	2006-12-22 14:04:51 +03:00
+++ 1.35/scripts/mysql_fix_privilege_tables.sql	2006-12-22 14:04:51 +03:00
@@ -463,6 +463,9 @@ CREATE TABLE IF NOT EXISTS proc (
                         'HIGH_NOT_PRECEDENCE'
                     ) DEFAULT '' NOT NULL,
   comment           char(64) collate utf8_bin DEFAULT '' NOT NULL,
+  client_cs         char(32),
+  connection_cs     char(32),
+  server_cs         char(32),
   PRIMARY KEY (db,name,type)
 ) engine=MyISAM
   character set utf8

--- 1.5/mysql-test/r/sp-destruct.result	2006-12-22 14:04:51 +03:00
+++ 1.6/mysql-test/r/sp-destruct.result	2006-12-22 14:04:51 +03:00
@@ -78,6 +78,6 @@ drop function bug14233_1;
 drop function bug14233_2;
 drop procedure bug14233_3;
 show procedure status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
 show function status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS

--- 1.109/mysql-test/r/sp-error.result	2006-12-22 14:04:51 +03:00
+++ 1.110/mysql-test/r/sp-error.result	2006-12-22 14:04:51 +03:00
@@ -682,8 +682,8 @@ create procedure bug17015_01234567890123
 begin
 end|
 show procedure status like 'bug17015%'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	bug17015_0123456789012345678901234567890123456789012345678901234	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	bug17015_0123456789012345678901234567890123456789012345678901234	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 drop procedure bug17015_0123456789012345678901234567890123456789012345678901234|
 drop procedure if exists bug10969|
 create procedure bug10969()
@@ -1087,8 +1087,8 @@ create procedure p2() select version();
 ERROR 3D000: No database selected
 use mysqltest2;
 show procedure status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-mysqltest2	p1	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+mysqltest2	p1	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 drop database mysqltest2;
 use test;
 DROP FUNCTION IF EXISTS bug13012|
@@ -1178,8 +1178,8 @@ call ` bug15658`();
 1
 1
 show procedure status;
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	 bug15658	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	 bug15658	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 drop procedure ` bug15658`;
 drop function if exists bug14270;
 drop table if exists t1;

--- 1.31/mysql-test/r/sp-security.result	2006-12-22 14:04:51 +03:00
+++ 1.32/mysql-test/r/sp-security.result	2006-12-22 14:04:51 +03:00
@@ -11,12 +11,12 @@ create table t1 ( u varchar(64), i int )
 create procedure stamp(i int)
 insert into db1_secret.t1 values (user(), i);
 show procedure status like 'stamp';
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-db1_secret	stamp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+db1_secret	stamp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 create function db() returns varchar(64) return database();
 show function status like 'db';
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-db1_secret	db	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+db1_secret	db	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 call stamp(1);
 select * from t1;
 u	i
@@ -55,12 +55,12 @@ user1@localhost	2
 anon@localhost	3
 alter procedure stamp sql security invoker;
 show procedure status like 'stamp';
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-db1_secret	stamp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+db1_secret	stamp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER		latin1	latin1	latin1
 alter function db sql security invoker;
 show function status like 'db';
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-db1_secret	db	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+db1_secret	db	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER		latin1	latin1	latin1
 call stamp(4);
 select * from t1;
 u	i

--- 1.215/mysql-test/r/sp.result	2006-12-22 14:04:51 +03:00
+++ 1.216/mysql-test/r/sp.result	2006-12-22 14:04:51 +03:00
@@ -1219,12 +1219,12 @@ n	f
 20	2432902008176640000
 drop table t3|
 show function status like '%f%'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	fac	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	fac	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 drop procedure ifac|
 drop function fac|
 show function status like '%f%'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
 drop table if exists t3|
 create table t3 (
 i int unsigned not null primary key,
@@ -1314,9 +1314,9 @@ end if;
 end loop;
 end
 show procedure status like '%p%'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	ip	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
-test	opp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	ip	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
+test	opp	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 call ip(200)|
 select * from t3 where i=45 or i=100 or i=199|
 i	p
@@ -1327,7 +1327,7 @@ drop table t3|
 drop procedure opp|
 drop procedure ip|
 show procedure status like '%p%'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
 drop table if exists t3|
 create table t3 ( f bigint unsigned not null )|
 drop procedure if exists fib|
@@ -1379,8 +1379,8 @@ create procedure bar(x char(16), y int)
 comment "111111111111" sql security invoker
 insert into test.t1 values (x, y)|
 show procedure status like 'bar'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	bar	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER	111111111111
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	bar	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	INVOKER	111111111111	latin1	latin1	latin1
 alter procedure bar comment "2222222222" sql security definer|
 alter procedure bar comment "3333333333"|
 alter procedure bar|
@@ -1390,8 +1390,8 @@ bar		CREATE DEFINER=`root`@`localhost` P
     COMMENT '3333333333'
 insert into test.t1 values (x, y)
 show procedure status like 'bar'|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	bar	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	3333333333
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	bar	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	3333333333	latin1	latin1	latin1
 drop procedure bar|
 drop procedure if exists p1|
 create procedure p1 ()
@@ -1956,14 +1956,14 @@ show create function bug2267_4;
 end|
 create function bug2267_4() returns int return 100|
 call bug2267_1()|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	bug2267_1	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
-test	bug2267_2	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
-test	bug2267_3	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
-test	bug2267_4	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	bug2267_1	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
+test	bug2267_2	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
+test	bug2267_3	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
+test	bug2267_4	PROCEDURE	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 call bug2267_2()|
-Db	Name	Type	Definer	Modified	Created	Security_type	Comment
-test	bug2267_4	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER	
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment	Client CS	Connection CS	Server CS
+test	bug2267_4	FUNCTION	root@localhost	0000-00-00 00:00:00	0000-00-00 00:00:00	DEFINER		latin1	latin1	latin1
 call bug2267_3()|
 Procedure	sql_mode	Create Procedure
 bug2267_1		CREATE DEFINER=`root`@`localhost` PROCEDURE `bug2267_1`()
@@ -5405,7 +5405,7 @@ DROP PROCEDURE bug21414|
 set names utf8|
 drop database if exists това_е_дълго_име_за_база_данни_нали|
 create database това_е_дълго_име_за_база_данни_нали|
-INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')|
+INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','', 'utf8', 'utf8', 'latin1')|
 call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()|
 ERROR HY000: Failed to load routine това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго. The table mysql.proc is missing, corrupt, or contains bad data (internal code -6)
 drop database това_е_дълго_име_за_база_данни_нали|
@@ -5626,5 +5626,32 @@ Called B
 Called B
 drop procedure proc_21462_a|
 drop procedure proc_21462_b|
+DROP PROCEDURE IF EXISTS bug25212|
+
+---> connection: bug25212_con1
+SET NAMES utf8;
+CREATE PROCEDURE bug25212()
+SELECT CHARSET('string literal'), COLLATION('string_literal')|
+
+---> connection: bug25212_con2
+SET NAMES cp1251|
+CALL bug25212()|
+CHARSET('string literal')	COLLATION('string_literal')
+utf8	utf8_general_ci
+SET NAMES koi8r|
+CALL bug25212()|
+CHARSET('string literal')	COLLATION('string_literal')
+utf8	utf8_general_ci
+
+---> connection: bug25212_con3
+SET NAMES koi8r|
+CALL bug25212()|
+CHARSET('string literal')	COLLATION('string_literal')
+utf8	utf8_general_ci
+SET NAMES cp1251|
+CALL bug25212()|
+CHARSET('string literal')	COLLATION('string_literal')
+utf8	utf8_general_ci
+DROP PROCEDURE bug25212|
 End of 5.0 tests
 drop table t1,t2;

--- 1.205/mysql-test/t/sp.test	2006-12-22 14:04:51 +03:00
+++ 1.206/mysql-test/t/sp.test	2006-12-22 14:04:51 +03:00
@@ -6350,7 +6350,7 @@ set names utf8|
 drop database if exists това_е_дълго_име_за_база_данни_нали|
 --enable_warnings
 create database това_е_дълго_име_за_база_данни_нали|
-INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','')|
+INSERT INTO mysql.proc VALUES ('това_е_дълго_име_за_база_данни_нали','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','PROCEDURE','това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго','SQL','CONTAINS_SQL','NO','DEFINER','','','bad_body','root@localhost',now(), now(),'','', 'utf8', 'utf8', 'latin1')|
 --error ER_SP_PROC_TABLE_CORRUPT
 call това_е_дълго_име_за_база_данни_нали.това_е_процедура_с_доста_дълго_име_нали_и_още_по_дълго()|
 drop database това_е_дълго_име_за_база_данни_нали|
@@ -6586,6 +6586,66 @@ call proc_21462_b(1)|
 
 drop procedure proc_21462_a|
 drop procedure proc_21462_b|
+
+
+#
+# BUG#25212: Character set of string constant is ignored 
+#
+
+# Prepare.
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug25212|
+--enable_warnings
+
+# Create procedure.
+
+--connect (bug25212_con1,localhost,root,,)
+--connection bug25212_con1
+--echo
+--echo ---> connection: bug25212_con1
+
+SET NAMES utf8;
+
+CREATE PROCEDURE bug25212()
+  SELECT CHARSET('string literal'), COLLATION('string_literal')|
+
+# Make a separate connection, set some character set and execute the stored
+# routine.
+
+--connect (bug25212_con2,localhost,root,,)
+--connection bug25212_con2
+--echo
+--echo ---> connection: bug25212_con2
+
+SET NAMES cp1251|
+
+CALL bug25212()|
+
+SET NAMES koi8r|
+
+CALL bug25212()|
+
+# Make another connection, set another character set and execute the stored
+# routine again.
+
+--connect (bug25212_con3,localhost,root,,)
+--connection bug25212_con3
+--echo
+--echo ---> connection: bug25212_con3
+
+SET NAMES koi8r|
+
+CALL bug25212()|
+
+SET NAMES cp1251|
+
+CALL bug25212()|
+
+# Cleanup.
+
+DROP PROCEDURE bug25212|
+
 
 --echo End of 5.0 tests
 

--- 1.122/sql/sp.cc	2006-12-22 14:04:51 +03:00
+++ 1.123/sql/sp.cc	2006-12-22 14:04:51 +03:00
@@ -37,7 +37,10 @@ static int
 db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
                 ulong sql_mode, const char *params, const char *returns,
                 const char *body, st_sp_chistics &chistics,
-                const char *definer, longlong created, longlong modified);
+                const char *definer, longlong created, longlong modified,
+                CHARSET_INFO *client_cs,
+                CHARSET_INFO *connection_cs,
+                CHARSET_INFO *server_cs);
 
 /*
  *
@@ -63,6 +66,9 @@ enum
   MYSQL_PROC_FIELD_MODIFIED,
   MYSQL_PROC_FIELD_SQL_MODE,
   MYSQL_PROC_FIELD_COMMENT,
+  MYSQL_PROC_FIELD_CLIENT_CS,
+  MYSQL_PROC_FIELD_CONNECTION_CS,
+  MYSQL_PROC_FIELD_SERVER_CS,
   MYSQL_PROC_FIELD_COUNT
 };
 
@@ -226,6 +232,59 @@ db_find_routine_aux(THD *thd, int type, 
 }
 
 
+static void
+db_retrieve_cs(THD *thd, const sp_name *name, Field *field, CHARSET_INFO **cs)
+{
+  char str_buffer[33];
+  String str(str_buffer, sizeof (str_buffer), system_charset_info);
+
+  if (field->is_null())
+  {
+    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                        ER_SR_NO_DEF_CONTEXT,
+                        ER(ER_SR_NO_DEF_CONTEXT),
+                        (const char *) name->m_db.str,
+                        (const char *) name->m_name.str,
+                        (const char *) field->field_name);
+
+    *cs= system_charset_info;
+
+    return;
+  }
+
+  field->val_str(&str, &str);
+
+  if (str.is_empty())
+  {
+    push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                        ER_SR_NO_DEF_CONTEXT,
+                        ER(ER_SR_NO_DEF_CONTEXT),
+                        (const char *) name->m_db.str,
+                        (const char *) name->m_name.str,
+                        (const char *) field->field_name);
+
+    *cs= system_charset_info;
+
+    return;
+  }
+
+  *cs= get_charset_by_csname(str.c_ptr(), MY_CS_PRIMARY, MYF(0));
+
+  if (*cs)
+    return;
+
+  push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                      ER_SR_UNKNOWN_CHARSET,
+                      ER(ER_SR_UNKNOWN_CHARSET),
+                      (const char *) str.c_ptr(),
+                      (const char *) field->field_name,
+                      (const char *) name->m_db.str,
+                      (const char *) name->m_name.str);
+
+  *cs= system_charset_info;
+}
+
+
 /*
   Find routine definition in mysql.proc table and create corresponding
   sp_head object for it.
@@ -263,6 +322,11 @@ db_find_routine(THD *thd, int type, sp_n
   String str(buff, sizeof(buff), &my_charset_bin);
   ulong sql_mode;
   Open_tables_state open_tables_state_backup;
+
+  CHARSET_INFO *client_cs;
+  CHARSET_INFO *connection_cs;
+  CHARSET_INFO *server_cs;
+
   DBUG_ENTER("db_find_routine");
   DBUG_PRINT("enter", ("type: %d name: %.*s",
 		       type, name->m_name.length, name->m_name.str));
@@ -363,12 +427,25 @@ db_find_routine(THD *thd, int type, sp_n
   chistics.comment.str= ptr;
   chistics.comment.length= length;
 
+  db_retrieve_cs(thd, name,
+                 table->field[MYSQL_PROC_FIELD_CLIENT_CS],
+                 &client_cs);
+
+  db_retrieve_cs(thd, name,
+                 table->field[MYSQL_PROC_FIELD_CONNECTION_CS],
+                 &connection_cs);
+
+  db_retrieve_cs(thd, name,
+                 table->field[MYSQL_PROC_FIELD_SERVER_CS],
+                 &server_cs);
+
   close_proc_table(thd, &open_tables_state_backup);
   table= 0;
 
   ret= db_load_routine(thd, type, name, sphp,
                        sql_mode, params, returns, body, chistics,
-                       definer, created, modified);
+                       definer, created, modified,
+                       client_cs, connection_cs, server_cs);
                        
  done:
   if (table)
@@ -381,7 +458,10 @@ static int
 db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
                 ulong sql_mode, const char *params, const char *returns,
                 const char *body, st_sp_chistics &chistics,
-                const char *definer, longlong created, longlong modified)
+                const char *definer, longlong created, longlong modified,
+                CHARSET_INFO *client_cs,
+                CHARSET_INFO *connection_cs,
+                CHARSET_INFO *server_cs)
 {
   LEX *old_lex= thd->lex, newlex;
   String defstr;
@@ -412,7 +492,7 @@ db_load_routine(THD *thd, int type, sp_n
              definer_user_name.str, &definer_user_name.length,
              definer_host_name.str, &definer_host_name.length);
 
-  defstr.set_charset(system_charset_info);
+  defstr.set_charset(client_cs);
 
   /*
     We have to add DEFINER clause and provide proper routine characterstics in
@@ -438,7 +518,24 @@ db_load_routine(THD *thd, int type, sp_n
   lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
 
   thd->spcont= 0;
-  if (MYSQLparse(thd) || thd->is_fatal_error || newlex.sphead == NULL)
+
+  CHARSET_INFO *saved_client_cs= thd->variables.character_set_client;
+  CHARSET_INFO *saved_connection_cs= thd->variables.collation_connection;
+  CHARSET_INFO *saved_server_cs= thd->variables.collation_server;
+
+  thd->variables.character_set_client= client_cs;
+  thd->variables.collation_connection= connection_cs;
+  thd->variables.collation_server= server_cs;
+  thd->update_charset();
+
+  ret= MYSQLparse(thd);
+
+  thd->variables.character_set_client= saved_client_cs;
+  thd->variables.collation_connection= saved_connection_cs;
+  thd->variables.collation_server= saved_server_cs;
+  thd->update_charset();
+
+  if (ret || thd->is_fatal_error || newlex.sphead == NULL)
   {
     sp_head *sp= newlex.sphead;
 
@@ -454,6 +551,9 @@ db_load_routine(THD *thd, int type, sp_n
     *sphp= newlex.sphead;
     (*sphp)->set_definer(&definer_user_name, &definer_host_name);
     (*sphp)->set_info(created, modified, &chistics, sql_mode);
+    (*sphp)->m_defstr_ctx.client_cs= client_cs;
+    (*sphp)->m_defstr_ctx.connection_cs= connection_cs;
+    (*sphp)->m_defstr_ctx.server_cs= server_cs;
     (*sphp)->optimize();
   }
 end:
@@ -602,6 +702,24 @@ db_create_routine(THD *thd, int type, sp
       }
     }
 
+    table->field[MYSQL_PROC_FIELD_CLIENT_CS]->set_notnull();
+    table->field[MYSQL_PROC_FIELD_CLIENT_CS]->store(
+      thd->charset()->csname,
+      strlen(thd->charset()->csname),
+      system_charset_info);
+
+    table->field[MYSQL_PROC_FIELD_CONNECTION_CS]->set_notnull();
+    table->field[MYSQL_PROC_FIELD_CONNECTION_CS]->store(
+      thd->variables.collation_connection->csname,
+      strlen(thd->variables.collation_connection->csname),
+      system_charset_info);
+
+    table->field[MYSQL_PROC_FIELD_SERVER_CS]->set_notnull();
+    table->field[MYSQL_PROC_FIELD_SERVER_CS]->store(
+      thd->variables.collation_server->csname,
+      strlen(thd->variables.collation_server->csname),
+      system_charset_info);
+
     ret= SP_OK;
     if (table->file->write_row(table->record[0]))
       ret= SP_WRITE_ROW_FAILED;
@@ -723,15 +841,18 @@ struct st_used_field
 
 static struct st_used_field init_fields[]=
 {
-  { "Db",       NAME_LEN, MYSQL_TYPE_STRING,    0},
-  { "Name",     NAME_LEN, MYSQL_TYPE_STRING,    0},
-  { "Type",            9, MYSQL_TYPE_STRING,    0},
-  { "Definer",        77, MYSQL_TYPE_STRING,    0},
-  { "Modified",        0, MYSQL_TYPE_TIMESTAMP, 0},
-  { "Created",         0, MYSQL_TYPE_TIMESTAMP, 0},
-  { "Security_type",   1, MYSQL_TYPE_STRING,    0},
-  { "Comment",  NAME_LEN, MYSQL_TYPE_STRING,    0},
-  { 0,                 0, MYSQL_TYPE_STRING,    0}
+  { "Db",                    NAME_LEN, MYSQL_TYPE_STRING,    0},
+  { "Name",                  NAME_LEN, MYSQL_TYPE_STRING,    0},
+  { "Type",                         9, MYSQL_TYPE_STRING,    0},
+  { "Definer",                     77, MYSQL_TYPE_STRING,    0},
+  { "Modified",                     0, MYSQL_TYPE_TIMESTAMP, 0},
+  { "Created",                      0, MYSQL_TYPE_TIMESTAMP, 0},
+  { "Security_type",                1, MYSQL_TYPE_STRING,    0},
+  { "Comment",               NAME_LEN, MYSQL_TYPE_STRING,    0},
+  { "Client CS",      MY_CS_NAME_SIZE, MYSQL_TYPE_STRING,    0},
+  { "Connection CS",  MY_CS_NAME_SIZE, MYSQL_TYPE_STRING,    0},
+  { "Server CS",      MY_CS_NAME_SIZE, MYSQL_TYPE_STRING,    0},
+  { 0,                              0, MYSQL_TYPE_STRING,    0}
 };
 
 
@@ -1033,7 +1154,10 @@ sp_find_routine(THD *thd, int type, sp_n
     if (db_load_routine(thd, type, name, &new_sp,
                         sp->m_sql_mode, sp->m_params.str, returns,
                         sp->m_body.str, *sp->m_chistics, definer,
-                        sp->m_created, sp->m_modified) == SP_OK)
+                        sp->m_created, sp->m_modified,
+                        sp->m_defstr_ctx.client_cs,
+                        sp->m_defstr_ctx.connection_cs,
+                        sp->m_defstr_ctx.server_cs) == SP_OK)
     {
       sp->m_last_cached_sp->m_next_cached_sp= new_sp;
       new_sp->m_recursion_level= level;

--- 1.226/sql/sp_head.cc	2006-12-22 14:04:51 +03:00
+++ 1.227/sql/sp_head.cc	2006-12-22 14:04:51 +03:00
@@ -443,12 +443,20 @@ sp_head::operator delete(void *ptr, size
 
 sp_head::sp_head()
   :Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
-   m_flags(0), m_recursion_level(0), m_next_cached_sp(0),
-   m_first_instance(this), m_first_free_instance(this), m_last_cached_sp(this),
+   m_flags(0),
+   m_recursion_level(0),
+   m_next_cached_sp(0),
+   m_first_instance(this),
+   m_first_free_instance(this),
+   m_last_cached_sp(this),
    m_cont_level(0)
 {
   m_return_field_def.charset = NULL;
 
+  m_defstr_ctx.client_cs= system_charset_info;
+  m_defstr_ctx.connection_cs= system_charset_info;
+  m_defstr_ctx.server_cs= system_charset_info;
+
   extern byte *
     sp_table_key(const byte *ptr, uint *plen, my_bool first);
   DBUG_ENTER("sp_head::sp_head");
@@ -1322,6 +1330,9 @@ err_with_cleanup:
    - evaluate the return value
    - restores security context
 
+  NOTE: there is no need to switch query context (character sets) here,
+  because compiled code contains all necessary charset information.
+
   SYNOPSIS
     sp_head::execute_function()
       thd               Thread handle
@@ -1537,6 +1548,10 @@ err_with_cleanup:
    - copy back values of INOUT and OUT parameters
    - restores security context
 
+  NOTE: there is no need to switch query context (character sets) here,
+  because compiled code contains all necessary charset information.
+
+
   RETURN
     FALSE  on success
     TRUE   on error
@@ -2054,16 +2069,38 @@ sp_head::show_create_procedure(THD *thd)
   definition->maybe_null= TRUE;
   field_list.push_back(definition);
 
+  field_list.push_back(new Item_empty_string("Client CS",
+                                             MY_CS_NAME_SIZE));
+  field_list.push_back(new Item_empty_string("Connection CS",
+                                             MY_CS_NAME_SIZE));
+  field_list.push_back(new Item_empty_string("Server CS",
+                                             MY_CS_NAME_SIZE));
+
   if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
                                          Protocol::SEND_EOF))
     DBUG_RETURN(1);
+
   protocol->prepare_for_resend();
   protocol->store(m_name.str, m_name.length, system_charset_info);
   protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
+
   if (full_access)
-    protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
+    protocol->store(m_defstr.str, m_defstr.length, &my_charset_bin);
   else
     protocol->store_null();
+
+  protocol->store(m_defstr_ctx.client_cs->csname,
+                  strlen(m_defstr_ctx.client_cs->csname),
+                  system_charset_info);
+
+  protocol->store(m_defstr_ctx.connection_cs->csname,
+                  strlen(m_defstr_ctx.connection_cs->csname),
+                  system_charset_info);
+
+  protocol->store(m_defstr_ctx.server_cs->csname,
+                  strlen(m_defstr_ctx.server_cs->csname),
+                  system_charset_info);
+
   res= protocol->write();
   send_eof(thd);
 
@@ -2124,6 +2161,13 @@ sp_head::show_create_function(THD *thd)
   definition->maybe_null= TRUE;
   field_list.push_back(definition);
 
+  field_list.push_back(new Item_empty_string("Client CS",
+                                             MY_CS_NAME_SIZE));
+  field_list.push_back(new Item_empty_string("Connection CS",
+                                             MY_CS_NAME_SIZE));
+  field_list.push_back(new Item_empty_string("Server CS",
+                                             MY_CS_NAME_SIZE));
+
   if (protocol->send_fields(&field_list,
                             Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
     DBUG_RETURN(1);
@@ -2131,9 +2175,22 @@ sp_head::show_create_function(THD *thd)
   protocol->store(m_name.str, m_name.length, system_charset_info);
   protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
   if (full_access)
-    protocol->store(m_defstr.str, m_defstr.length, system_charset_info);
+    protocol->store(m_defstr.str, m_defstr.length, &my_charset_bin);
   else
     protocol->store_null();
+
+  protocol->store(m_defstr_ctx.client_cs->csname,
+                  strlen(m_defstr_ctx.client_cs->csname),
+                  system_charset_info);
+
+  protocol->store(m_defstr_ctx.connection_cs->csname,
+                  strlen(m_defstr_ctx.connection_cs->csname),
+                  system_charset_info);
+
+  protocol->store(m_defstr_ctx.server_cs->csname,
+                  strlen(m_defstr_ctx.server_cs->csname),
+                  system_charset_info);
+
   res= protocol->write();
   send_eof(thd);
 

--- 1.89/sql/sp_head.h	2006-12-22 14:04:51 +03:00
+++ 1.90/sql/sp_head.h	2006-12-22 14:04:51 +03:00
@@ -138,6 +138,9 @@ public:
   LEX_STRING m_defstr;
   LEX_STRING m_definer_user;
   LEX_STRING m_definer_host;
+
+  st_query_ctx m_defstr_ctx;
+
   longlong m_created;
   longlong m_modified;
   /* Recursion level of the current SP instance. The levels are numbered from 0 */

--- 1.117/mysql-test/r/mysqldump.result	2006-12-22 14:04:51 +03:00
+++ 1.118/mysql-test/r/mysqldump.result	2006-12-22 14:04:51 +03:00
@@ -1831,10 +1831,22 @@ DROP TABLE IF EXISTS `v2`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
 /*!50002 WITH CASCADED CHECK OPTION */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1910,9 +1922,21 @@ DROP TABLE IF EXISTS `v1`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v1` AS select `t1`.`a` AS `a` from `t1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1969,10 +1993,22 @@ DROP TABLE IF EXISTS `v2`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') */
 /*!50002 WITH CASCADED CHECK OPTION */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -2079,19 +2115,55 @@ DROP TABLE IF EXISTS `v3`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v1` AS select `v3`.`a` AS `a`,`v3`.`b` AS `b`,`v3`.`c` AS `c` from `v3` where (`v3`.`b` in (1,2,3,4,5,6,7)) */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v2` AS select `v3`.`a` AS `a` from (`v3` join `v1`) where ((`v1`.`a` = `v3`.`a`) and (`v3`.`b` = 3)) limit 1 */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!50001 DROP TABLE IF EXISTS `v3`*/;
 /*!50001 DROP VIEW IF EXISTS `v3`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v3` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -2134,21 +2206,21 @@ end if;
 end|
 set sql_mode=default|
 show triggers like "t1";
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 trg1	INSERT	t1	begin
 if new.a > 10 then
 set new.a := 10;
 set new.a := 11;
 end if;
-end	BEFORE	0000-00-00 00:00:00		root@localhost
+end	BEFORE	0000-00-00 00:00:00		root@localhost	latin1	latin1	latin1
 trg2	UPDATE	t1	begin
 if old.a % 2 = 0 then set new.b := 12; end if;
-end	BEFORE	0000-00-00 00:00:00		root@localhost
+end	BEFORE	0000-00-00 00:00:00		root@localhost	latin1	latin1	latin1
 trg3	UPDATE	t1	begin
 if new.a = -1 then
 set @fired:= "Yes";
 end if;
-end	AFTER	0000-00-00 00:00:00	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost
+end	AFTER	0000-00-00 00:00:00	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	latin1	latin1	latin1
 INSERT INTO t1 (a) VALUES (1),(2),(3),(22);
 update t1 set a = 4 where a=3;
 
@@ -2284,26 +2356,26 @@ Tables_in_test
 t1
 t2
 show triggers;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 trg1	INSERT	t1	begin
 if new.a > 10 then
 set new.a := 10;
 set new.a := 11;
 end if;
-end	BEFORE	#		root@localhost
+end	BEFORE	#		root@localhost	utf8	utf8	latin1
 trg2	UPDATE	t1	begin
 if old.a % 2 = 0 then set new.b := 12; end if;
-end	BEFORE	#		root@localhost
+end	BEFORE	#		root@localhost	utf8	utf8	latin1
 trg3	UPDATE	t1	begin
 if new.a = -1 then
 set @fired:= "Yes";
 end if;
-end	AFTER	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost
+end	AFTER	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	utf8	utf8	latin1
 trg4	INSERT	t2	begin
 if new.a > 10 then
 set @fired:= "No";
 end if;
-end	BEFORE	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost
+end	BEFORE	#	STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER	root@localhost	utf8	utf8	latin1
 DROP TABLE t1, t2;
 #
 # Bugs #9136, #12917: problems with --defaults-extra-file option
@@ -2332,9 +2404,9 @@ SELECT * FROM `test2`;
 a2
 1
 SHOW TRIGGERS;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 testref	INSERT	test1	BEGIN
-INSERT INTO test2 SET a2 = NEW.a1; END	BEFORE	NULL		root@localhost
+INSERT INTO test2 SET a2 = NEW.a1; END	BEFORE	NULL		root@localhost	utf8	utf8	latin1
 SELECT * FROM `test1`;
 a1
 1
@@ -2398,34 +2470,74 @@ UNLOCK TABLES;
 DELIMITER ;;
 /*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */;;
 /*!50003 SET SESSION SQL_MODE=""*/;;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
 RETURN a+b */;;
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;
 /*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;;
 /*!50003 SET SESSION SQL_MODE=""*/;;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1
 begin
 set f1= concat( 'hello', f1 );
 return f1;
 end */;;
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;
 /*!50003 DROP PROCEDURE IF EXISTS `a'b` */;;
 /*!50003 SET SESSION SQL_MODE="REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI"*/;;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50003 CREATE*/ /*!50020 DEFINER="root"@"localhost"*/ /*!50003 PROCEDURE "a'b"()
 select 1 */;;
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;
 /*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc1` */;;
 /*!50003 SET SESSION SQL_MODE=""*/;;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
 BEGIN SELECT a+b INTO c; end */;;
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;
 /*!50003 DROP PROCEDURE IF EXISTS `bug9056_proc2` */;;
 /*!50003 SET SESSION SQL_MODE=""*/;;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 PROCEDURE `bug9056_proc2`(OUT a INT)
 BEGIN 
 select sum(id) from t1 into a; 
 END */;;
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/ ;;
 DELIMITER ;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
@@ -2666,19 +2778,55 @@ DROP TABLE IF EXISTS `v2`;
 USE `test`;
 /*!50001 DROP TABLE IF EXISTS `v0`*/;
 /*!50001 DROP VIEW IF EXISTS `v0`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v0` AS select `v1`.`a` AS `a`,`v1`.`b` AS `b`,`v1`.`c` AS `c` from `v1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v2` AS select `v0`.`a` AS `a`,`v0`.`b` AS `b`,`v0`.`c` AS `c` from `v0` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -2867,12 +3015,12 @@ drop trigger tr1;
 drop trigger tr2;
 drop table t1, t2;
 show triggers;
-Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer	Client CS	Connection CS	Server CS
 tr1	INSERT	t1	set
-new.created=now()	BEFORE	#		root@localhost
+new.created=now()	BEFORE	#		root@localhost	utf8	utf8	latin1
 tr2	INSERT	t1	begin
 insert into t2 set b=new.a and created=new.created;
-end	AFTER	#		root@localhost
+end	AFTER	#		root@localhost	utf8	utf8	latin1
 drop trigger tr1;
 drop trigger tr2;
 drop table t1, t2;
@@ -2885,14 +3033,38 @@ insert into t values(5, 51);
 create view v1 as select qty, price, qty*price as value from t;
 create view v2 as select qty from v1;
 mysqldump {
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v1` AS select `t`.`qty` AS `qty`,`t`.`price` AS `price`,(`t`.`qty` * `t`.`price`) AS `value` from `t` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 
 } mysqldump {
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v2` AS select `v1`.`qty` AS `qty` from `v1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 
 } mysqldump
 drop view v1;
@@ -2907,13 +3079,13 @@ return 42 */|
 /*!50003 CREATE PROCEDURE `p`()
 select 42 */|
 show create function f;
-Function	sql_mode	Create Function
+Function	sql_mode	Create Function	Client CS	Connection CS	Server CS
 f		CREATE DEFINER=`root`@`localhost` FUNCTION `f`() RETURNS bigint(20)
-return 42
+return 42	latin1	latin1	latin1
 show create procedure p;
-Procedure	sql_mode	Create Procedure
+Procedure	sql_mode	Create Procedure	Client CS	Connection CS	Server CS
 p		CREATE DEFINER=`root`@`localhost` PROCEDURE `p`()
-select 42
+select 42	latin1	latin1	latin1
 drop function f;
 drop procedure p;
 #
@@ -2975,9 +3147,21 @@ DROP TABLE IF EXISTS `v1`;
 USE `mysqldump_test_db`;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `v1` AS select `t1`.`id` AS `id` from `t1` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -3020,9 +3204,21 @@ USE `mysqldump_views`;
 USE `mysqldump_tables`;
 
 USE `mysqldump_views`;
+SET @saved_cs_client = @@character_set_client;
+SET @saved_cs_results = @@character_set_results;
+SET @saved_cs_connection = @@character_set_connection;
+SET @saved_cs_server = @@character_set_server;
+SET character_set_client = latin1;
+SET character_set_results = latin1;
+SET character_set_connection = latin1;
+SET character_set_server = latin1;
 /*!50001 CREATE ALGORITHM=UNDEFINED */
 /*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
 /*!50001 VIEW `mysqldump_views`.`nasishnasifu` AS select `mysqldump_tables`.`basetable`.`id` AS `id` from `mysqldump_tables`.`basetable` */;
+SET character_set_server = @saved_cs_client;
+SET character_set_results = @saved_cs_results;
+SET character_set_connection = @saved_cs_connection;
+SET character_set_server = @saved_cs_server;
 drop view nasishnasifu;
 drop database mysqldump_views;
 drop table mysqldump_tables.basetable;
@@ -3217,6 +3413,66 @@ INSERT INTO t1 VALUES(1,0xff00fef0);
 </database>
 </mysqldump>
 DROP TABLE t1;
-#
-# End of 5.0 tests
-#
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+DROP TABLE IF EXISTS t1;
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+SET names utf8;
+CREATE TABLE t1(абв INT);
+INSERT INTO t1 VALUES(1);
+CREATE VIEW v1 AS SELECT 'абв', абв FROM t1;
+CREATE PROCEDURE p1() SELECT 'абв', абв FROM t1;
+CREATE FUNCTION f1() RETURNS CHAR(10) CHARSET utf8 RETURN 'абв';
+SHOW CREATE VIEW v1;
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'абв' AS `My_exp_абв`,`t1`.`абв` AS `абв` from `t1`	utf8	utf8	latin1
+SHOW CREATE PROCEDURE p1;
+Procedure	sql_mode	Create Procedure	Client CS	Connection CS	Server CS
+p1		CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SELECT 'абв', абв FROM t1	utf8	utf8	latin1
+SHOW CREATE FUNCTION f1;
+Function	sql_mode	Create Function	Client CS	Connection CS	Server CS
+f1		CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS char(10) CHARSET utf8
+RETURN 'абв'	utf8	utf8	latin1
+SELECT * FROM v1;
+My_exp_абв	абв
+абв	1
+CALL p1();
+абв	абв
+абв	1
+SELECT f1();
+f1()
+абв
+DROP VIEW v1;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+SHOW CREATE VIEW v1;
+View	Create View	Client CS	Connection CS	Server CS
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select _utf8'абв' AS `My_exp_абв`,`t1`.`абв` AS `абв` from `t1`	utf8	utf8	latin1
+SHOW CREATE PROCEDURE p1;
+Procedure	sql_mode	Create Procedure	Client CS	Connection CS	Server CS
+p1		CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
+SELECT 'абв', абв FROM t1	utf8	utf8	latin1
+SHOW CREATE FUNCTION f1;
+Function	sql_mode	Create Function	Client CS	Connection CS	Server CS
+f1		CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS char(10) CHARSET utf8
+RETURN 'абв'	utf8	utf8	latin1
+SELECT * FROM v1;
+My_exp_абв	абв
+абв	1
+CALL p1();
+абв	абв
+абв	1
+SELECT f1();
+f1()
+абв
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
+DROP VIEW v1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;

--- 1.106/mysql-test/t/mysqldump.test	2006-12-22 14:04:51 +03:00
+++ 1.107/mysql-test/t/mysqldump.test	2006-12-22 14:04:51 +03:00
@@ -1427,6 +1427,80 @@ INSERT INTO t1 VALUES(1,0xff00fef0);
 
 DROP TABLE t1;
 
---echo #
---echo # End of 5.0 tests
---echo #
+
+#
+# BUG#16291: mysqldump corrupts string-constants with non-ascii-chars
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1;
+DROP FUNCTION IF EXISTS f1;
+DROP VIEW IF EXISTS v1;
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+# Switch locale to UTF8, because the CREATE-VIEW-statetement is in UTF8.
+
+SET @old_cs_client = @@character_set_client;
+SET @old_cs_results = @@character_set_results;
+SET @old_cs_connection = @@character_set_connection;
+
+SET names utf8;
+
+# Create objects with non-latin1 symbols.
+
+CREATE TABLE t1(абв INT);
+INSERT INTO t1 VALUES(1);
+
+CREATE VIEW v1 AS SELECT 'абв', абв FROM t1;
+
+CREATE PROCEDURE p1() SELECT 'абв', абв FROM t1;
+
+CREATE FUNCTION f1() RETURNS CHAR(10) CHARSET utf8 RETURN 'абв';
+
+# Check what we have created.
+
+SHOW CREATE VIEW v1;
+SHOW CREATE PROCEDURE p1;
+SHOW CREATE FUNCTION f1;
+
+SELECT * FROM v1;
+
+CALL p1();
+
+SELECT f1();
+
+# Dump the view using the KOI8-R client character set.
+
+--exec $MYSQL_DUMP --character-sets-dir=$CHARSETSDIR --default-character-set=koi8r --routines test > $MYSQLTEST_VARDIR/tmp/bug16291.sql
+
+# Drop and re-create the view.
+
+DROP VIEW v1;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;
+
+--exec $MYSQL --character-sets-dir=$CHARSETSDIR test < $MYSQLTEST_VARDIR/tmp/bug16291.sql
+
+# Check again what we've got.
+
+SHOW CREATE VIEW v1;
+SHOW CREATE PROCEDURE p1;
+SHOW CREATE FUNCTION f1;
+
+SELECT * FROM v1;
+
+CALL p1();
+
+SELECT f1();
+
+# Clean up: reset locale and drop the view.
+
+SET character_set_client = @old_cs_client;
+SET character_set_results = @old_cs_results;
+SET character_set_connection = @old_cs_connection;
+
+DROP VIEW v1;
+DROP TABLE t1;
+DROP PROCEDURE p1;
+DROP FUNCTION f1;

--- 1.29/mysql-test/r/system_mysql_db.result	2006-12-22 14:04:51 +03:00
+++ 1.30/mysql-test/r/system_mysql_db.result	2006-12-22 14:04:51 +03:00
@@ -178,6 +178,9 @@ proc	CREATE TABLE `proc` (
   `modified` timestamp NOT NULL default '0000-00-00 00:00:00',
   `sql_mode` set('REAL_AS_FLOAT','PIPES_AS_CONCAT','ANSI_QUOTES','IGNORE_SPACE','NOT_USED','ONLY_FULL_GROUP_BY','NO_UNSIGNED_SUBTRACTION','NO_DIR_IN_CREATE','POSTGRESQL','ORACLE','MSSQL','DB2','MAXDB','NO_KEY_OPTIONS','NO_TABLE_OPTIONS','NO_FIELD_OPTIONS','MYSQL323','MYSQL40','ANSI','NO_AUTO_VALUE_ON_ZERO','NO_BACKSLASH_ESCAPES','STRICT_TRANS_TABLES','STRICT_ALL_TABLES','NO_ZERO_IN_DATE','NO_ZERO_DATE','INVALID_DATES','ERROR_FOR_DIVISION_BY_ZERO','TRADITIONAL','NO_AUTO_CREATE_USER','HIGH_NOT_PRECEDENCE') NOT NULL default '',
   `comment` char(64) character set utf8 collate utf8_bin NOT NULL default '',
+  `client_cs` char(32) default NULL,
+  `connection_cs` char(32) default NULL,
+  `server_cs` char(32) default NULL,
   PRIMARY KEY  (`db`,`name`,`type`)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT='Stored Procedures'
 show tables;

--- 1.28/scripts/mysql_create_system_tables.sh	2006-12-22 14:04:51 +03:00
+++ 1.29/scripts/mysql_create_system_tables.sh	2006-12-22 14:04:51 +03:00
@@ -720,6 +720,9 @@ then
   c_p="$c_p                         'HIGH_NOT_PRECEDENCE'"
   c_p="$c_p                     ) DEFAULT '' NOT NULL,"
   c_p="$c_p   comment           char(64) collate utf8_bin DEFAULT '' NOT NULL,"
+  c_p="$c_p   client_cs         char(32),"
+  c_p="$c_p   connection_cs     char(32),"
+  c_p="$c_p   server_cs         char(32),"
   c_p="$c_p   PRIMARY KEY (db,name,type)"
   c_p="$c_p ) engine=MyISAM"
   c_p="$c_p character set utf8"
Thread
bk commit into 5.0 tree (anozdrin:1.2321) BUG#11986Alexander Nozdrin22 Dec