=== modified file 'mysql-test/r/ctype_latin1.result'
--- a/mysql-test/r/ctype_latin1.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/ctype_latin1.result	2008-06-26 21:44:37 +0000
@@ -365,7 +365,7 @@
 ab_def
 drop table t1;
 CREATE TABLE „a (a int);
-ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?a (a int)' at line 1
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '„a (a int)' at line 1
 SELECT '„a' as str;
 str
 „a

=== modified file 'mysql-test/r/ctype_recoding.result'
--- a/mysql-test/r/ctype_recoding.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/ctype_recoding.result	2008-06-26 21:44:37 +0000
@@ -162,10 +162,10 @@
 DROP TABLE t1;
 SET NAMES binary;
 CREATE TABLE `goodÐÌÏÈÏ` (a int);
-ERROR HY000: Invalid utf8 character string: '?????'
+ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ'
 SET NAMES utf8;
 CREATE TABLE `goodÐÌÏÈÏ` (a int);
-ERROR HY000: Invalid utf8 character string: '?????` (a int)'
+ERROR HY000: Invalid utf8 character string: 'ÐÌÏÈÏ` (a int)'
 set names latin1;
 create table t1 (a char(10) character set koi8r, b text character set koi8r);
 insert into t1 values ('test','test');

=== modified file 'mysql-test/r/foreign_key_checks_basic.result'
--- a/mysql-test/r/foreign_key_checks_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/foreign_key_checks_basic.result	2008-06-26 21:44:37 +0000
@@ -52,7 +52,7 @@
 SET @@session.foreign_key_checks = ÓFF;
 ERROR 42000: Variable 'foreign_key_checks' can't be set to the value of 'Ã“FF'
 SET @@session.foreign_key_checks = '¹';
-ERROR 42000: Variable 'foreign_key_checks' can't be set to the value of '?'
+ERROR 42000: Variable 'foreign_key_checks' can't be set to the value of '¹'
 SET @@session.foreign_key_checks = NO;
 ERROR 42000: Variable 'foreign_key_checks' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_032_05----------------------------#'

=== modified file 'mysql-test/r/signal.result'
--- a/mysql-test/r/signal.result	2008-06-24 23:41:24 +0000
+++ b/mysql-test/r/signal.result	2008-06-26 21:44:37 +0000
@@ -1632,6 +1632,16 @@
 call test_signal() $$
 ERROR AABBB: User variable
 drop procedure test_signal $$
+create procedure test_invalid()
+begin
+DECLARE something CONDITION FOR SQLSTATE "AABBB";
+SIGNAL something SET
+MESSAGE_TEXT = @message_text := 'illegal',
+MYSQL_ERRNO = @sqlcode := 1234;
+end $$
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '
+MYSQL_ERRNO = @sqlcode := 1234;
+end' at line 5
 create procedure test_signal()
 begin
 DECLARE aaa VARCHAR(64);
@@ -1953,6 +1963,21 @@
 insert into t1 values (5), (6) $$
 ERROR 03XXX: This trigger SIGNAL an error, a=5
 drop table t1 $$
+create table t1 (errno integer, msg varchar(128)) $$
+create trigger t1_ai after insert on t1 for each row
+begin
+DECLARE warn CONDITION FOR SQLSTATE "01XXX";
+SIGNAL warn SET
+MESSAGE_TEXT = NEW.msg,
+MYSQL_ERRNO = NEW.errno;
+end $$
+insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$
+Warnings:
+Warning	1012	Warning message 1 in trigger
+insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$
+Warnings:
+Warning	1013	Warning message 2 in trigger
+drop table t1 $$
 drop table if exists t1 $$
 drop procedure if exists p1 $$
 drop function if exists f1 $$

=== modified file 'mysql-test/r/signal_utf32.result'
--- a/mysql-test/r/signal_utf32.result	2008-06-24 23:41:24 +0000
+++ b/mysql-test/r/signal_utf32.result	2008-06-26 21:44:37 +0000
@@ -30,5 +30,5 @@
 signal sqlstate '77777';
 end $$
 call test_signal() $$
-ERROR 77777: ÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒÃŒ
+ERROR 77777: ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ
 drop procedure test_signal $$

=== modified file 'mysql-test/r/sql_big_selects_basic.result'
--- a/mysql-test/r/sql_big_selects_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_big_selects_basic.result	2008-06-26 21:44:37 +0000
@@ -51,7 +51,7 @@
 SET @@session.sql_big_selects = ÓFF;
 ERROR 42000: Variable 'sql_big_selects' can't be set to the value of 'Ã“FF'
 SET @@session.sql_big_selects = '¹';
-ERROR 42000: Variable 'sql_big_selects' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_big_selects' can't be set to the value of '¹'
 SET @@session.sql_big_selects = NO;
 ERROR 42000: Variable 'sql_big_selects' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_153_05----------------------------#'

=== modified file 'mysql-test/r/sql_big_tables_basic.result'
--- a/mysql-test/r/sql_big_tables_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_big_tables_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_big_tables = ÓFF;
 ERROR 42000: Variable 'sql_big_tables' can't be set to the value of 'Ã“FF'
 SET @@session.sql_big_tables = '¹';
-ERROR 42000: Variable 'sql_big_tables' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_big_tables' can't be set to the value of '¹'
 SET @@session.sql_big_tables = NO;
 ERROR 42000: Variable 'sql_big_tables' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_154_05----------------------------#'

=== modified file 'mysql-test/r/sql_buffer_result_basic.result'
--- a/mysql-test/r/sql_buffer_result_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_buffer_result_basic.result	2008-06-26 21:44:37 +0000
@@ -64,7 +64,7 @@
 SET @@session.sql_buffer_result = ÓFF;
 ERROR 42000: Variable 'sql_buffer_result' can't be set to the value of 'Ã“FF'
 SET @@session.sql_buffer_result = '¹';
-ERROR 42000: Variable 'sql_buffer_result' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_buffer_result' can't be set to the value of '¹'
 SET @@session.sql_buffer_result = NO;
 ERROR 42000: Variable 'sql_buffer_result' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_155_05----------------------------#'

=== modified file 'mysql-test/r/sql_log_bin_basic.result'
--- a/mysql-test/r/sql_log_bin_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_log_bin_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_log_bin = ÓFF;
 ERROR 42000: Variable 'sql_log_bin' can't be set to the value of 'Ã“FF'
 SET @@session.sql_log_bin = '¹';
-ERROR 42000: Variable 'sql_log_bin' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_log_bin' can't be set to the value of '¹'
 SET @@session.sql_log_bin = NO;
 ERROR 42000: Variable 'sql_log_bin' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_156_05----------------------------#'

=== modified file 'mysql-test/r/sql_log_off_basic.result'
--- a/mysql-test/r/sql_log_off_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_log_off_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_log_off = ÓFF;
 ERROR 42000: Variable 'sql_log_off' can't be set to the value of 'Ã“FF'
 SET @@session.sql_log_off = '¹';
-ERROR 42000: Variable 'sql_log_off' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_log_off' can't be set to the value of '¹'
 SET @@session.sql_log_off = NO;
 ERROR 42000: Variable 'sql_log_off' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_157_05----------------------------#'

=== modified file 'mysql-test/r/sql_notes_basic.result'
--- a/mysql-test/r/sql_notes_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_notes_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_notes = ÓFF;
 ERROR 42000: Variable 'sql_notes' can't be set to the value of 'Ã“FF'
 SET @@session.sql_notes = '¹';
-ERROR 42000: Variable 'sql_notes' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_notes' can't be set to the value of '¹'
 SET @@session.sql_notes = NO;
 ERROR 42000: Variable 'sql_notes' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_161_05----------------------------#'

=== modified file 'mysql-test/r/sql_quote_show_create_basic.result'
--- a/mysql-test/r/sql_quote_show_create_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_quote_show_create_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_quote_show_create = ÓFF;
 ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of 'Ã“FF'
 SET @@session.sql_quote_show_create = '¹';
-ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of '¹'
 SET @@session.sql_quote_show_create = NO;
 ERROR 42000: Variable 'sql_quote_show_create' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_162_05----------------------------#'

=== modified file 'mysql-test/r/sql_safe_updates_basic.result'
--- a/mysql-test/r/sql_safe_updates_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_safe_updates_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_safe_updates = ÓFF;
 ERROR 42000: Variable 'sql_safe_updates' can't be set to the value of 'Ã“FF'
 SET @@session.sql_safe_updates = '¹';
-ERROR 42000: Variable 'sql_safe_updates' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_safe_updates' can't be set to the value of '¹'
 SET @@session.sql_safe_updates = NO;
 ERROR 42000: Variable 'sql_safe_updates' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_163_05----------------------------#'

=== modified file 'mysql-test/r/sql_warnings_basic.result'
--- a/mysql-test/r/sql_warnings_basic.result	2008-06-11 22:53:47 +0000
+++ b/mysql-test/r/sql_warnings_basic.result	2008-06-26 21:44:37 +0000
@@ -56,7 +56,7 @@
 SET @@session.sql_warnings = ÓFF;
 ERROR 42000: Variable 'sql_warnings' can't be set to the value of 'Ã“FF'
 SET @@session.sql_warnings = '¹';
-ERROR 42000: Variable 'sql_warnings' can't be set to the value of '?'
+ERROR 42000: Variable 'sql_warnings' can't be set to the value of '¹'
 SET @@session.sql_warnings = NO;
 ERROR 42000: Variable 'sql_warnings' can't be set to the value of 'NO'
 '#-------------------FN_DYNVARS_166_05----------------------------#'

=== modified file 'mysql-test/t/signal.test'
--- a/mysql-test/t/signal.test	2008-06-24 23:41:24 +0000
+++ b/mysql-test/t/signal.test	2008-06-26 21:44:37 +0000
@@ -1970,6 +1970,16 @@
 call test_signal() $$
 drop procedure test_signal $$
 
+--error ER_PARSE_ERROR
+create procedure test_invalid()
+begin
+  DECLARE something CONDITION FOR SQLSTATE "AABBB";
+
+  SIGNAL something SET
+    MESSAGE_TEXT = @message_text := 'illegal',
+    MYSQL_ERRNO = @sqlcode := 1234;
+end $$
+
 ## create procedure test_signal()
 ## begin
 ##   DECLARE something CONDITION FOR SQLSTATE "12345";
@@ -2381,6 +2391,22 @@
 
 drop table t1 $$
 
+create table t1 (errno integer, msg varchar(128)) $$
+
+create trigger t1_ai after insert on t1 for each row
+begin
+  DECLARE warn CONDITION FOR SQLSTATE "01XXX";
+
+  SIGNAL warn SET
+    MESSAGE_TEXT = NEW.msg,
+    MYSQL_ERRNO = NEW.errno;
+end $$
+
+insert into t1 set errno=1012, msg='Warning message 1 in trigger' $$
+insert into t1 set errno=1013, msg='Warning message 2 in trigger' $$
+
+drop table t1 $$
+
 --disable_warnings
 drop table if exists t1 $$
 drop procedure if exists p1 $$

=== modified file 'sql/derror.cc'
--- a/sql/derror.cc	2008-04-09 00:56:49 +0000
+++ b/sql/derror.cc	2008-06-26 21:44:37 +0000
@@ -121,7 +121,7 @@
   }
   
   /* TODO: Convert the character set to server system character set */
-  if (!get_charset(head[30],MYF(MY_WME)))
+  if (!(error_message_charset_info= get_charset(head[30],MYF(MY_WME))))
   {
     sql_print_error("Character set #%d is not supported for messagefile '%s'",
                     (int)head[30],name);

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-06-20 23:00:44 +0000
+++ b/sql/mysql_priv.h	2008-06-26 21:44:37 +0000
@@ -152,6 +152,10 @@
 extern CHARSET_INFO *system_charset_info, *files_charset_info ;
 extern CHARSET_INFO *national_charset_info, *table_alias_charset;
 
+/**
+  Character set of the buildin error messages loaded from errmsg.sys.
+*/
+extern CHARSET_INFO *error_message_charset_info;
 
 enum Derivation
 {

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-06-20 23:00:44 +0000
+++ b/sql/mysqld.cc	2008-06-26 21:44:37 +0000
@@ -651,6 +651,7 @@
 CHARSET_INFO *system_charset_info, *files_charset_info ;
 CHARSET_INFO *national_charset_info, *table_alias_charset;
 CHARSET_INFO *character_set_filesystem;
+CHARSET_INFO *error_message_charset_info= NULL;
 
 MY_LOCALE *my_default_lc_time_names;
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2008-06-24 18:25:54 +0000
+++ b/sql/sql_class.cc	2008-06-26 21:44:37 +0000
@@ -412,35 +412,6 @@
   m_status= DA_EMPTY;
 }
 
-void
-Diagnostics_area::set_utf8_message(const char* utf8_message)
-{
-  if (utf8_message)
-  {
-    uint convert_error= 0;
-    uint32 copy_len;
-
-    /*
-      Enforce that m_message is a valid UTF8 string,
-      and is properly terminated.
-      Note: any invalid character in utf8_message will be
-      converted to a '?' character.
-    */
-    copy_len= copy_and_convert(m_message,
-                               sizeof(m_message) - 1,
-                               & my_charset_utf8_bin,
-                               utf8_message,
-                               strlen(utf8_message),
-                               & my_charset_utf8_bin,
-                               & convert_error);
-    DBUG_ASSERT(copy_len < sizeof(m_message));
-    m_message[copy_len]= '\0';
-  }
-  else
-    m_message[0]= '\0';
-}
-
-
 /**
   Set OK status -- ends commands that do not return a
   result set, e.g. INSERT/UPDATE/DELETE.
@@ -466,7 +437,10 @@
   m_total_warn_count= thd->total_warn_count;
   m_affected_rows= affected_rows_arg;
   m_last_insert_id= last_insert_id_arg;
-  set_utf8_message(message_arg);
+  if (message_arg)
+    strmake(m_message, message_arg, sizeof(m_message) - 1);
+  else
+    m_message[0]= '\0';
   m_status= DA_OK;
 
   if (! m_stmt_area.is_read_only())
@@ -540,9 +514,9 @@
 #endif
 
   m_sql_errno= sql_errno_arg;
-  strncpy(m_sqlstate, sqlstate, 5);
-  m_sqlstate[5]= '\0';
-  set_utf8_message(message_arg);
+  strncpy(m_sqlstate, sqlstate, SQLSTATE_LENGTH);
+  m_sqlstate[SQLSTATE_LENGTH]= '\0';
+  strmake(m_message, message_arg, sizeof(m_message) - 1);
   m_status= DA_ERROR;
 }
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2008-06-20 23:00:44 +0000
+++ b/sql/sql_class.h	2008-06-26 21:44:37 +0000
@@ -1291,14 +1291,15 @@
   void set_printf(THD *thd, uint code, const char *str,
                   MYSQL_ERROR::enum_warning_level level, myf MyFlags, ...);
 
-  void set_utf8_message_text(const char* str);
-  void set_message_text(THD *thd, String *str);
+  /**
+    Set the condition message test.
+    @param str Message text, expressed in the character set derived from
+    the server --language option
+  */
+  void set_builtin_message_text(const char* str);
+
   const char* get_message_text() const;
-  const String* get_message_text_string() const
-  { return & m_message_text; }
 
-  /** The length in characters of m_message_text. */
-  int get_message_length() const;
   /** The length in bytes of m_message_text. */
   int get_message_octet_length() const;
 
@@ -1321,6 +1322,7 @@
   UTF8String64 m_cursor_name;
 
 private:
+  /** Message text, expressed in the character set implied by --language. */
   String m_message_text;
 
 public:
@@ -1538,8 +1540,6 @@
   Diagnostics_area() { reset_diagnostics_area(); }
 
 private:
-  void set_utf8_message(const char* utf8_message);
-
   /** Message buffer. Can be used by OK or ERROR status. */
   char m_message[MYSQL_ERRMSG_SIZE];
   /**

=== modified file 'sql/sql_signal.cc'
--- a/sql/sql_signal.cc	2008-06-20 23:00:44 +0000
+++ b/sql/sql_signal.cc	2008-06-26 21:44:37 +0000
@@ -181,8 +181,6 @@
    m_broken_caller(FALSE)
 {
   memset(m_returned_sqlstate, 0, sizeof(m_returned_sqlstate));
-
-  m_message_text.set_charset(& my_charset_utf8_bin);
 }
 
 SQL_condition *
@@ -207,7 +205,7 @@
 
     copy= strdup_root(mem_root, cond->m_message_text.ptr());
     m_message_text.set(copy, cond->m_message_text.length(),
-                       & my_charset_utf8_bin);
+                       error_message_charset_info);
   }
   else
     m_message_text.length(0);
@@ -279,7 +277,7 @@
   memcpy(m_returned_sqlstate, sqlstate, SQLSTATE_LENGTH);
   m_returned_sqlstate[SQLSTATE_LENGTH+1]= '\0';
 
-  set_utf8_message_text(str);
+  set_builtin_message_text(str);
   if ((level == MYSQL_ERROR::WARN_LEVEL_WARN) &&
       thd->really_abort_on_warning())
   {
@@ -296,35 +294,10 @@
 }
 
 void
-SQL_condition::set_utf8_message_text(const char* str)
-{
-  uint32 len= strlen(str);
-
-  m_message_text.length(0);
-  m_message_text.append(str, len, & my_charset_utf8_bin);
-}
-
-void
-SQL_condition::set_message_text(THD *thd, String *str)
-{
-  if (str)
-  {
-    m_message_text.length(0);
-    m_message_text.append(str->ptr(), str->length(), str->charset());
-
-    if (m_message_text.numchars() > 128)
-    {
-      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-                          ER_TRUNCATED_WRONG_VALUE,
-                          ER(ER_TRUNCATED_WRONG_VALUE),
-                          "VARCHAR(128)", str->c_ptr_safe());
-
-      uint32 end= m_message_text.charpos(128);
-      m_message_text.length(end);
-    }
-
-    (void) m_message_text.c_ptr_safe();
-  }
+SQL_condition::set_builtin_message_text(const char* str)
+{
+  m_message_text.set(str, strlen(str), error_message_charset_info);
+  (void) m_message_text.c_ptr_safe();
 }
 
 const char*
@@ -334,12 +307,6 @@
 }
 
 int
-SQL_condition::get_message_length() const
-{
-  return m_message_text.numchars();
-}
-
-int
 SQL_condition::get_message_octet_length() const
 {
   return m_message_text.length();
@@ -437,7 +404,7 @@
   if ((sqlstate[0] == '0') && (sqlstate[1] == '1'))
   {
     /* SQLSTATE class "01": warning */
-    cond->set_utf8_message_text(ER(ER_SIGNAL_WARN));
+    cond->set_builtin_message_text(ER(ER_SIGNAL_WARN));
     cond->m_level= MYSQL_ERROR::WARN_LEVEL_WARN;
     if (cond->m_sqlcode == 0)
       cond->m_sqlcode= ER_SIGNAL_WARN;
@@ -445,14 +412,14 @@
   else if ((sqlstate[0] == '0') && (sqlstate[1] == '2'))
   {
     /* SQLSTATE class "02": not found */
-    cond->set_utf8_message_text(ER(ER_SIGNAL_NOT_FOUND));
+    cond->set_builtin_message_text(ER(ER_SIGNAL_NOT_FOUND));
     cond->m_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
     if (cond->m_sqlcode == 0)
       cond->m_sqlcode= ER_SIGNAL_NOT_FOUND;
   }
   else
   {
-    cond->set_utf8_message_text(ER(ER_SIGNAL_EXCEPTION));
+    cond->set_builtin_message_text(ER(ER_SIGNAL_EXCEPTION));
     cond->m_level= MYSQL_ERROR::WARN_LEVEL_ERROR;
     if (cond->m_sqlcode == 0)
       cond->m_sqlcode= ER_SIGNAL_EXCEPTION;
@@ -614,8 +581,34 @@
       my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "MESSAGE_TEXT", "NULL");
       DBUG_RETURN(1);
     }
+    /*
+      Enforce that SET MESSAGE_TEXT = <value> evaluates the value
+      as VARCHAR(128) CHARACTER SET UTF8.
+    */
     str= set->val_str(& str_value);
-    cond->set_message_text(thd, str);
+    String utf8_text;
+    utf8_text.set_charset(& my_charset_utf8_bin);
+    utf8_text.append(str->ptr(), str->length(), str->charset());
+    if (utf8_text.numchars() > 128)
+    {
+      push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                          ER_TRUNCATED_WRONG_VALUE,
+                          ER(ER_TRUNCATED_WRONG_VALUE),
+                          "VARCHAR(128)", str->c_ptr_safe());
+
+      uint32 end= utf8_text.charpos(128);
+      utf8_text.length(end);
+    }
+
+    /*
+      Convert to the character set used with --language.
+      This code will be removed once WL#xxx is implemented.
+    */
+    String converted_text;
+    converted_text.set_charset(error_message_charset_info);
+    converted_text.append(utf8_text.ptr(), utf8_text.length(),
+                          utf8_text.charset());
+    cond->set_builtin_message_text(converted_text.c_ptr_safe());
   }
 
   set= m_set_signal_information.m_item[DIAG_MYSQL_ERRNO];
@@ -807,6 +800,8 @@
   int32 int_value;
   const String *str_value;
   Item *value= NULL;
+  String utf8_text;
+  const char* language_text;
 
   /* FIXME: this is prototype code, to be continued */
 
@@ -879,10 +874,13 @@
                                            str_value->charset());
     break;
   case DIAG_MESSAGE_TEXT:
-    str_value= cond->get_message_text_string();
-    value= new (thd->mem_root) Item_string("", str_value->ptr(),
-                                           str_value->length(),
-                                           str_value->charset());
+    language_text= cond->get_message_text();
+    utf8_text.set_charset(& my_charset_utf8_bin);
+    utf8_text.append(language_text, strlen(language_text),
+                     error_message_charset_info);
+    value= new (thd->mem_root) Item_string("", utf8_text.ptr(),
+                                           utf8_text.length(),
+                                           utf8_text.charset());
     break;
   case DIAG_MYSQL_ERRNO:
     int_value= cond->m_sqlcode;
@@ -905,7 +903,11 @@
                                            str_value->charset());
     break;
   case DIAG_MESSAGE_LENGTH:
-    int_value= cond->get_message_length();
+    language_text= cond->get_message_text();
+    utf8_text.set_charset(& my_charset_utf8_bin);
+    utf8_text.append(language_text, strlen(language_text),
+                     error_message_charset_info);
+    int_value= utf8_text.numchars();
     value= new (thd->mem_root) Item_int(int_value);
     break;
   case DIAG_MESSAGE_OCTET_LENGTH:

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2008-06-24 23:41:24 +0000
+++ b/sql/sql_yacc.yy	2008-06-26 21:44:37 +0000
@@ -2822,7 +2822,23 @@
           literal
           { $$= $1; }
         | variable
-          { $$= $1; }
+          {
+            if ($1->type() == Item::FUNC_ITEM)
+            {
+              Item_func *item= (Item_func*) $1;
+              if (item->functype() == Item_func::SUSERVAR_FUNC)
+              {
+                /*
+                  Don't allow the following syntax:
+                    SIGNAL/RESIGNAL ...
+                    SET <signal condition item name> = @foo := expr
+                */
+                my_parse_error(ER(ER_SYNTAX_ERROR));
+                MYSQL_YYABORT;
+              }
+            }
+            $$= $1;
+          }
         | simple_ident
           { $$= $1; }
         ;


