From 046f82e3a52e212cb50f3d32497030fe317d9b25 Mon Sep 17 00:00:00 2001
From: unknown <jimw@mysql.com>
Date: Wed, 23 Nov 2005 16:49:07 -0800
Subject: [PATCH 001/103] Fix possible corruption of results from
 SUBSTRING_INDEX(). (Bug #14676)

mysql-test/r/func_str.result:
  Add new results
mysql-test/t/func_str.test:
  Add new test
sql/item_strfunc.cc:
  Mark tmp_value in Item_func_substr_index as const so that we don't
  overwrite the contents of another String when getting the delimiter.
  Fix typo in variable names (delimeter -> delimiter).
---
 mysql-test/r/func_str.result |  7 +++++++
 mysql-test/t/func_str.test   |  8 ++++++++
 sql/item_strfunc.cc          | 38 +++++++++++++++++++++---------------
 3 files changed, 37 insertions(+), 16 deletions(-)

diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index a305bf20bff..911d6eea033 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1023,3 +1023,10 @@ select format(d, 2) from t1;
 format(d, 2)
 NULL
 drop table t1;
+create table t1 (c varchar(40));
+insert into t1 values ('y,abc'),('y,abc');
+select c, substring_index(lcase(c), @q:=',', -1) as res from t1;
+c	res
+y,abc	abc
+y,abc	abc
+drop table t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index ac2bf820257..ef20d766bce 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -676,4 +676,12 @@ insert into t1 values (null);
 select format(d, 2) from t1;
 drop table t1;
 
+#
+# Bug #14676: substring_index() returns incorrect results
+#
+create table t1 (c varchar(40));
+insert into t1 values ('y,abc'),('y,abc');
+select c, substring_index(lcase(c), @q:=',', -1) as res from t1;
+drop table t1;
+
 # End of 5.0 tests
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 1e8fe2e695f..9f17e978b39 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1094,9 +1094,9 @@ void Item_func_substr_index::fix_length_and_dec()
 String *Item_func_substr_index::val_str(String *str)
 {
   DBUG_ASSERT(fixed == 1);
-  String *res =args[0]->val_str(str);
-  String *delimeter =args[1]->val_str(&tmp_value);
-  int32 count = (int32) args[2]->val_int();
+  String *res= args[0]->val_str(str);
+  String *delimiter= args[1]->val_str(&tmp_value);
+  int32 count= (int32) args[2]->val_int();
   uint offset;
 
   if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
@@ -1105,8 +1105,8 @@ String *Item_func_substr_index::val_str(String *str)
     return 0;
   }
   null_value=0;
-  uint delimeter_length=delimeter->length();
-  if (!res->length() || !delimeter_length || !count)
+  uint delimiter_length= delimiter->length();
+  if (!res->length() || !delimiter_length || !count)
     return &my_empty_string;		// Wrong parameters
 
   res->set_charset(collation.collation);
@@ -1114,11 +1114,11 @@ String *Item_func_substr_index::val_str(String *str)
 #ifdef USE_MB
   if (use_mb(res->charset()))
   {
-    const char *ptr=res->ptr();
-    const char *strend = ptr+res->length();
-    const char *end=strend-delimeter_length+1;
-    const char *search=delimeter->ptr();
-    const char *search_end=search+delimeter_length;
+    const char *ptr= res->ptr();
+    const char *strend= ptr+res->length();
+    const char *end= strend-delimiter_length+1;
+    const char *search= delimiter->ptr();
+    const char *search_end= search+delimiter_length;
     int32 n=0,c=count,pass;
     register uint32 l;
     for (pass=(count>0);pass<2;++pass)
@@ -1133,7 +1133,7 @@ String *Item_func_substr_index::val_str(String *str)
 	    if (*i++ != *j++) goto skip;
 	  if (pass==0) ++n;
 	  else if (!--c) break;
-	  ptr+=delimeter_length;
+	  ptr+= delimiter_length;
 	  continue;
 	}
     skip:
@@ -1155,7 +1155,7 @@ String *Item_func_substr_index::val_str(String *str)
         }
         else /* return right part */
         {
-	  ptr+=delimeter_length;
+	  ptr+= delimiter_length;
 	  tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
         }
       }
@@ -1166,9 +1166,9 @@ String *Item_func_substr_index::val_str(String *str)
   {
     if (count > 0)
     {					// start counting from the beginning
-      for (offset=0 ;; offset+=delimeter_length)
+      for (offset=0; ; offset+= delimiter_length)
       {
-	if ((int) (offset=res->strstr(*delimeter,offset)) < 0)
+	if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
 	  return res;			// Didn't find, return org string
 	if (!--count)
 	{
@@ -1189,7 +1189,7 @@ String *Item_func_substr_index::val_str(String *str)
           address space less than where the found substring is located
           in res
         */
-	if ((int) (offset=res->strrstr(*delimeter,offset)) < 0)
+	if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
 	  return res;			// Didn't find, return org string
         /*
           At this point, we've searched for the substring
@@ -1197,13 +1197,19 @@ String *Item_func_substr_index::val_str(String *str)
         */
 	if (!++count)
 	{
-	  offset+=delimeter_length;
+	  offset+= delimiter_length;
 	  tmp_value.set(*res,offset,res->length()- offset);
 	  break;
 	}
       }
     }
   }
+  /*
+    We always mark tmp_value as const so that if val_str() is called again
+    on this object, we don't disrupt the contents of tmp_value when it was
+    derived from another String.
+  */
+  tmp_value.mark_as_const();
   return (&tmp_value);
 }
 

From ffebdee6426d8145b3aacd6274ca5e507103daab Mon Sep 17 00:00:00 2001
From: unknown <ramil@mysql.com>
Date: Tue, 24 Jan 2006 13:58:28 +0400
Subject: [PATCH 002/103] Fix for bug #15756: incorrect ip address matching in
 ACL due to use of latin1 collation. Thanks Deomid Ryabkov
 <mysqlbugs@rojer.pp.ru> for the great help!

sql/hostname.cc:
  Fix for bug #15756: incorrect ip address matching in ACL due to use of latin1 collation.
  - use my_charset_bin instead of my_charset_latin1 to properly compare IP addresses.
---
 sql/hostname.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/hostname.cc b/sql/hostname.cc
index 32e1d84fac3..32c4bb8533d 100644
--- a/sql/hostname.cc
+++ b/sql/hostname.cc
@@ -61,7 +61,7 @@ bool hostname_cache_init()
   if (!(hostname_cache=new hash_filo(HOST_CACHE_SIZE, offset,
 				     sizeof(struct in_addr),NULL,
 				     (hash_free_key) free,
-				     &my_charset_latin1)))
+				     &my_charset_bin)))
     return 1;
   hostname_cache->clear();
   (void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);

From 2caa5608c6c3f5eba5974a69b1d29b25d4eda280 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 9 Feb 2006 11:05:28 +0100
Subject: [PATCH 003/103] Bug#16878 dump of trigger  - Pass "in_comment"
 variable on to new lex in sp_head::reset_lex  - Add testcases for dumping and
 reloading trigger without BEGIN/END

mysql-test/r/mysqldump.result:
  Update test result
mysql-test/t/mysqldump.test:
  Add test for dumping trigger without begin/end, and test that the output from mysqldump can be reloaded.
sql/sp_head.cc:
  If already in a comment before parsing a substatement, set in_comment in the new lex as well.
  This will handle cases where the comment starts before the substatement, which is common in
  output from mysqldump to mask away syntax not supported by earlier versions of MySQL.
  Ex:
  /*!50003 CREATE TRIGGER `tr1` BEFORE INSERT ON `t1` FOR EACH ROW
  set new.created=now() */;
  ^=== sp_head::reset_lex is called when already in comment
---
 mysql-test/r/mysqldump.result | 22 ++++++++++++++++++++++
 mysql-test/t/mysqldump.test   | 30 ++++++++++++++++++++++++++++++
 sql/sp_head.cc                |  2 ++
 3 files changed, 54 insertions(+)

diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 717d9f67774..46056edcd5e 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2611,3 +2611,25 @@ UNLOCK TABLES;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
 drop table t1;
+create table t1 (a int, created datetime);
+create table t2 (b int, created datetime);
+create trigger tr1 before insert on t1 for each row set
+new.created=now();
+create trigger tr2 after insert on t1
+for each row
+begin
+insert into t2 set b=new.a and created=new.created;
+end|
+drop trigger tr1;
+drop trigger tr2;
+drop table t1, t2;
+show triggers;
+Trigger	Event	Table	Statement	Timing	Created	sql_mode	Definer
+tr1	INSERT	t1	set
+new.created=now()	BEFORE	#		root@localhost
+tr2	INSERT	t1	begin
+insert into t2 set b=new.a and created=new.created;
+end	AFTER	#		root@localhost
+drop trigger tr1;
+drop trigger tr2;
+drop table t1, t2;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index e54bf6386c5..caa1ae0d837 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1036,3 +1036,33 @@ insert into t1 values ('','');
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug #16878 dump of trigger
+#
+
+create table t1 (a int, created datetime);
+create table t2 (b int, created datetime);
+create trigger tr1 before insert on t1 for each row set
+new.created=now();
+delimiter |;
+create trigger tr2 after insert on t1
+for each row
+begin
+  insert into t2 set b=new.a and created=new.created;
+end|
+delimiter ;|
+
+# dump table and trigger
+--exec $MYSQL_DUMP test > var/tmp/bug16878.sql
+drop trigger tr1;
+drop trigger tr2;
+drop table t1, t2;
+
+# reload dump
+--exec $MYSQL test < var/tmp/bug16878.sql
+--replace_column 6 #
+show triggers;
+drop trigger tr1;
+drop trigger tr2;
+drop table t1, t2;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 96bf2c51b02..df993d304b1 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1584,6 +1584,8 @@ sp_head::reset_lex(THD *thd)
   sublex->trg_table_fields.empty();
   sublex->sp_lex_in_use= FALSE;
 
+  sublex->in_comment= oldlex->in_comment;
+
   /* Reset type info. */
 
   sublex->charset= NULL;

From 0fd784928c340968967a104dd0191837549ee8a3 Mon Sep 17 00:00:00 2001
From: unknown <pem@mysql.com>
Date: Thu, 9 Feb 2006 13:00:32 +0100
Subject: [PATCH 004/103] Fixed BUG#16896: Stored function: unused
 AGGREGATE-clause in CREATE FUNCTION   Check if AGGREGATE was given with a
 stored (non-UDF) function, and return   error in that case.   Also made
 udf_example/udf_test work again, by adding a missing *_init()   function.
 (_init() functions required unless --allow_suspicious_udfs is   given to the
 server, since March 2005 - it seems udf_example wasn't updated   at the
 time.)

mysql-test/r/sp-error.result:
  Updated results for BUG#16896.
mysql-test/t/sp-error.test:
  Added test case for BUG#16896.
sql/share/errmsg.txt:
  New error message: ER_SP_NO_AGGREGATE
sql/sql_yacc.yy:
  Check if AGGREGATE was used when creating a stored function (i.e. not an UDF).
sql/udf_example.cc:
  Added myfunc_int_init() function to make it work when the server is running without
  --allow_suspicious_udfs.
---
 mysql-test/r/sp-error.result |  3 +++
 mysql-test/t/sp-error.test   | 12 ++++++++++++
 sql/share/errmsg.txt         |  2 ++
 sql/sql_yacc.yy              | 10 ++++++++++
 sql/udf_example.cc           |  9 +++++++++
 5 files changed, 36 insertions(+)

diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index 2766dca5845..c0e02cbeb6f 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -1176,3 +1176,6 @@ end|
 call bug15091();
 ERROR 42S02: Unknown table 'c' in field list
 drop procedure bug15091;
+drop function if exists bug16896;
+create aggregate function bug16896() returns int return 1;
+ERROR 42000: AGGREGATE is not supported for stored functions
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index e1839b4b98f..c4745537de3 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -1703,6 +1703,17 @@ call bug15091();
 drop procedure bug15091;
 
 
+#
+# BUG#16896: Stored function: unused AGGREGATE-clause in CREATE FUNCTION
+#
+--disable_warnings
+drop function if exists bug16896;
+--enable_warnings
+
+--error ER_SP_NO_AGGREGATE
+create aggregate function bug16896() returns int return 1;
+
+
 #
 # BUG#NNNN: New bug synopsis
 #
@@ -1710,3 +1721,4 @@ drop procedure bug15091;
 #drop procedure if exists bugNNNN|
 #--enable_warnings
 #create procedure bugNNNN...
+
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 8017ba3ef9f..1315de6528a 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5607,3 +5607,5 @@ ER_SP_PROC_TABLE_CORRUPT
 	eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
 ER_SP_WRONG_NAME 42000
 	eng "Incorrect routine name '%-.64s'"
+ER_SP_NO_AGGREGATE 42000
+	eng "AGGREGATE is not supported for stored functions"
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index ebb97cde3e4..4f4ec5e92de 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1326,6 +1326,16 @@ create_function_tail:
 	    LEX *lex= Lex;
 	    sp_head *sp;
 
+            /* 
+              First check if AGGREGATE was used, in that case it's a
+              syntax error.
+            */
+            if (lex->udf.type == UDFTYPE_AGGREGATE)
+            {
+              my_error(ER_SP_NO_AGGREGATE, MYF(0));
+              YYABORT;
+            }
+
 	    if (lex->sphead)
 	    {
 	      my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
diff --git a/sql/udf_example.cc b/sql/udf_example.cc
index a186b4fbf6c..35833e63fab 100644
--- a/sql/udf_example.cc
+++ b/sql/udf_example.cc
@@ -144,6 +144,7 @@ char *metaphon(UDF_INIT *initid, UDF_ARGS *args, char *result,
 my_bool myfunc_double_init(UDF_INIT *, UDF_ARGS *args, char *message);
 double myfunc_double(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
 		     char *error);
+my_bool myfunc_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
 longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
 		    char *error);
 my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
@@ -597,6 +598,14 @@ longlong myfunc_int(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
   return val;
 }
 
+/*
+  At least one of _init/_deinit is needed unless the server is started
+  with --allow_suspicious_udfs.
+*/
+my_bool myfunc_int_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
+{
+  return 0;
+}
 
 /*
   Simple example of how to get a sequences starting from the first argument

From 4b0cce48737bf90eb33e389706df824cc00d7e5c Mon Sep 17 00:00:00 2001
From: unknown <sergefp@mysql.com>
Date: Sat, 11 Feb 2006 21:51:43 +0300
Subject: [PATCH 005/103] BUG#17314: Can't use index_merge/intersection for
 MERGE tables 1. Fix index access costs for MERGE tables, set
 block_size=myisam_block_size/#underlying_tables    instead of 0 which it was
 before. 2. Make index scans on MERGE table to return records in (key_tuple,
 merge_table_rowid) order,    instead of just (key_tuple) order. This makes an
 index scan on MERGE table to be truly a ROR-scan    which is a requirement
 for index_merge union/intersection.

myisammrg/myrg_queue.c:
  BUG#17314: Make index scans on MERGE table return records ordered by (keytuple, merge_table_rowid).
mysql-test/r/index_merge.result:
  Testcase for BUG#17314
mysql-test/r/merge.result:
  BUG#17314: update testcase result
mysql-test/t/index_merge.test:
  Testcase for BUG#17314
sql/ha_myisammrg.cc:
  BUG#17314: For MERGE tables, set handler::block_size to myisam_block_size/#underlying_tables, and not to 0.
---
 myisammrg/myrg_queue.c          | 20 +++++++++++++++++---
 mysql-test/r/index_merge.result | 22 ++++++++++++++++++++++
 mysql-test/r/merge.result       |  2 +-
 mysql-test/t/index_merge.test   | 26 ++++++++++++++++++++++++++
 sql/ha_myisammrg.cc             | 22 +++++++++++++++++++++-
 5 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/myisammrg/myrg_queue.c b/myisammrg/myrg_queue.c
index 7172b9f0e2a..2e600a526c0 100644
--- a/myisammrg/myrg_queue.c
+++ b/myisammrg/myrg_queue.c
@@ -18,12 +18,26 @@
 
 static int queue_key_cmp(void *keyseg, byte *a, byte *b)
 {
-  MI_INFO *aa=((MYRG_TABLE *)a)->table;
-  MI_INFO *bb=((MYRG_TABLE *)b)->table;
+  MYRG_TABLE *ma= (MYRG_TABLE *)a;
+  MYRG_TABLE *mb= (MYRG_TABLE *)b;
+  MI_INFO *aa= ma->table;
+  MI_INFO *bb= mb->table;
   uint not_used[2];
   int ret= ha_key_cmp((HA_KEYSEG *)keyseg, aa->lastkey, bb->lastkey,
 		       USE_WHOLE_KEY, SEARCH_FIND, not_used);
-  return ret < 0 ? -1 : ret > 0 ? 1 : 0;
+  if (ret < 0)
+    return -1;
+  if (ret > 0)
+    return 1;
+ 
+  /*
+    If index tuples have the same values, let the record with least rowid
+    value be "smaller", so index scans return records ordered by (keytuple,
+    rowid). This is used by index_merge access method, grep for ROR in
+    sql/opt_range.cc for details.
+  */
+  return (ma->file_offset < mb->file_offset)? -1 : (ma->file_offset > 
+                                                    mb->file_offset) ? 1 : 0;
 } /* queue_key_cmp */
 
 
diff --git a/mysql-test/r/index_merge.result b/mysql-test/r/index_merge.result
index db87253e19a..3a69f56cbd3 100644
--- a/mysql-test/r/index_merge.result
+++ b/mysql-test/r/index_merge.result
@@ -402,3 +402,25 @@ explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'b
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	SIMPLE	t1	index_merge	cola,colb	cola,colb	3,3	NULL	24	Using intersect(cola,colb); Using where
 drop table t1;
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+a int, b int, 
+filler1 char(200), filler2 char(200),
+key(a),key(b)
+);
+insert into t1 select @v:= A.a, @v, 't1', 'filler2' from t0 A, t0 B, t0 C;
+create table t2 like t1;
+create table t3 (
+a int, b int, 
+filler1 char(200), filler2 char(200),
+key(a),key(b)
+) engine=merge union=(t1,t2);
+explain select * from t1 where a=1 and b=1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t1	index_merge	a,b	a,b	5,5	NULL	#	Using intersect(a,b); Using where
+explain select * from t3 where a=1 and b=1;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t3	index_merge	a,b	a,b	5,5	NULL	#	Using intersect(a,b); Using where
+drop table t3;
+drop table t0, t1, t2;
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 7e3ccc83d73..58e1f86b3f9 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -56,8 +56,8 @@ a	b
 4	Testing
 5	table
 5	table
-6	t1
 6	t2
+6	t1
 7	Testing
 7	Testing
 8	table
diff --git a/mysql-test/t/index_merge.test b/mysql-test/t/index_merge.test
index 10512902409..3da5711bf7a 100644
--- a/mysql-test/t/index_merge.test
+++ b/mysql-test/t/index_merge.test
@@ -357,3 +357,29 @@ explain select * from t1 WHERE cola = 'foo' AND colb = 'bar';
 explain select * from t1 force index(cola,colb) WHERE cola = 'foo' AND colb = 'bar';
 drop table t1;
 
+#
+# BUG#17314: Index_merge/intersection not choosen by the optimizer for MERGE tables
+#
+create table t0 (a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+  a int, b int, 
+  filler1 char(200), filler2 char(200),
+  key(a),key(b)
+);
+insert into t1 select @v:= A.a, @v, 't1', 'filler2' from t0 A, t0 B, t0 C;
+create table t2 like t1;
+
+create table t3 (
+  a int, b int, 
+  filler1 char(200), filler2 char(200),
+  key(a),key(b)
+) engine=merge union=(t1,t2);
+
+--replace_column 9 #
+explain select * from t1 where a=1 and b=1;
+--replace_column 9 #
+explain select * from t3 where a=1 and b=1;
+
+drop table t3;
+drop table t0, t1, t2;
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index da4136def68..9780f163634 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -288,7 +288,27 @@ void ha_myisammrg::info(uint flag)
   table->s->db_options_in_use= info.options;
   table->s->is_view= 1;
   mean_rec_length= info.reclength;
-  block_size=0;
+  
+  /* 
+    The handler::block_size is used all over the code in index scan cost
+    calculations. It is used to get number of disk seeks required to
+    retrieve a number of index tuples.
+    If the merge table has N underlying tables, then (assuming underlying
+    tables have equal size, the only "simple" approach we can use)
+    retrieving X index records from a merge table will require N times more
+    disk seeks compared to doing the same on a MyISAM table with equal
+    number of records.
+    In the edge case (file_tables > myisam_block_size) we'll get
+    block_size==0, and index calculation code will act as if we need one
+    disk seek to retrieve one index tuple.
+
+    TODO: In 5.2 index scan cost calculation will be factored out into a
+    virtual function in class handler and we'll be able to remove this hack.
+  */
+  block_size= 0;
+  if (file->tables)
+    block_size= myisam_block_size / file->tables;
+  
   update_time=0;
 #if SIZEOF_OFF_T > 4
   ref_length=6;					// Should be big enough

From b39626f9e4fa3a45d06b9f1146eb9763a21aad3d Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 13 Feb 2006 14:02:39 +0100
Subject: [PATCH 006/103] Bug#16557 mysql cmd-line client does not rename
 .mysql_history.TMP to .mysql_history  - Return error only if 'history'
 returns -1

cmd-line-utils/libedit/readline.c:
  Return 1 to indicate error only if 'history' returned -1, since the history function normally will return the number of entries written or read. Only -1 indicates error.
---
 cmd-line-utils/libedit/readline.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c
index 616b55a877e..8c09a6f39d5 100644
--- a/cmd-line-utils/libedit/readline.c
+++ b/cmd-line-utils/libedit/readline.c
@@ -1109,7 +1109,7 @@ read_history(const char *filename)
 
 	if (h == NULL || e == NULL)
 		rl_initialize();
-	return (history(h, &ev, H_LOAD, filename));
+	return (history(h, &ev, H_LOAD, filename) == -1);
 }
 
 
@@ -1123,7 +1123,7 @@ write_history(const char *filename)
 
 	if (h == NULL || e == NULL)
 		rl_initialize();
-	return (history(h, &ev, H_SAVE, filename));
+	return (history(h, &ev, H_SAVE, filename) == -1);
 }
 
 

From 559abcf5d973213727e2dda42ee1577b4914564e Mon Sep 17 00:00:00 2001
From: unknown <SergeyV@selena.>
Date: Mon, 13 Feb 2006 19:53:34 +0300
Subject: [PATCH 007/103] Fixes bug #15943. resets error flag for show create
 view command, to allow proper processing of multiple sql statements sent as a
 single command.

mysql-test/r/view.result:
  result file update for #15943 test case
mysql-test/t/view.test:
  test case added for bug #15943
---
 mysql-test/r/view.result | 10 ++++++++++
 mysql-test/t/view.test   | 15 +++++++++++++++
 sql/sql_show.cc          |  7 +++++++
 3 files changed, 32 insertions(+)

diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index e209e393d00..6b96bf7ca17 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2538,3 +2538,13 @@ Warnings:
 Warning	1052	Column 'x' in group statement is ambiguous
 DROP VIEW v1;
 DROP TABLE t1;
+drop table if exists t1; 
+drop view if exists v1; 
+create table t1 (id int); 
+create view v1 as select * from t1; 
+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 sql_no_cache `test`.`t1`.`id` AS `id` from `t1`
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index ed44bf3b7c0..dcd2b4de8dc 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2380,3 +2380,18 @@ SELECT IF(x IS NULL, 'blank', 'not blank') AS x FROM v1 GROUP BY x;
 
 DROP VIEW v1;
 DROP TABLE t1;
+
+#
+# BUG#15943: mysql_next_result hangs on invalid SHOW CREATE VIEW
+#
+
+delimiter //;
+drop table if exists t1; 
+drop view if exists v1; 
+create table t1 (id int); 
+create view v1 as select * from t1; 
+drop table t1; 
+show create view v1; 
+drop view v1;
+//
+delimiter ;//
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 1b854a005ce..37a922cf103 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -365,6 +365,13 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
   {
     if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
       DBUG_RETURN(TRUE);
+
+    /* 
+       Need this for proper processing of multiple sql statements        
+       sent as single command     
+    */    
+    thd->net.report_error= 0;
+
     /*
       Clear all messages with 'error' level status and
       issue a warning with 'warning' level status in 

From 8a4ebb52325702b2e781e11f730e1df78bceaef9 Mon Sep 17 00:00:00 2001
From: unknown <petr@mysql.com>
Date: Tue, 14 Feb 2006 03:09:17 +0300
Subject: [PATCH 008/103] fix Bug#12813 "Instance Manager: START/STOP INSTANCE 
               commands accept a list as argument"

mysql-test/r/im_life_cycle.result:
  update result file
mysql-test/t/im_life_cycle.imtest:
  add a test for the bug
server-tools/instance-manager/parse.cc:
  check for nonaplhanumeric symbols at the end of the commands
---
 mysql-test/r/im_life_cycle.result      |  4 ++++
 mysql-test/t/im_life_cycle.imtest      | 15 +++++++++++++++
 server-tools/instance-manager/parse.cc | 17 ++++++++++-------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/mysql-test/r/im_life_cycle.result b/mysql-test/r/im_life_cycle.result
index 5df874ba452..36277f6aa28 100644
--- a/mysql-test/r/im_life_cycle.result
+++ b/mysql-test/r/im_life_cycle.result
@@ -64,3 +64,7 @@ mysqld1	online
 mysqld2	offline
 SHOW INSTANCE STATUS;
 ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
+START INSTANCE mysqld1,mysqld2,mysqld3;
+ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
+STOP INSTANCE mysqld1,mysqld2,mysqld3;
+ERROR 42000: You have an error in your command syntax. Check the manual that corresponds to your MySQL Instance Manager version for the right syntax to use
diff --git a/mysql-test/t/im_life_cycle.imtest b/mysql-test/t/im_life_cycle.imtest
index 20b4b0be17c..445ae7f72fa 100644
--- a/mysql-test/t/im_life_cycle.imtest
+++ b/mysql-test/t/im_life_cycle.imtest
@@ -149,3 +149,18 @@ SHOW INSTANCES;
 ###########################################################################
 --error 1149
 SHOW INSTANCE STATUS;
+
+#
+# Tests for bug fixes
+#
+
+#
+# Bug #12813    Instance Manager: START/STOP INSTANCE commands accept
+#                                 a list as argument.
+#
+
+--error 1149
+START INSTANCE mysqld1,mysqld2,mysqld3;
+
+--error 1149
+STOP INSTANCE mysqld1,mysqld2,mysqld3;
diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
index 9d9064240d4..4a8e85faf8f 100644
--- a/server-tools/instance-manager/parse.cc
+++ b/server-tools/instance-manager/parse.cc
@@ -143,7 +143,7 @@ Command *parse_command(Instance_map *map, const char *text)
     instance_name_len= word_len;
     text+= word_len;
     /* it should be the end of command */
-    get_word(&text, &word_len);
+    get_word(&text, &word_len, NONSPACE);
     if (word_len)
       goto syntax_error;
 
@@ -156,7 +156,7 @@ Command *parse_command(Instance_map *map, const char *text)
     if (shift_token(&text, &word_len) != TOK_INSTANCES)
       goto syntax_error;
 
-    get_word(&text, &word_len);
+    get_word(&text, &word_len, NONSPACE);
     if (word_len)
       goto syntax_error;
 
@@ -197,7 +197,7 @@ Command *parse_command(Instance_map *map, const char *text)
     }
 
     /* should be empty */
-    get_word(&text, &word_len);
+    get_word(&text, &word_len, NONSPACE);
     if (word_len)
       goto syntax_error;
 
@@ -213,7 +213,7 @@ Command *parse_command(Instance_map *map, const char *text)
   case TOK_SHOW:
     switch (shift_token(&text, &word_len)) {
     case TOK_INSTANCES:
-      get_word(&text, &word_len);
+      get_word(&text, &word_len, NONSPACE);
       if (word_len)
         goto syntax_error;
       command= new Show_instances(map);
@@ -226,7 +226,7 @@ Command *parse_command(Instance_map *map, const char *text)
           goto syntax_error;
         text+= instance_name_len;
         /* check that this is the end of the command */
-        get_word(&text, &word_len);
+        get_word(&text, &word_len, NONSPACE);
         if (word_len)
           goto syntax_error;
         if (tok2 == TOK_STATUS)
@@ -250,7 +250,7 @@ Command *parse_command(Instance_map *map, const char *text)
         case TOK_LOG:
           switch (Token tok3= shift_token(&text, &word_len)) {
           case TOK_FILES:
-            get_word(&text, &word_len);
+            get_word(&text, &word_len, NONSPACE);
             /* check that this is the end of the command */
             if (word_len)
               goto syntax_error;
@@ -293,7 +293,10 @@ Command *parse_command(Instance_map *map, const char *text)
                 command= new Show_instance_log(map, instance_name,
                                                instance_name_len, log_type,
                                                log_size, text);
-
+                get_word(&text, &word_len, NONSPACE);
+                /* check that this is the end of the command */
+                if (word_len)
+                  goto syntax_error;
                 break;
               case '\0':
                 command= new Show_instance_log(map, instance_name,

From d0fb23385d7764e00ec71fb3bc132ff24611f4fb Mon Sep 17 00:00:00 2001
From: unknown <igor@rurik.mysql.com>
Date: Mon, 13 Feb 2006 18:50:06 -0800
Subject: [PATCH 009/103] Fixed bug #16603. A subquery transformation changes
 the HAVING clause of the embedding query if the subquery contains a GROUP BY
 clause. Yet the split_sum_func2 function was not applied to the modified
 HAVING clause. This could result in wrong answers.

mysql-test/r/subselect.result:
  Added a test case for bug #16603.
mysql-test/t/subselect.test:
  Added a test case for bug #16603.
---
 mysql-test/r/subselect.result | 32 +++++++++++++++++++++++++++++---
 mysql-test/t/subselect.test   | 22 ++++++++++++++++++++++
 sql/sql_select.cc             | 29 +++++++++++++++--------------
 3 files changed, 66 insertions(+), 17 deletions(-)

diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 85976c211c5..33b12c05f98 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -215,9 +215,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
 a
 select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
 b	(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
-8	7.5
-8	4.5
-9	7.5
+8	7.5000
+8	4.5000
+9	7.5000
 explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t4	ALL	NULL	NULL	NULL	NULL	3	
@@ -3131,3 +3131,29 @@ a	sum
 3	20
 4	40
 DROP TABLE t1,t2,t3;
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a	b
+BBB	4
+CCC	7
+AAA	8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	9	Using where
+2	DEPENDENT SUBQUERY	t1	ALL	NULL	NULL	NULL	NULL	9	Using temporary; Using filesort
+ALTER TABLE t1 ADD INDEX(a);
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+a	b
+BBB	4
+CCC	7
+AAA	8
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t1	ALL	NULL	NULL	NULL	NULL	9	Using where
+2	DEPENDENT SUBQUERY	t1	index	NULL	a	8	NULL	9	Using filesort
+DROP TABLE t1;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 762ff36ba63..9e09b215951 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -2051,3 +2051,25 @@ SELECT t1.a, SUM(b) AS sum  FROM t1 GROUP BY t1.a
                     HAVING t2.c+sum > 20);
 
 DROP TABLE t1,t2,t3;
+
+#
+# Test for bug #16603: GROUP BY in a row subquery with a quantifier 
+#                      when an index is defined on the grouping field
+
+CREATE TABLE t1 (a varchar(5), b varchar(10));
+INSERT INTO t1 VALUES
+  ('AAA', 5), ('BBB', 4), ('BBB', 1), ('CCC', 2),
+  ('CCC', 7), ('AAA', 2), ('AAA', 4), ('BBB', 3), ('AAA', 8);
+
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+
+ALTER TABLE t1 ADD INDEX(a);
+
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+EXPLAIN
+SELECT * FROM t1 WHERE (a,b) = ANY (SELECT a, max(b) FROM t1 GROUP BY a);
+
+DROP TABLE t1;
+
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9160c023576..777814adc5f 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -364,22 +364,8 @@ JOIN::prepare(Item ***rref_pointer_array,
     select_lex->having_fix_field= 0;
     if (having_fix_rc || thd->net.report_error)
       DBUG_RETURN(-1);				/* purecov: inspected */
-    if (having->with_sum_func)
-      having->split_sum_func2(thd, ref_pointer_array, all_fields,
-                              &having, TRUE);
     thd->lex->allow_sum_func= save_allow_sum_func;
   }
-  if (select_lex->inner_sum_func_list)
-  {
-    Item_sum *end=select_lex->inner_sum_func_list;
-    Item_sum *item_sum= end;  
-    do
-    { 
-      item_sum= item_sum->next;
-      item_sum->split_sum_func2(thd, ref_pointer_array,
-                                all_fields, item_sum->ref_by, FALSE);
-    } while (item_sum != end);
-  }
 
   if (!thd->lex->view_prepare_mode)
   {
@@ -397,6 +383,21 @@ JOIN::prepare(Item ***rref_pointer_array,
     }
   }
 
+  if (having && having->with_sum_func)
+    having->split_sum_func2(thd, ref_pointer_array, all_fields,
+                            &having, TRUE);
+  if (select_lex->inner_sum_func_list)
+  {
+    Item_sum *end=select_lex->inner_sum_func_list;
+    Item_sum *item_sum= end;  
+    do
+    { 
+      item_sum= item_sum->next;
+      item_sum->split_sum_func2(thd, ref_pointer_array,
+                                all_fields, item_sum->ref_by, FALSE);
+    } while (item_sum != end);
+  }
+
   if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
     DBUG_RETURN(-1);
   

From 4628da295f421042f9aa3b24e307f5d20133528b Mon Sep 17 00:00:00 2001
From: unknown <pem@mysql.com>
Date: Wed, 15 Feb 2006 17:28:34 +0100
Subject: [PATCH 010/103] Additional tests for nested handlers added to
 sp.test. A follow-up to BUG#15011 (already fixed).

mysql-test/r/sp.result:
  Updated results for new handler tests.
mysql-test/t/sp.test:
  Additional tests for nested handlers.
---
 mysql-test/r/sp.result | 335 ++++++++++++++++++++++++++++++++++-
 mysql-test/t/sp.test   | 393 ++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 725 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index bec2f049bc4..61c977f1a5c 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -1413,8 +1413,6 @@ select `foo` ()|
 5
 drop function `foo`|
 drop function if exists t1max|
-Warnings:
-Note	1305	FUNCTION t1max does not exist
 create function t1max() returns int
 begin
 declare x int;
@@ -1470,6 +1468,339 @@ zip	3
 foo	1
 drop table t3|
 drop function getcount|
+drop table if exists t3|
+drop procedure if exists h_ee|
+drop procedure if exists h_es|
+drop procedure if exists h_en|
+drop procedure if exists h_ew|
+drop procedure if exists h_ex|
+drop procedure if exists h_se|
+drop procedure if exists h_ss|
+drop procedure if exists h_sn|
+drop procedure if exists h_sw|
+drop procedure if exists h_sx|
+drop procedure if exists h_ne|
+drop procedure if exists h_ns|
+drop procedure if exists h_nn|
+drop procedure if exists h_we|
+drop procedure if exists h_ws|
+drop procedure if exists h_ww|
+drop procedure if exists h_xe|
+drop procedure if exists h_xs|
+drop procedure if exists h_xx|
+create table t3 (a smallint primary key)|
+insert into t3 (a) values (1)|
+create procedure h_ee()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (bad)' as 'h_ee';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_ee';
+insert into t3 values (1);
+end;
+end|
+create procedure h_es()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (good)' as 'h_es';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000'
+      select 'Inner (bad)' as 'h_es';
+insert into t3 values (1);
+end;
+end|
+create procedure h_en()
+deterministic
+begin
+declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+select 'Outer (good)' as 'h_en';
+begin
+declare x int;
+declare continue handler for sqlstate '02000' -- no data
+select 'Inner (bad)' as 'h_en';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_ew()
+deterministic
+begin
+declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+select 'Outer (good)' as 'h_ew';
+begin
+declare continue handler for sqlwarning
+select 'Inner (bad)' as 'h_ew';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ex()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (good)' as 'h_ex';
+begin
+declare continue handler for sqlexception
+select 'Inner (bad)' as 'h_ex';
+insert into t3 values (1);
+end;
+end|
+create procedure h_se()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (bad)' as 'h_se';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_se';
+insert into t3 values (1);
+end;
+end|
+create procedure h_ss()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (bad)' as 'h_ss';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Inner (good)' as 'h_ss';
+insert into t3 values (1);
+end;
+end|
+create procedure h_sn()
+deterministic
+begin
+-- Note: '02000' is more specific than NOT FOUND ;
+--       there might be other not found states 
+declare continue handler for sqlstate '02000' -- no data
+select 'Outer (good)' as 'h_sn';
+begin
+declare x int;
+declare continue handler for not found
+select 'Inner (bad)' as 'h_sn';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_sw()
+deterministic
+begin
+-- data exception - numeric value out of range
+declare continue handler for sqlstate '22003'
+    select 'Outer (good)' as 'h_sw';
+begin
+declare continue handler for sqlwarning
+select 'Inner (bad)' as 'h_sw';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_sx()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (good)' as 'h_sx';
+begin
+declare continue handler for sqlexception
+select 'Inner (bad)' as 'h_sx';
+insert into t3 values (1);
+end;
+end|
+create procedure h_ne()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_ne';
+begin
+declare x int;
+declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+select 'Inner (good)' as 'h_ne';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_ns()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_ns';
+begin
+declare x int;
+declare continue handler for sqlstate '02000' -- no data
+select 'Inner (good)' as 'h_ns';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_nn()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_nn';
+begin
+declare x int;
+declare continue handler for not found
+select 'Inner (good)' as 'h_nn';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_we()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_we';
+begin
+declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+select 'Inner (good)' as 'h_we';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ws()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_ws';
+begin
+-- data exception - numeric value out of range
+declare continue handler for sqlstate '22003'
+      select 'Inner (good)' as 'h_ws';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ww()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_ww';
+begin
+declare continue handler for sqlwarning
+select 'Inner (good)' as 'h_ww';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_xe()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xe';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_xe';
+insert into t3 values (1);
+end;
+end|
+create procedure h_xs()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xs';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000'
+      select 'Inner (good)' as 'h_xs';
+insert into t3 values (1);
+end;
+end|
+create procedure h_xx()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xx';
+begin
+declare continue handler for sqlexception
+select 'Inner (good)' as 'h_xx';
+insert into t3 values (1);
+end;
+end|
+call h_ee()|
+h_ee
+Inner (good)
+call h_es()|
+h_es
+Outer (good)
+call h_en()|
+h_en
+Outer (good)
+call h_ew()|
+h_ew
+Outer (good)
+call h_ex()|
+h_ex
+Outer (good)
+call h_se()|
+h_se
+Inner (good)
+call h_ss()|
+h_ss
+Inner (good)
+call h_sn()|
+h_sn
+Outer (good)
+call h_sw()|
+h_sw
+Outer (good)
+call h_sx()|
+h_sx
+Outer (good)
+call h_ne()|
+h_ne
+Inner (good)
+call h_ns()|
+h_ns
+Inner (good)
+call h_nn()|
+h_nn
+Inner (good)
+call h_we()|
+h_we
+Inner (good)
+call h_ws()|
+h_ws
+Inner (good)
+call h_ww()|
+h_ww
+Inner (good)
+call h_xe()|
+h_xe
+Inner (good)
+call h_xs()|
+h_xs
+Inner (good)
+call h_xx()|
+h_xx
+Inner (good)
+drop table t3|
+drop procedure h_ee|
+drop procedure h_es|
+drop procedure h_en|
+drop procedure h_ew|
+drop procedure h_ex|
+drop procedure h_se|
+drop procedure h_ss|
+drop procedure h_sn|
+drop procedure h_sw|
+drop procedure h_sx|
+drop procedure h_ne|
+drop procedure h_ns|
+drop procedure h_nn|
+drop procedure h_we|
+drop procedure h_ws|
+drop procedure h_ww|
+drop procedure h_xe|
+drop procedure h_xs|
+drop procedure h_xx|
 drop procedure if exists bug822|
 create procedure bug822(a_id char(16), a_data int)
 begin
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 53c15ffd05b..bc0b6f654b8 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -1660,7 +1660,7 @@ drop function `foo`|
 # Implicit LOCK/UNLOCK TABLES for table access in functions
 #
 
---disable_warning
+--disable_warnings
 drop function if exists t1max|
 --enable_warnings
 create function t1max() returns int
@@ -1704,6 +1704,397 @@ drop table t3|
 drop function getcount|
 
 
+# Test cases for different combinations of condition handlers in nested
+# begin-end blocks in stored procedures.
+#
+# Note that the standard specifies that the most specific handler should
+# be triggered even if it's an outer handler masked by a less specific
+# handler in an inner block.
+# Note also that '02000' is more specific than NOT FOUND; there might be
+# other '02xxx' states, even if we currently do not issue them in any
+# situation (e.g. '02001').
+#
+# The combinations we test are these:
+#
+#                                         Inner
+#              errcode      sqlstate     not found    sqlwarning   sqlexception
+#  Outer      +------------+------------+------------+------------+------------+
+#errcode      | h_ee (i)   | h_es (o)   | h_en (o)   | h_ew (o)   | h_ex (o)   |
+#sqlstate     | h_se (i)   | h_ss (i)   | h_sn (o)   | h_sw (o)   | h_sx (o)   |
+#not found    | h_ne (i)   | h_ns (i)   | h_nn (i)   |            |            |
+#sqlwarning   | h_we (i)   | h_ws (i)   |            | h_ww (i)   |            |
+#sqlexception | h_xe (i)   | h_xs (i)   |            |            | h_xx (i)   |
+#             +------------+---------------------------------------------------+
+#
+# (i) means that the inner handler is the one that should be invoked,
+# (o) means that the outer handler should be invoked.
+#
+# ('not found', 'sqlwarning' and 'sqlexception' are mutually exclusive, hence
+#  no tests for those combinations.)
+#
+
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists h_ee|
+drop procedure if exists h_es|
+drop procedure if exists h_en|
+drop procedure if exists h_ew|
+drop procedure if exists h_ex|
+drop procedure if exists h_se|
+drop procedure if exists h_ss|
+drop procedure if exists h_sn|
+drop procedure if exists h_sw|
+drop procedure if exists h_sx|
+drop procedure if exists h_ne|
+drop procedure if exists h_ns|
+drop procedure if exists h_nn|
+drop procedure if exists h_we|
+drop procedure if exists h_ws|
+drop procedure if exists h_ww|
+drop procedure if exists h_xe|
+drop procedure if exists h_xs|
+drop procedure if exists h_xx|
+--enable_warnings
+
+# smallint    - to get out of range warnings
+# primary key - to get constraint errors
+create table t3 (a smallint primary key)|
+
+insert into t3 (a) values (1)|
+
+create procedure h_ee()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (bad)' as 'h_ee';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+        select 'Inner (good)' as 'h_ee';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_es()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (good)' as 'h_es';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000'
+      select 'Inner (bad)' as 'h_es';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_en()
+    deterministic
+begin
+  declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+    select 'Outer (good)' as 'h_en';
+
+  begin
+    declare x int;
+    declare continue handler for sqlstate '02000' -- no data
+      select 'Inner (bad)' as 'h_en';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_ew()
+    deterministic
+begin
+  declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+    select 'Outer (good)' as 'h_ew';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (bad)' as 'h_ew';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ex()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (good)' as 'h_ex';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (bad)' as 'h_ex';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_se()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (bad)' as 'h_se';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+      select 'Inner (good)' as 'h_se';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_ss()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (bad)' as 'h_ss';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000' 
+      select 'Inner (good)' as 'h_ss';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_sn()
+    deterministic
+begin
+  -- Note: '02000' is more specific than NOT FOUND ;
+  --       there might be other not found states 
+  declare continue handler for sqlstate '02000' -- no data
+    select 'Outer (good)' as 'h_sn';
+
+  begin
+    declare x int;
+    declare continue handler for not found
+      select 'Inner (bad)' as 'h_sn';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_sw()
+    deterministic
+begin
+  -- data exception - numeric value out of range
+  declare continue handler for sqlstate '22003'
+    select 'Outer (good)' as 'h_sw';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (bad)' as 'h_sw';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_sx()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (good)' as 'h_sx';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (bad)' as 'h_sx';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_ne()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_ne';
+
+  begin
+    declare x int;
+    declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+      select 'Inner (good)' as 'h_ne';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_ns()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_ns';
+
+  begin
+    declare x int;
+    declare continue handler for sqlstate '02000' -- no data
+      select 'Inner (good)' as 'h_ns';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_nn()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_nn';
+
+  begin
+    declare x int;
+    declare continue handler for not found
+      select 'Inner (good)' as 'h_nn';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_we()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_we';
+
+  begin
+    declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+      select 'Inner (good)' as 'h_we';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ws()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_ws';
+
+  begin
+    -- data exception - numeric value out of range
+    declare continue handler for sqlstate '22003'
+      select 'Inner (good)' as 'h_ws';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ww()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_ww';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (good)' as 'h_ww';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_xe()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xe';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+      select 'Inner (good)' as 'h_xe';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_xs()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xs';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000'
+      select 'Inner (good)' as 'h_xs';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_xx()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xx';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (good)' as 'h_xx';
+
+    insert into t3 values (1);
+  end;
+end|
+
+call h_ee()|
+call h_es()|
+call h_en()|
+call h_ew()|
+call h_ex()|
+call h_se()|
+call h_ss()|
+call h_sn()|
+call h_sw()|
+call h_sx()|
+call h_ne()|
+call h_ns()|
+call h_nn()|
+call h_we()|
+call h_ws()|
+call h_ww()|
+call h_xe()|
+call h_xs()|
+call h_xx()|
+
+drop table t3|
+drop procedure h_ee|
+drop procedure h_es|
+drop procedure h_en|
+drop procedure h_ew|
+drop procedure h_ex|
+drop procedure h_se|
+drop procedure h_ss|
+drop procedure h_sn|
+drop procedure h_sw|
+drop procedure h_sx|
+drop procedure h_ne|
+drop procedure h_ns|
+drop procedure h_nn|
+drop procedure h_we|
+drop procedure h_ws|
+drop procedure h_ww|
+drop procedure h_xe|
+drop procedure h_xs|
+drop procedure h_xx|
+
+
 #
 # Test cases for old bugs
 #

From de0c65dd4e925105b2670e2f86a041cd76820e0d Mon Sep 17 00:00:00 2001
From: unknown <evgen@moonbone.local>
Date: Wed, 15 Feb 2006 19:45:06 +0300
Subject: [PATCH 011/103] Fix bug #15706 find_field_in_tables() returns field
 from outer select

If item->cached_table is set, find_field_in_tables() returns found field
even if it doesn't belong to current select. Because Item_field::fix_fields
doesn't expect such behaviour, reported bug occurs.

Item_field::fix_fields() was modifed to detect when find_field_in_tables()
can return field from outer select and process such fields accordingly.
In order to ease this code which was searching and processing outed fields was
moved into separate function called Item_field::fix_outer_field().


sql/item_subselect.h:
  Fixed bug #15706: find_field_in_tables() returns field from outer select
  Item_field::fix_outer_field() was marked as friend to Item_subselect class.
sql/item.h:
  Fixed bug #15706: find_field_in_tables() returns field from outer select
  fix_outer_field() function is added to the Item_field class.
sql/item.cc:
  Fixed bug #15706: find_field_in_tables() returns field from outer select

  Item_ref::fix_fields() and Item_field::fix_fields() were modifed to detect when
  find_field_in_tables() can return field from outer select and process such
  fields accordingly.
  In order to ease this, code Item_field::fix_fields() which was searching and
  processing outer fields was moved into separate function called
  Item_field::fix_outer_field().
  To the Item_field::fix_field() added a loop for finding context for found field.
mysql-test/t/disabled.def:
  Fixed bug #15706: find_field_in_tables() returns field from outer select
  Enable subselect test
---
 mysql-test/t/disabled.def |   1 -
 sql/item.cc               | 477 ++++++++++++++++++++++----------------
 sql/item.h                |   1 +
 sql/item_subselect.h      |   1 +
 4 files changed, 285 insertions(+), 195 deletions(-)

diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 4722fac435c..4f5e11e7fbd 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -12,4 +12,3 @@
 
 sp-goto         : GOTO is currently is disabled - will be fixed in the future
 kill            : Unstable test case, bug#9712
-subselect       : Bug#15706
diff --git a/sql/item.cc b/sql/item.cc
index 659970f2a91..793cbc70998 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3210,6 +3210,252 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
 }
 
 
+/*
+  Resolve the name of an outer select column reference.
+
+  SYNOPSIS
+    Item_field::fix_outer_field()
+    thd        [in]      current thread
+    from_field [in/out]  found field reference or (Field*)not_found_field
+    reference  [in/out]  view column if this item was resolved to a view column
+
+  DESCRIPTION
+    The method resolves the column reference represented by 'this' as a column
+    present in outer selects that contain current select.
+
+  NOTES
+    This is the inner loop of Item_field::fix_fields:
+
+      for each outer query Q_k beginning from the inner-most one
+      {
+        search for a column or derived column named col_ref_i
+        [in table T_j] in the FROM clause of Q_k;
+
+        if such a column is not found
+          Search for a column or derived column named col_ref_i
+          [in table T_j] in the SELECT and GROUP clauses of Q_k.
+      }
+
+  IMPLEMENTATION
+    In prepared statements, because of cache, find_field_in_tables()
+    can resolve fields even if they don't belong to current context.
+    In this case this method only finds appropriate context and marks
+    current select as dependent. The found reference of field should be
+    provided in 'from_field'.
+
+  RETURN
+     1 - column succefully resolved and fix_fields() should continue.
+     0 - column fully fixed and fix_fields() should return FALSE
+    -1 - error occured
+*/
+int
+Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
+{
+  enum_parsing_place place= NO_MATTER;
+  bool field_found= (*from_field != not_found_field);
+  bool upward_lookup= FALSE;
+
+  /*
+    If there are outer contexts (outer selects, but current select is
+    not derived table or view) try to resolve this reference in the
+    outer contexts.
+
+    We treat each subselect as a separate namespace, so that different
+    subselects may contain columns with the same names. The subselects
+    are searched starting from the innermost.
+  */
+  Name_resolution_context *last_checked_context= context;
+  Item **ref= (Item **) not_found_item;
+  Name_resolution_context *outer_context= context->outer_context;
+  for (;
+       outer_context;
+       outer_context= outer_context->outer_context)
+  {
+    SELECT_LEX *select= outer_context->select_lex;
+    Item_subselect *prev_subselect_item=
+      last_checked_context->select_lex->master_unit()->item;
+    last_checked_context= outer_context;
+    upward_lookup= TRUE;
+
+    place= prev_subselect_item->parsing_place;
+    /*
+      If outer_field is set, field was already found by first call
+      to find_field_in_tables(). Only need to find appropriate context.
+    */
+    if (field_found && outer_context->select_lex !=
+        cached_table->select_lex)
+      continue;
+    /*
+      In case of a view, find_field_in_tables() writes the pointer to
+      the found view field into '*reference', in other words, it
+      substitutes this Item_field with the found expression.
+    */
+    if (field_found || (*from_field= find_field_in_tables(thd, this,
+                                          outer_context->
+                                            first_name_resolution_table,
+                                          outer_context->
+                                            last_name_resolution_table,
+                                          reference,
+                                          IGNORE_EXCEPT_NON_UNIQUE,
+                                          TRUE, TRUE)) !=
+        not_found_field)
+    {
+      if (*from_field)
+      {
+        if (*from_field != view_ref_found)
+        {
+          prev_subselect_item->used_tables_cache|= (*from_field)->table->map;
+          prev_subselect_item->const_item_cache= 0;
+          if (thd->lex->in_sum_func &&
+              thd->lex->in_sum_func->nest_level == 
+              thd->lex->current_select->nest_level)
+          {
+            Item::Type type= (*reference)->type();
+            set_if_bigger(thd->lex->in_sum_func->max_arg_level,
+                          select->nest_level);
+            set_field(*from_field);
+            fixed= 1;
+            mark_as_dependent(thd, last_checked_context->select_lex,
+                              context->select_lex, this,
+                              ((type == REF_ITEM || type == FIELD_ITEM) ?
+                               (Item_ident*) (*reference) : 0));
+            return 0;
+          }
+        }
+        else
+        {
+          Item::Type type= (*reference)->type();
+          prev_subselect_item->used_tables_cache|=
+            (*reference)->used_tables();
+          prev_subselect_item->const_item_cache&=
+            (*reference)->const_item();
+          mark_as_dependent(thd, last_checked_context->select_lex,
+                            context->select_lex, this,
+                            ((type == REF_ITEM || type == FIELD_ITEM) ?
+                             (Item_ident*) (*reference) :
+                             0));
+          /*
+            A reference to a view field had been found and we
+            substituted it instead of this Item (find_field_in_tables
+            does it by assigning the new value to *reference), so now
+            we can return from this function.
+          */
+          return 0;
+        }
+      }
+      break;
+    }
+
+    /* Search in SELECT and GROUP lists of the outer select. */
+    if (outer_context->resolve_in_select_list)
+    {
+      if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
+        return -1; /* Some error occurred (e.g. ambiguous names). */
+      if (ref != not_found_item)
+      {
+        DBUG_ASSERT(*ref && (*ref)->fixed);
+        prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
+        prev_subselect_item->const_item_cache&= (*ref)->const_item();
+        break;
+      }
+    }
+
+    /*
+      Reference is not found in this select => this subquery depend on
+      outer select (or we just trying to find wrong identifier, in this
+      case it does not matter which used tables bits we set)
+    */
+    prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
+    prev_subselect_item->const_item_cache= 0;
+  }
+
+  DBUG_ASSERT(ref != 0);
+  if (!*from_field)
+    return -1;
+  if (ref == not_found_item && *from_field == not_found_field)
+  {
+    if (upward_lookup)
+    {
+      // We can't say exactly what absent table or field
+      my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
+    }
+    else
+    {
+      /* Call find_field_in_tables only to report the error */
+      find_field_in_tables(thd, this,
+                           context->first_name_resolution_table,
+                           context->last_name_resolution_table,
+                           reference, REPORT_ALL_ERRORS,
+                           !any_privileges &&
+                           TRUE, TRUE);
+    }
+    return -1;
+  }
+  else if (ref != not_found_item)
+  {
+    Item *save;
+    Item_ref *rf;
+
+    /* Should have been checked in resolve_ref_in_select_and_group(). */
+    DBUG_ASSERT(*ref && (*ref)->fixed);
+    /*
+      Here, a subset of actions performed by Item_ref::set_properties
+      is not enough. So we pass ptr to NULL into Item_[direct]_ref
+      constructor, so no initialization is performed, and call 
+      fix_fields() below.
+    */
+    save= *ref;
+    *ref= NULL;                             // Don't call set_properties()
+    rf= (place == IN_HAVING ?
+         new Item_ref(context, ref, (char*) table_name,
+                      (char*) field_name) :
+         new Item_direct_ref(context, ref, (char*) table_name,
+                             (char*) field_name));
+    *ref= save;
+    if (!rf)
+      return -1;
+    thd->change_item_tree(reference, rf);
+    /*
+      rf is Item_ref => never substitute other items (in this case)
+      during fix_fields() => we can use rf after fix_fields()
+    */
+    DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
+    if (rf->fix_fields(thd, reference) || rf->check_cols(1))
+      return -1;
+
+    mark_as_dependent(thd, last_checked_context->select_lex,
+                      context->select_lex, this,
+                      rf);
+    return 0;
+  }
+  else
+  {
+    mark_as_dependent(thd, last_checked_context->select_lex,
+                      context->select_lex,
+                      this, this);
+    if (last_checked_context->select_lex->having_fix_field)
+    {
+      Item_ref *rf;
+      rf= new Item_ref(context,
+                       (cached_table->db[0] ? cached_table->db : 0),
+                       (char*) cached_table->alias, (char*) field_name);
+      if (!rf)
+        return -1;
+      thd->change_item_tree(reference, rf);
+      /*
+        rf is Item_ref => never substitute other items (in this case)
+        during fix_fields() => we can use rf after fix_fields()
+      */
+      DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
+      if (rf->fix_fields(thd, reference) || rf->check_cols(1))
+        return -1;
+      return 0;
+    }
+  }
+  return 1;
+}
+
+
 /*
   Resolve the name of a column reference.
 
@@ -3257,12 +3503,11 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
 
 bool Item_field::fix_fields(THD *thd, Item **reference)
 {
-  enum_parsing_place place= NO_MATTER;
   DBUG_ASSERT(fixed == 0);
   if (!field)					// If field is not checked
   {
-    bool upward_lookup= FALSE;
     Field *from_field= (Field *)not_found_field;
+    bool outer_fixed= false;
     /*
       In case of view, find_field_in_tables() write pointer to view field
       expression to 'reference', i.e. it substitute that expression instead
@@ -3277,7 +3522,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
                                           TRUE)) ==
 	not_found_field)
     {
-
+      int ret;
       /* Look up in current select's item_list to find aliased fields */
       if (thd->lex->current_select->is_item_list_lookup)
       {
@@ -3292,197 +3537,11 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
           return 0;
         }
       }
-
-      /*
-        If there are outer contexts (outer selects, but current select is
-        not derived table or view) try to resolve this reference in the
-        outer contexts.
-
-        We treat each subselect as a separate namespace, so that different
-        subselects may contain columns with the same names. The subselects
-        are searched starting from the innermost.
-      */
-      Name_resolution_context *last_checked_context= context;
-      Item **ref= (Item **) not_found_item;
-      Name_resolution_context *outer_context= context->outer_context;
-      for (;
-           outer_context;
-           outer_context= outer_context->outer_context)
-      {
-        SELECT_LEX *select= outer_context->select_lex;
-        Item_subselect *prev_subselect_item=
-          last_checked_context->select_lex->master_unit()->item;
-        last_checked_context= outer_context;
-        upward_lookup= TRUE;
-
-        place= prev_subselect_item->parsing_place;
-        /*
-          In case of a view, find_field_in_tables() writes the pointer to
-          the found view field into '*reference', in other words, it
-          substitutes this Item_field with the found expression.
-        */
-        if ((from_field= find_field_in_tables(thd, this,
-                                              outer_context->
-                                                first_name_resolution_table,
-                                              outer_context->
-                                                last_name_resolution_table,
-                                              reference,
-                                              IGNORE_EXCEPT_NON_UNIQUE,
-                                              TRUE, TRUE)) !=
-            not_found_field)
-        {
-          if (from_field)
-          {
-            if (from_field != view_ref_found)
-            {
-              prev_subselect_item->used_tables_cache|= from_field->table->map;
-              prev_subselect_item->const_item_cache= 0;
-              if (thd->lex->in_sum_func &&
-                  thd->lex->in_sum_func->nest_level == 
-                  thd->lex->current_select->nest_level)
-              {
-                Item::Type type= (*reference)->type();
-                set_if_bigger(thd->lex->in_sum_func->max_arg_level,
-                              select->nest_level);
-                set_field(from_field);
-                fixed= 1;
-                mark_as_dependent(thd, last_checked_context->select_lex,
-                                  context->select_lex, this,
-                                  ((type == REF_ITEM || type == FIELD_ITEM) ?
-                                   (Item_ident*) (*reference) : 0));
-                return FALSE;
-              }
-            }
-            else
-            {
-              Item::Type type= (*reference)->type();
-              prev_subselect_item->used_tables_cache|=
-                (*reference)->used_tables();
-              prev_subselect_item->const_item_cache&=
-                (*reference)->const_item();
-              mark_as_dependent(thd, last_checked_context->select_lex,
-                                context->select_lex, this,
-                                ((type == REF_ITEM || type == FIELD_ITEM) ?
-                                 (Item_ident*) (*reference) :
-                                 0));
-              /*
-                A reference to a view field had been found and we
-                substituted it instead of this Item (find_field_in_tables
-                does it by assigning the new value to *reference), so now
-                we can return from this function.
-              */
-              return FALSE;
-            }
-          }
-          break;
-        }
-
-        /* Search in SELECT and GROUP lists of the outer select. */
-        if (outer_context->resolve_in_select_list)
-        {
-          if (!(ref= resolve_ref_in_select_and_group(thd, this, select)))
-            goto error; /* Some error occurred (e.g. ambiguous names). */
-          if (ref != not_found_item)
-          {
-            DBUG_ASSERT(*ref && (*ref)->fixed);
-            prev_subselect_item->used_tables_cache|= (*ref)->used_tables();
-	    prev_subselect_item->const_item_cache&= (*ref)->const_item();
-            break;
-          }
-        }
-
-        /*
-          Reference is not found in this select => this subquery depend on
-          outer select (or we just trying to find wrong identifier, in this
-          case it does not matter which used tables bits we set)
-        */
-        prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT;
-        prev_subselect_item->const_item_cache= 0;
-      }
-
-      DBUG_ASSERT(ref != 0);
-      if (!from_field)
-	goto error;
-      if (ref == not_found_item && from_field == not_found_field)
-      {
-	if (upward_lookup)
-	{
-          // We can't say exactly what absent table or field
-	  my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
-	}
-	else
-	{
-          /* Call find_field_in_tables only to report the error */
-	  find_field_in_tables(thd, this,
-                               context->first_name_resolution_table,
-                               context->last_name_resolution_table,
-                               reference, REPORT_ALL_ERRORS,
-                               !any_privileges &&
-                               TRUE, TRUE);
-	}
-	goto error;
-      }
-      else if (ref != not_found_item)
-      {
-        Item *save;
-        Item_ref *rf;
-
-        /* Should have been checked in resolve_ref_in_select_and_group(). */
-        DBUG_ASSERT(*ref && (*ref)->fixed);
-        /*
-          Here, a subset of actions performed by Item_ref::set_properties
-          is not enough. So we pass ptr to NULL into Item_[direct]_ref
-          constructor, so no initialization is performed, and call 
-          fix_fields() below.
-        */
-        save= *ref;
-        *ref= NULL;                             // Don't call set_properties()
-        rf= (place == IN_HAVING ?
-             new Item_ref(context, ref, (char*) table_name,
-                          (char*) field_name) :
-             new Item_direct_ref(context, ref, (char*) table_name,
-                                 (char*) field_name));
-        *ref= save;
-	if (!rf)
-	  goto error;
-        thd->change_item_tree(reference, rf);
-	/*
-	  rf is Item_ref => never substitute other items (in this case)
-	  during fix_fields() => we can use rf after fix_fields()
-	*/
-        DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
-        if (rf->fix_fields(thd, reference) || rf->check_cols(1))
-	  goto error;
-
-	mark_as_dependent(thd, last_checked_context->select_lex,
-                          context->select_lex, this,
-                          rf);
-	return FALSE;
-      }
-      else
-      {
-	mark_as_dependent(thd, last_checked_context->select_lex,
-                          context->select_lex,
-                          this, this);
-	if (last_checked_context->select_lex->having_fix_field)
-	{
-	  Item_ref *rf;
-          rf= new Item_ref(context,
-                           (cached_table->db[0] ? cached_table->db : 0),
-                           (char*) cached_table->alias, (char*) field_name);
-	  if (!rf)
-	    goto error;
-          thd->change_item_tree(reference, rf);
-	  /*
-	    rf is Item_ref => never substitute other items (in this case)
-	    during fix_fields() => we can use rf after fix_fields()
-	  */
-          DBUG_ASSERT(!rf->fixed);                // Assured by Item_ref()
-          if (rf->fix_fields(thd, reference) || rf->check_cols(1))
-            goto error;
-          return FALSE;
-	}
-      }
+      if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
+        goto error;
+      else if (!ret)
+        return FALSE;
+      outer_fixed= TRUE;
     }
     else if (!from_field)
       goto error;
@@ -3502,6 +3561,17 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
     if (from_field == view_ref_found)
       return FALSE;
 
+    if (!outer_fixed && cached_table && cached_table->select_lex &&
+          context->select_lex &&
+          cached_table->select_lex != context->select_lex)
+    {
+      int ret;
+      if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
+        goto error;
+      else if (!ret)
+        return FALSE;
+    }
+
     set_field(from_field);
     if (thd->lex->in_sum_func &&
         thd->lex->in_sum_func->nest_level == 
@@ -4620,6 +4690,25 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
           }
           if (from_field != not_found_field)
           {
+            if (cached_table && cached_table->select_lex &&
+                outer_context->select_lex &&
+                cached_table->select_lex != outer_context->select_lex)
+            {
+              /*
+                Due to cache, find_field_in_tables() can return field which
+                doesn't belong to provided outer_context. In this case we have
+                to find proper field context in order to fix field correcly.
+              */
+              do
+              {
+                outer_context= outer_context->outer_context;
+                select= outer_context->select_lex;
+                prev_subselect_item=
+                  last_checked_context->select_lex->master_unit()->item;
+                last_checked_context= outer_context;
+              } while (outer_context && outer_context->select_lex &&
+                       cached_table->select_lex != outer_context->select_lex);
+            }
             prev_subselect_item->used_tables_cache|= from_field->table->map;
             prev_subselect_item->const_item_cache= 0;
             break;
diff --git a/sql/item.h b/sql/item.h
index 4b49ff907d3..1a5e64c585b 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1161,6 +1161,7 @@ public:
   inline uint32 max_disp_length() { return field->max_length(); }
   Item_field *filed_for_view_update() { return this; }
   Item *safe_charset_converter(CHARSET_INFO *tocs);
+  int fix_outer_field(THD *thd, Field **field, Item **reference);
   friend class Item_default_value;
   friend class Item_insert_value;
   friend class st_select_lex_unit;
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index f1c99f74498..a4dac5bda87 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -125,6 +125,7 @@ public:
   friend class select_subselect;
   friend class Item_in_optimizer;
   friend bool Item_field::fix_fields(THD *, Item **);
+  friend int  Item_field::fix_outer_field(THD *, Field **, Item **);
   friend bool Item_ref::fix_fields(THD *, Item **);
   friend void mark_select_range_as_dependent(THD*,
                                              st_select_lex*, st_select_lex*,

From 8c1c10dc20c471d349ddd08e566efd63d44d825e Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Wed, 15 Feb 2006 22:43:42 +0100
Subject: [PATCH 012/103] Add possibility to have a negative expression in "if"
 and "while" in mysqltest

client/mysqltest.c:
  Extend 'do_block' to be able to process a !<expression>.
  Making it possible to do 'if(!$i)' and 'while(!$i)'
mysql-test/r/mysqltest.result:
  Update test results
mysql-test/t/mysqltest.test:
  Add test for if
  Add test for while with ! expr
---
 client/mysqltest.c            | 49 ++++++++++++++++++++++++++++++++---
 mysql-test/r/mysqltest.result |  3 +++
 mysql-test/t/mysqltest.test   | 31 +++++++++++++++++++++-
 3 files changed, 78 insertions(+), 5 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 3179535347d..cb5325f9158 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -2362,12 +2362,41 @@ int do_done(struct st_query *q)
 }
 
 
+/*
+  Process start of a "if" or "while" statement
+
+  SYNOPSIS
+   do_block()
+    cmd        Type of block
+    q	       called command
+
+  DESCRIPTION
+    if ([!]<expr>)
+    {
+      <block statements>
+    }
+
+    while ([!]<expr>)
+    {
+      <block statements>
+    }
+
+    Evaluates the <expr> and if it evaluates to
+    greater than zero executes the following code block.
+    A '!' can be used before the <expr> to indicate it should
+    be executed if it evaluates to zero.
+
+ */
+
 int do_block(enum block_cmd cmd, struct st_query* q)
 {
   char *p= q->first_argument;
   const char *expr_start, *expr_end;
   VAR v;
   const char *cmd_name= (cmd == cmd_while ? "while" : "if");
+  my_bool not_expr= FALSE;
+  DBUG_ENTER("do_block");
+  DBUG_PRINT("enter", ("%s", cmd_name));
 
   /* Check stack overflow */
   if (cur_block == block_stack_end)
@@ -2388,8 +2417,16 @@ int do_block(enum block_cmd cmd, struct st_query* q)
 
   /* Parse and evaluate test expression */
   expr_start= strchr(p, '(');
-  if (!expr_start)
+  if (!expr_start++)
     die("missing '(' in %s", cmd_name);
+
+  /* Check for !<expr> */
+  if (*expr_start == '!')
+  {
+    not_expr= TRUE;
+    expr_start++; /* Step past the '!' */
+  }
+  /* Find ending ')' */
   expr_end= strrchr(expr_start, ')');
   if (!expr_end)
     die("missing ')' in %s", cmd_name);
@@ -2403,14 +2440,20 @@ int do_block(enum block_cmd cmd, struct st_query* q)
     die("Missing '{' after %s. Found \"%s\"", cmd_name, p);
 
   var_init(&v,0,0,0,0);
-  eval_expr(&v, ++expr_start, &expr_end);
+  eval_expr(&v, expr_start, &expr_end);
 
   /* Define inner block */
   cur_block++;
   cur_block->cmd= cmd;
   cur_block->ok= (v.int_val ? TRUE : FALSE);
 
+  if (not_expr)
+    cur_block->ok = !cur_block->ok;
+
+  DBUG_PRINT("info", ("OK: %d", cur_block->ok));
+
   var_free(&v);
+  DBUG_VOID_RETURN;
   return 0;
 }
 
@@ -3046,8 +3089,6 @@ static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
 static void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field,
                          const char* val, ulonglong len, bool is_null)
 {
-
-  char buf[256];
   if (col_idx < max_replace_column && replace_column[col_idx])
   {
     val= replace_column[col_idx];
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 067054510c2..a7286316b0a 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -309,7 +309,10 @@ test
 test2
 test3
 test4
+Counter is greater than 0, (counter=10)
+Counter is not 0, (counter=0)
 1
+Testing while with not
 mysqltest: In included file "./include/mysqltest_while.inc": At line 64: Nesting too deeply
 mysqltest: At line 1: missing '(' in while
 mysqltest: At line 1: missing ')' in while
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 5cf49185c30..7699817354f 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -742,6 +742,30 @@ echo test3stop
 --delimiter ;
 echo test4;
 
+
+# ----------------------------------------------------------------------------
+# Test if
+# ----------------------------------------------------------------------------
+
+let $counter=10;
+if ($counter)
+{
+  echo Counter is greater than 0, (counter=10);
+}
+if (!$counter)
+{
+  echo Counter is not 0, (counter=10);
+}
+let $counter=0;
+if ($counter)
+{
+  echo Counter is greater than 0, (counter=0);
+}
+if (!$counter)
+{
+  echo Counter is not 0, (counter=0);
+}
+
 # ----------------------------------------------------------------------------
 # Test while, { and }
 # ----------------------------------------------------------------------------
@@ -755,7 +779,12 @@ while ($i)
 # One liner
 #let $i=1;while ($i){echo $i;dec $i;}
 
-
+let $i=0;
+while (!$i)
+{
+  echo Testing while with not;
+  inc $i;
+}
 
 # Exceed max nesting level
 --error 1

From 3e17193aa341f3a88d98aded5f1898ca6c230911 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Wed, 15 Feb 2006 22:46:16 +0100
Subject: [PATCH 013/103] Bug#16795 ndb_cache_multi2  - remove timing dependent
 part of test, wait until condition occurs or sleep max 10 seconds

mysql-test/r/ndb_cache_multi2.result:
  Update test results
mysql-test/t/ndb_cache_multi2.test:
  Convert long sleeps to a while leep whith small sleeps and a check if condition has occured.
  This allows slower machines to sleep longer if needed.
---
 mysql-test/r/ndb_cache_multi2.result |  7 ++-----
 mysql-test/t/ndb_cache_multi2.test   | 27 +++++++++++++++++++--------
 2 files changed, 21 insertions(+), 13 deletions(-)

diff --git a/mysql-test/r/ndb_cache_multi2.result b/mysql-test/r/ndb_cache_multi2.result
index 2863908a436..63cc4d4ceed 100644
--- a/mysql-test/r/ndb_cache_multi2.result
+++ b/mysql-test/r/ndb_cache_multi2.result
@@ -64,13 +64,10 @@ a
 3
 show status like "Qcache_queries_in_cache";
 Variable_name	Value
-Qcache_queries_in_cache	2
+Qcache_queries_in_cache	3
 show status like "Qcache_inserts";
 Variable_name	Value
-Qcache_inserts	3
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	0
+Qcache_inserts	4
 drop table t1, t2;
 set GLOBAL query_cache_size=0;
 set GLOBAL ndb_cache_check_time=0;
diff --git a/mysql-test/t/ndb_cache_multi2.test b/mysql-test/t/ndb_cache_multi2.test
index 9352505649c..5a78380097e 100644
--- a/mysql-test/t/ndb_cache_multi2.test
+++ b/mysql-test/t/ndb_cache_multi2.test
@@ -24,10 +24,6 @@ set GLOBAL ndb_cache_check_time=1;
 reset query cache;
 flush status;
 
-# Sleep so that the query cache check thread has time to start
-sleep 15;
-
-
 # Create test tables in NDB and load them into cache
 # on server1
 connection server1;
@@ -53,19 +49,34 @@ show status like "Qcache_inserts";
 show status like "Qcache_hits";
 update t1 set a=3 where a=2;
 
-# Sleep so that the query cache check thread has time to run
-sleep 5;
-
 # Connect to server1 and check that cache is invalidated 
 # and correct data is returned
 connection server1;
 show status like "Qcache_queries_in_cache";
 show status like "Qcache_inserts";
 show status like "Qcache_hits";
+
+# Loop and wait for max 10 seconds until query cache thread
+# has invalidated the cache and the column a in t1 is equal to 3
+let $retries=20;
+while (`select a != 3 from t1`)
+{
+  dec $retries;
+  if (!$retries)
+  {
+     The query_cache thread failed to invalidate query_cache in 10 seconds;
+  }
+  sleep 0.5;
+}
+
+# Select from t1 one last time for the result file
+# Column a should be 3
 select * from t1;
+
+# There should now be three queries in the cache
 show status like "Qcache_queries_in_cache";
+# And inserts should be four
 show status like "Qcache_inserts";
-show status like "Qcache_hits";
 
 drop table t1, t2;
 

From f47a3805d956c5863d1a5dd94b3b868016b26058 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 00:53:55 +0100
Subject: [PATCH 014/103] Bug#13809 mysql-test: --replace_result option works
 on Windows incorrect

client/mysqltest.c:
  Convert cr/lf to lf
---
 client/mysqltest.c | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6f212f784ef..da6a670c4ed 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -2517,10 +2517,16 @@ int read_line(char *buf, int size)
       continue;
     }
 
-    /* Line counting is independent of state */
     if (c == '\n')
+    {
+      /* Line counting is independent of state */
       cur_file->lineno++;
 
+      /* Convert cr/lf to lf */
+      if (p != buf && *(p-1) == '\r')
+        *(p-1)= 0;
+    }
+
     switch(state) {
     case R_NORMAL:
       /*  Only accept '{' in the beginning of a line */

From d430e2474fbffe05307d1a2b9697db6e43c8b211 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 12:02:38 +0100
Subject: [PATCH 015/103] Bug#2845 client fails to reconnect if using TCP/IP -
 Detect that connection to server has been broken in "net_clear". Since  
 net_clear is always called before we send command to server, we can be sure  
 that server has not received the command.

mysql-test/r/wait_timeout.result:
  Update test result
mysql-test/t/wait_timeout-master.opt:
  Decrease wait_timeout value to avoid unneccessary sleeps
mysql-test/t/wait_timeout.test:
  Test that same error message is returned when disconnected regardless of connection is socket or TCP
  Decrease sleep times
sql/net_serv.cc:
  Make "net_clear" detect if connection with server has been broken by
  performing a select. If the select returns that there are data to read but
  no data can be read, that means the connection is broken. Signal disconnected
  to "write" functions by setting error to 2.
---
 mysql-test/r/wait_timeout.result     |  8 +++
 mysql-test/t/wait_timeout-master.opt |  2 +-
 mysql-test/t/wait_timeout.test       | 20 ++++++-
 sql/net_serv.cc                      | 85 ++++++++++++++++++++++++----
 4 files changed, 101 insertions(+), 14 deletions(-)

diff --git a/mysql-test/r/wait_timeout.result b/mysql-test/r/wait_timeout.result
index 56232e481c0..683986abf5d 100644
--- a/mysql-test/r/wait_timeout.result
+++ b/mysql-test/r/wait_timeout.result
@@ -6,3 +6,11 @@ ERROR HY000: MySQL server has gone away
 select 3;
 3
 3
+select 1;
+1
+1
+select 2;
+ERROR HY000: MySQL server has gone away
+select 3;
+3
+3
diff --git a/mysql-test/t/wait_timeout-master.opt b/mysql-test/t/wait_timeout-master.opt
index 0ad622e9677..9e5c2289eb2 100644
--- a/mysql-test/t/wait_timeout-master.opt
+++ b/mysql-test/t/wait_timeout-master.opt
@@ -1 +1 @@
---wait-timeout=2
+--wait-timeout=1
diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test
index 26f91569868..1c9efa7c07d 100644
--- a/mysql-test/t/wait_timeout.test
+++ b/mysql-test/t/wait_timeout.test
@@ -3,9 +3,25 @@
 #
 --disable_reconnect
 select 1;
-# wait_timeout is 2, so we should get disconnected now
---sleep 5
+# wait_timeout is 1, so we should get disconnected now
+--sleep 2
+# When the connection is closed in this way, the error code should
+# be consistent see bug#2845 for an explanation
 --error 2006
 select 2;
 --enable_reconnect
 select 3;
+
+# Do the same test as above on a TCP connection
+connect (con1,127.0.0.1,root,,test,$MASTER_MYPORT,);
+--disable_reconnect
+select 1;
+# wait_timeout is 1, so we should get disconnected now
+--sleep 2
+# When the connection is closed in this way, the error code should
+# be consistent see bug#2845 for an explanation
+--error 2006
+select 2;
+--enable_reconnect
+select 3;
+disconnect con1;
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 7326c0395e3..ef56f0d77e2 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -194,30 +194,93 @@ my_bool net_realloc(NET *net, ulong length)
   DBUG_RETURN(0);
 }
 
-	/* Remove unwanted characters from connection */
+
+/*
+  Check if there is any data to be read from the socket
+
+  SYNOPSIS
+    net_data_is_ready()
+    sd   socket descriptor
+
+  DESCRIPTION
+    Check if there is any data to be read from the socket.
+
+  RETURN VALUES
+    0	No data to read
+    1	Data or EOF to read
+*/
+
+static my_bool net_data_is_ready(my_socket sd)
+{
+  fd_set sfds;
+  struct timeval tv;
+  int res;
+
+  FD_ZERO(&sfds);
+  FD_SET(sd, &sfds);
+
+  tv.tv_sec= tv.tv_usec= 0;
+
+  if ((res= select(sd+1, &sfds, NULL, NULL, &tv)) < 0)
+    return FALSE;
+  else
+    return test(res ? FD_ISSET(sd, &sfds) : 0);
+}
+
+
+/*
+  Remove unwanted characters from connection
+  and check if disconnected
+
+  SYNOPSIS
+    net_clear()
+    net			NET handler
+
+  DESCRIPTION
+    Read from socket until there is nothing more to read. Discard
+    what is read.
+
+    If there is anything when to read 'net_clear' is called this
+    normally indicates an error in the protocol.
+
+    When connection is properly closed (for TCP it means with
+    a FIN packet), then select() considers a socket "ready to read",
+    in the sense that there's EOF to read, but read() returns 0.
+
+*/
 
 void net_clear(NET *net)
 {
+  int count;
   DBUG_ENTER("net_clear");
-#if !defined(EXTRA_DEBUG) && !defined(EMBEDDED_LIBRARY)
+#if !defined(EMBEDDED_LIBRARY)
+  while(net_data_is_ready(net->vio->sd))
   {
-    int count;					/* One may get 'unused' warn */
-    my_bool old_mode;
-    if (!vio_blocking(net->vio, FALSE, &old_mode))
+    /* The socket is ready */
+    if ((count= vio_read(net->vio, (char*) (net->buff),
+                         (uint32) net->max_packet)) > 0)
     {
-      while ((count = vio_read(net->vio, (char*) (net->buff),
-			       (uint32) net->max_packet)) > 0)
-	DBUG_PRINT("info",("skipped %d bytes from file: %s",
-			   count, vio_description(net->vio)));
-      vio_blocking(net->vio, TRUE, &old_mode);
+      DBUG_PRINT("info",("skipped %d bytes from file: %s",
+                         count, vio_description(net->vio)));
+#ifdef EXTRA_DEBUG
+      fprintf(stderr,"skipped %d bytes from file: %s\n",
+              count, vio_description(net->vio));
+#endif
+    }
+    else
+    {
+      DBUG_PRINT("info",("socket ready but only EOF to read - disconnected"));
+      net->error= 2;
+      break;
     }
   }
-#endif /* EXTRA_DEBUG */
+#endif
   net->pkt_nr=net->compress_pkt_nr=0;		/* Ready for new command */
   net->write_pos=net->buff;
   DBUG_VOID_RETURN;
 }
 
+
 	/* Flush write_buffer if not empty. */
 
 my_bool net_flush(NET *net)

From 7032a814f2884a3d56dedbcff9a08ba9157ced05 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 13:44:56 +0100
Subject: [PATCH 016/103] Bug#14057 mysql_ping() handles TCP and UNIX socket
 connections in different ways  - Retry the ping if reconnect is turned on and
 the error was CR_SERVER_LOST

libmysql/libmysql.c:
  Send a new ping if first ping fails with CR_SERVER_LOST and reconnect is turned on
---
 libmysql/libmysql.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 11ee7284cbf..8e368090137 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -1370,8 +1370,12 @@ mysql_stat(MYSQL *mysql)
 int STDCALL
 mysql_ping(MYSQL *mysql)
 {
+  int res;
   DBUG_ENTER("mysql_ping");
-  DBUG_RETURN(simple_command(mysql,COM_PING,0,0,0));
+  res= simple_command(mysql,COM_PING,0,0,0);
+  if (res == CR_SERVER_LOST && mysql->reconnect)
+    res= simple_command(mysql,COM_PING,0,0,0);
+  DBUG_RETURN(res);
 }
 
 

From e1c8d9c9b4f4d7592f088e38a8374ab844cd51ee Mon Sep 17 00:00:00 2001
From: unknown <dlenev@mysql.com>
Date: Thu, 16 Feb 2006 16:19:24 +0300
Subject: [PATCH 017/103] Fix for bug #16593 "Deadlock or crash in stress test
 for case where trigger starts trigger".

In short, the deadlock/crash happened when execution of statement, which used
stored functions or activated triggers, coincided with alteration of the
tables used by these functions or triggers (in highly concurrent environment).

Bug was caused by the incorrect handling of tables from prelocked set in
open_tables() functions in situations when refresh happened. This fix replaces
old smart but not very robust way of handling tables after refresh (which was
closing only old tables), with new one which simply closes all tables opened so
far and restarts open_tables().
Also fixed handling of temporary tables in close_tables_for_reopen().

No test case present since bug manifests itself only in concurrent environment.


sql/mysql_priv.h:
  In order to handle correctly case when table list completely consists from tables
  from prelocked set close_tables_for_reopen() have to accept table list as in/out
  parameter.
sql/sql_base.cc:
  open_tables():
    Removed part of comment  which was out of date.
    Changed handling of case when refresh happens during opening of tables, now
    instead of having code which decides for each table if it should be closed
    we simply close all tables. Old code also incorrectly handled tables from
    prelocked set in this situation which resulted in bug #16593 "Deadlock or
    crash in stress test for case where triggers starting trigger".
  close_tables_for_reopen():
    Now we correctly handle the case when table list completely consists from
    tables from prelocked set. Also now we simply close all tables instead
    leaving temporary tables non-closed (such approach allows easily handle
    correctly tables from prelocked set).
sql/sql_prepare.cc:
  In order to handle correctly case when table list completely consists from tables
  from prelocked set close_tables_for_reopen() have to accept table list as in/out
  parameter.
sql/sql_update.cc:
  In order to handle correctly case when table list completely consists from tables
  from prelocked set close_tables_for_reopen() have to accept table list as in/out
  parameter.
---
 sql/mysql_priv.h   |  2 +-
 sql/sql_base.cc    | 84 +++++++++++++++-------------------------------
 sql/sql_prepare.cc |  2 +-
 sql/sql_update.cc  |  4 +--
 4 files changed, 31 insertions(+), 61 deletions(-)

diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index ca2cda0f7c6..6908f2b9049 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -981,7 +981,7 @@ void free_io_cache(TABLE *entry);
 void intern_close_table(TABLE *entry);
 bool close_thread_table(THD *thd, TABLE **table_ptr);
 void close_temporary_tables(THD *thd);
-void close_tables_for_reopen(THD *thd, TABLE_LIST *tables);
+void close_tables_for_reopen(THD *thd, TABLE_LIST **tables);
 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
                                uint offset_to_list,
                                const char *db_name,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 9d1720cc527..37d4c80a0d0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -1982,22 +1982,11 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
     statement for which table list for prelocking is already built, let
     us cache routines and try to build such table list.
 
-    NOTE: We can't delay prelocking until we will met some sub-statement
-    which really uses tables, since this will imply that we have to restore
-    its table list to be able execute it in some other context.
-    And current views implementation assumes that view tables are added to
-    global table list only once during PS preparing/first SP execution.
-    Also locking at earlier stage is probably faster altough may decrease
-    concurrency a bit.
-
     NOTE: We will mark statement as requiring prelocking only if we will
     have non empty table list. But this does not guarantee that in prelocked
     mode we will have some locked tables, because queries which use only
     derived/information schema tables and views possible. Thus "counter"
     may be still zero for prelocked statement...
-
-    NOTE: The above notes may be out of date. Please wait for psergey to
-          document new prelocked behavior.
   */
 
   if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
@@ -2083,48 +2072,23 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
 
       if (refresh)				// Refresh in progress
       {
-	/* close all 'old' tables used by this thread */
-	pthread_mutex_lock(&LOCK_open);
-	// if query_id is not reset, we will get an error
-	// re-opening a temp table
-	thd->version=refresh_version;
-	TABLE **prev_table= &thd->open_tables;
-	bool found=0;
-	for (TABLE_LIST *tmp= *start; tmp; tmp= tmp->next_global)
-	{
-	  /* Close normal (not temporary) changed tables */
-	  if (tmp->table && ! tmp->table->s->tmp_table)
-	  {
-	    if (tmp->table->s->version != refresh_version ||
-		! tmp->table->db_stat)
-	    {
-	      VOID(hash_delete(&open_cache,(byte*) tmp->table));
-	      tmp->table=0;
-	      found=1;
-	    }
-	    else
-	    {
-	      *prev_table= tmp->table;		// Relink open list
-	      prev_table= &tmp->table->next;
-	    }
-	  }
-	}
-	*prev_table=0;
-	pthread_mutex_unlock(&LOCK_open);
-	if (found)
-	  VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
         /*
-          Let us prepare for recalculation of set of prelocked tables.
-          First we pretend that we have finished calculation which we
-          were doing currently. Then we restore list of tables to be
-          opened and set of used routines to the state in which they were
-          before first open_tables() call for this statement (i.e. before
-          we have calculated current set of tables for prelocking).
+          We have met name-locked or old version of table. Now we have
+          to close all tables which are not up to date. We also have to
+          throw away set of prelocked tables (and thus close tables from
+          this set that were open by now) since it possible that one of
+          tables which determined its content was changed.
+
+          Instead of implementing complex/non-robust logic mentioned
+          above we simply close and then reopen all tables.
+
+          In order to prepare for recalculation of set of prelocked tables
+          we pretend that we have finished calculation which we were doing
+          currently.
         */
         if (query_tables_last_own)
           thd->lex->mark_as_requiring_prelocking(query_tables_last_own);
-        thd->lex->chop_off_not_own_tables();
-        sp_remove_not_own_routines(thd->lex);
+        close_tables_for_reopen(thd, start);
 	goto restart;
       }
       result= -1;				// Fatal error
@@ -2335,7 +2299,7 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
       break;
     if (!need_reopen)
       DBUG_RETURN(-1);
-    close_tables_for_reopen(thd, tables);
+    close_tables_for_reopen(thd, &tables);
   }
   DBUG_RETURN(0);
 }
@@ -2372,7 +2336,7 @@ bool open_and_lock_tables(THD *thd, TABLE_LIST *tables)
       break;
     if (!need_reopen)
       DBUG_RETURN(-1);
-    close_tables_for_reopen(thd, tables);
+    close_tables_for_reopen(thd, &tables);
   }
   if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
       (thd->fill_derived_tables() &&
@@ -2600,18 +2564,24 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
 
   SYNOPSIS
     close_tables_for_reopen()
-      thd     Thread context
-      tables  List of tables which we were trying to open and lock
+      thd    in     Thread context
+      tables in/out List of tables which we were trying to open and lock
 
 */
 
-void close_tables_for_reopen(THD *thd, TABLE_LIST *tables)
+void close_tables_for_reopen(THD *thd, TABLE_LIST **tables)
 {
+  /*
+    If table list consists only from tables from prelocking set, table list
+    for new attempt should be empty, so we have to update list's root pointer.
+  */
+  if (thd->lex->first_not_own_table() == *tables)
+    *tables= 0;
   thd->lex->chop_off_not_own_tables();
   sp_remove_not_own_routines(thd->lex);
-  for (TABLE_LIST *tmp= tables; tmp; tmp= tmp->next_global)
-    if (tmp->table && !tmp->table->s->tmp_table)
-      tmp->table= 0;
+  for (TABLE_LIST *tmp= *tables; tmp; tmp= tmp->next_global)
+    tmp->table= 0;
+  mark_used_tables_as_free_for_reuse(thd, thd->temporary_tables);
   close_thread_tables(thd);
 }
 
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 68f033f78fe..b0c4cef6e87 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1135,7 +1135,7 @@ static int mysql_test_update(Prepared_statement *stmt,
       break;
     if (!need_reopen)
       goto error;
-    close_tables_for_reopen(thd, table_list);
+    close_tables_for_reopen(thd, &table_list);
   }
 
   /*
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 2ff8a4bc244..324623a61ca 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -158,7 +158,7 @@ int mysql_update(THD *thd,
       break;
     if (!need_reopen)
       DBUG_RETURN(1);
-    close_tables_for_reopen(thd, table_list);
+    close_tables_for_reopen(thd, &table_list);
   }
 
   if (mysql_handle_derived(thd->lex, &mysql_derived_prepare) ||
@@ -813,7 +813,7 @@ reopen_tables:
     for (TABLE_LIST *tbl= table_list; tbl; tbl= tbl->next_global)
       tbl->cleanup_items();
 
-    close_tables_for_reopen(thd, table_list);
+    close_tables_for_reopen(thd, &table_list);
     goto reopen_tables;
   }
 

From cb71a3051a0bcf7ed8b0bf05f4933b96f85c34e5 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 21:34:01 +0100
Subject: [PATCH 018/103] Use --system for unix command's

---
 mysql-test/t/mysqldump.test | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index e54bf6386c5..4e9d6f5683e 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -647,7 +647,7 @@ select '------ Testing with illegal table names ------' as test_sequence ;
 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\t1" 2>&1
  
 --error 6
---exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\\\t1" 2>&1
+--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\\\\\t1" 2>&1
 
 --error 6
 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "t\1" 2>&1
@@ -830,11 +830,11 @@ DROP TABLE t1, t2;
 # Bugs #9136, #12917: problems with --defaults-extra-file option
 #
 
---exec echo "[mysqltest1]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf
---exec echo "port=1234" >> $MYSQL_TEST_DIR/var/tmp/tmp.cnf
+--system echo "[mysqltest1]" > $MYSQL_TEST_DIR/var/tmp/tmp.cnf
+--system echo "port=1234" >> $MYSQL_TEST_DIR/var/tmp/tmp.cnf
 --exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1
 --exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQL_TEST_DIR/var/tmp/tmp.cnf mysqltest1 mysqltest1
---exec rm $MYSQL_TEST_DIR/var/tmp/tmp.cnf
+--system rm $MYSQL_TEST_DIR/var/tmp/tmp.cnf
 
 #
 # Test of fix to BUG 12597

From c54809fc59de56a452eb2e4736f28e8866e2c720 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 22:06:07 +0100
Subject: [PATCH 019/103] Don't disable warnings when dropping objects that
 should exist

---
 mysql-test/t/mysqldump.test | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 4e9d6f5683e..d5e48387203 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -950,15 +950,16 @@ set time_zone=default;
 #
 --disable_warnings
 DROP TABLE IF EXISTS `t1 test`;
+DROP TABLE IF EXISTS `t2 test`;
+--enable_warnings
+
 CREATE TABLE `t1 test` (
   `a1` int(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
-DROP TABLE IF EXISTS `t2 test`;
 CREATE TABLE `t2 test` (
   `a2` int(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
---enable_warnings
 
 DELIMITER //;
 CREATE TRIGGER `test trig` BEFORE INSERT ON `t1 test` FOR EACH ROW BEGIN
@@ -973,11 +974,10 @@ SELECT * FROM `t2 test`;
 # quoted
 --exec $MYSQL_DUMP --skip-comments --compatible=ansi --triggers test
 
---disable_warnings
 DROP TRIGGER `test trig`;
 DROP TABLE `t1 test`;
 DROP TABLE `t2 test`;
---enable_warnings
+
 #
 # BUG# 12838 mysqldump -x with views exits with error 
 #

From 2c07e96ca0ae4d790314c83640d89c5ed60eb194 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 22:10:25 +0100
Subject: [PATCH 020/103] Use the tmp dir of MYSQLTEST_VARDIR

---
 mysql-test/r/sp.result |  4 ++--
 mysql-test/t/sp.test   | 12 ++++++------
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index d56cf086cdf..fb4e25f6d18 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -539,7 +539,7 @@ drop procedure if exists into_outfile|
 create procedure into_outfile(x char(16), y int)
 begin
 insert into test.t1 values (x, y);
-select * into outfile "/tmp/spout" from test.t1;
+select * into outfile "../tmp/spout" from test.t1;
 insert into test.t1 values (concat(x, "2"), y+2);
 end|
 call into_outfile("ofile", 1)|
@@ -549,7 +549,7 @@ drop procedure if exists into_dumpfile|
 create procedure into_dumpfile(x char(16), y int)
 begin
 insert into test.t1 values (x, y);
-select * into dumpfile "/tmp/spdump" from test.t1 limit 1;
+select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
 insert into test.t1 values (concat(x, "2"), y+2);
 end|
 call into_dumpfile("dfile", 1)|
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index a1eba73635e..9279c861e94 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -702,13 +702,13 @@ drop procedure if exists into_outfile|
 create procedure into_outfile(x char(16), y int)
 begin
   insert into test.t1 values (x, y);
-  select * into outfile "/tmp/spout" from test.t1;
+  select * into outfile "../tmp/spout" from test.t1;
   insert into test.t1 values (concat(x, "2"), y+2);
 end|
 
-system rm -f /tmp/spout|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spout
 call into_outfile("ofile", 1)|
-system rm -f /tmp/spout|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spout
 delete from t1|
 drop procedure into_outfile|
 
@@ -718,13 +718,13 @@ drop procedure if exists into_dumpfile|
 create procedure into_dumpfile(x char(16), y int)
 begin
   insert into test.t1 values (x, y);
-  select * into dumpfile "/tmp/spdump" from test.t1 limit 1;
+  select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
   insert into test.t1 values (concat(x, "2"), y+2);
 end|
 
-system rm -f /tmp/spdump|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spdump
 call into_dumpfile("dfile", 1)|
-system rm -f /tmp/spdump|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spdump
 delete from t1|
 drop procedure into_dumpfile|
 

From 1be9ba8ae8295e753d4516b4faf42ba0b02dca25 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 16 Feb 2006 23:05:15 +0100
Subject: [PATCH 021/103] #define popen(A,B) _popen((A),(B))

include/config-win.h:
  Fix strange "double" define for popen.
---
 include/config-win.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/config-win.h b/include/config-win.h
index b2bd63efc30..cccd660efec 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -211,7 +211,7 @@ typedef uint rf_SetTimer;
 #define my_sigset(A,B) signal((A),(B))
 #define finite(A) _finite(A)
 #define sleep(A)  Sleep((A)*1000)
-#define popen(A) popen(A,B) _popen((A),(B))
+#define popen(A,B) _popen((A),(B))
 #define pclose(A) _pclose(A)
 
 #ifndef __BORLANDC__

From bf840404581d81fbb351f976a08a124d9be0b624 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot@deer.(none)>
Date: Fri, 17 Feb 2006 10:52:32 +0400
Subject: [PATCH 022/103] WL#2645 (CHECK TABLE FOR UPGRADE) necessary
 implementation in the server mysql_upgrade script added

client/mysqlcheck.c:
  --check-upgrade option added
include/my_base.h:
  errcode added
include/myisam.h:
  option added
scripts/Makefile.am:
  mysql_upgrade script added
sql/handler.cc:
  checks for old types/bugs added
sql/handler.h:
  declarations regarding checks for upgrade
sql/lex.h:
  sym added
sql/share/errmsg.txt:
  error message added
sql/slave.cc:
  now ha_repair is for public use
sql/sql_table.cc:
  upgrade in ha_repair implemented
sql/sql_yacc.yy:
  CHECK ... FOR UPGRADE added to syntax
---
 client/mysqlcheck.c      |  10 ++-
 include/my_base.h        |   3 +-
 include/myisam.h         |   1 +
 scripts/Makefile.am      |   3 +
 scripts/mysql_upgrade.sh | 185 +++++++++++++++++++++++++++++++++++++++
 sql/handler.cc           | 152 ++++++++++++++++++++++++++++++++
 sql/handler.h            |  22 +++++
 sql/lex.h                |   1 +
 sql/share/errmsg.txt     |   2 +
 sql/slave.cc             |   2 +-
 sql/sql_table.cc         |  34 ++++++-
 sql/sql_yacc.yy          |   4 +-
 12 files changed, 412 insertions(+), 7 deletions(-)
 create mode 100644 scripts/mysql_upgrade.sh

diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index f6fa15bb1c8..7ddfbbd7211 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -34,7 +34,7 @@ static my_bool opt_alldbs = 0, opt_check_only_changed = 0, opt_extended = 0,
                opt_compress = 0, opt_databases = 0, opt_fast = 0,
                opt_medium_check = 0, opt_quick = 0, opt_all_in_1 = 0,
                opt_silent = 0, opt_auto_repair = 0, ignore_errors = 0,
-               tty_password = 0, opt_frm = 0;
+               tty_password = 0, opt_frm = 0, opt_upgrade= 0;
 static uint verbose = 0, opt_mysql_port=0;
 static my_string opt_mysql_unix_port = 0;
 static char *opt_password = 0, *current_user = 0, 
@@ -78,6 +78,9 @@ static struct my_option my_long_options[] =
   {"check-only-changed", 'C',
    "Check only tables that have changed since last check or haven't been closed properly.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"check-upgrade", 'g',
+   "Check tables for version dependent changes.May be used with auto-repair to correct tables requiring version dependent updates.",
+   0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
    (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
    0, 0, 0},
@@ -268,6 +271,10 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
   case 'r':
     what_to_do = DO_REPAIR;
     break;
+  case 'g':
+    what_to_do= DO_CHECK;
+    opt_upgrade= 1;
+    break;
   case 'W':
 #ifdef __WIN__
     opt_protocol = MYSQL_PROTOCOL_PIPE;
@@ -525,6 +532,7 @@ static int handle_request_for_tables(char *tables, uint length)
     if (opt_medium_check)       end = strmov(end, " MEDIUM"); /* Default */
     if (opt_extended)           end = strmov(end, " EXTENDED");
     if (opt_check_only_changed) end = strmov(end, " CHANGED");
+    if (opt_upgrade)            end = strmov(end, " FOR UPGRADE");
     break;
   case DO_REPAIR:
     op = "REPAIR";
diff --git a/include/my_base.h b/include/my_base.h
index 77cd60fda92..c82ecd06627 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -346,8 +346,9 @@ enum ha_base_keytype {
 #define HA_ERR_NO_CONNECTION     157  /* Could not connect to storage engine */
 #define HA_ERR_NULL_IN_SPATIAL   158  /* NULLs are not supported in spatial index */
 #define HA_ERR_TABLE_DEF_CHANGED 159  /* The table changed in storage engine */
+#define HA_ERR_TABLE_NEEDS_UPGRADE 160  /* The table changed in storage engine */
 
-#define HA_ERR_LAST              159  /*Copy last error nr.*/
+#define HA_ERR_LAST              160  /*Copy last error nr.*/
 /* Add error numbers before HA_ERR_LAST and change it accordingly. */
 #define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
 
diff --git a/include/myisam.h b/include/myisam.h
index 96c1e7e192e..321952dcf4c 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -368,6 +368,7 @@ extern uint mi_get_pointer_length(ulonglong file_length, uint def);
 */
 
 #define TT_USEFRM               1
+#define TT_FOR_UPGRADE          2
 
 #define O_NEW_INDEX	1		/* Bits set in out_flag */
 #define O_NEW_DATA	2
diff --git a/scripts/Makefile.am b/scripts/Makefile.am
index 394e24c7c32..0f68b484f41 100644
--- a/scripts/Makefile.am
+++ b/scripts/Makefile.am
@@ -32,6 +32,7 @@ bin_SCRIPTS =		@server_scripts@ \
 			mysqldumpslow \
 			mysql_explain_log \
 			mysql_tableinfo \
+			mysql_upgrade \
 			mysqld_multi \
 			mysql_create_system_tables
 
@@ -59,6 +60,7 @@ EXTRA_SCRIPTS =		make_binary_distribution.sh \
 			mysql_explain_log.sh \
 			mysqld_multi.sh \
 			mysql_tableinfo.sh \
+			mysql_upgrade.sh \
 			mysqld_safe.sh \
 			mysql_create_system_tables.sh
 
@@ -87,6 +89,7 @@ CLEANFILES =		@server_scripts@ \
 			mysqldumpslow \
 			mysql_explain_log \
 			mysql_tableinfo \
+			mysql_upgrade \
 			mysqld_multi \
 			make_win_src_distribution \
 			mysql_create_system_tables
diff --git a/scripts/mysql_upgrade.sh b/scripts/mysql_upgrade.sh
new file mode 100644
index 00000000000..db5dc6a9516
--- /dev/null
+++ b/scripts/mysql_upgrade.sh
@@ -0,0 +1,185 @@
+#!/bin/sh
+# Copyright (C) 2002-2003 MySQL AB
+# For a more info consult the file COPYRIGHT distributed with this file.
+
+# Runs mysqlcheck --check-upgrade in case it has not been done on this
+# major MySQL version
+
+# This script should always be run when upgrading from one major version
+# to another (ie: 4.1 -> 5.0 -> 5.1)
+
+#
+# Note that in most cases one have to use '--password' as
+# arguments as these needs to be passed on to the mysqlcheck command
+
+
+user=root
+
+case "$1" in
+    --no-defaults|--defaults-file=*|--defaults-extra-file=*)
+      defaults="$1"; shift
+      ;;
+esac
+
+parse_arguments() {
+  # We only need to pass arguments through to the server if we don't
+  # handle them here.  So, we collect unrecognized options (passed on
+  # the command line) into the args variable.
+  pick_args=
+  if test "$1" = PICK-ARGS-FROM-ARGV
+  then
+    pick_args=1
+    shift
+  fi
+
+  for arg do
+    case "$arg" in
+      --basedir=*) MY_BASEDIR_VERSION=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
+      --user=*) user=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
+      --ldata=*|--data=*|--datadir=*) DATADIR=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
+      --force) force=1 ;;
+      --verbose) verbose=1 ;;
+      *)
+        if test -n "$pick_args"
+        then
+          # This sed command makes sure that any special chars are quoted,
+          # so the arg gets passed exactly to the server.
+          args="$args "`echo "$arg" | sed -e 's,\([^a-zA-Z0-9_.=-]\),\\\\\1,g'`
+        fi
+        ;;
+    esac
+  done
+}
+
+#
+# Find where my_print_defaults is
+#
+
+find_my_print_defaults () {
+  if test -x ./bin/my_print_defaults
+  then
+    print_defaults="./bin/my_print_defaults"
+  elif test -x ./extra/my_print_defaults
+  then
+    print_defaults="./extra/my_print_defaults"
+  elif test -x @bindir@/my_print_defaults
+  then
+    print_defaults="@bindir@/my_print_defaults"
+  elif test -x @bindir@/mysql_print_defaults
+  then
+    print_defaults="@bindir@/mysql_print_defaults"
+  else
+    print_defaults="my_print_defaults"
+  fi
+}
+
+find_my_print_defaults
+
+# Get first arguments from the my.cfg file, groups [mysqld] and
+# [mysql_upgrade], and then merge with the command line arguments
+
+args=
+DATADIR=
+bindir=
+MY_BASEDIR_VERSION=
+verbose=0
+force=0
+
+parse_arguments `$print_defaults $defaults mysqld mysql_upgrade`
+parse_arguments PICK-ARGS-FROM-ARGV "$@"
+
+#
+# Try to find where binaries are installed
+#
+
+MY_PWD=`pwd`
+# Check for the directories we would expect from a binary release install
+if test -z "$MY_BASEDIR_VERSION"
+then
+  if test -f ./share/mysql/english/errmsg.sys -a -x ./bin/mysqld
+  then
+    MY_BASEDIR_VERSION=$MY_PWD            # Where bin, share and data are
+    bindir="$MY_BASEDIR_VERSION/bin"
+  # Check for the directories we would expect from a source install
+  elif test -f ./share/mysql/english/errmsg.sys -a -x ./libexec/mysqld
+  then
+    MY_BASEDIR_VERSION=$MY_PWD            # Where libexec, share and var are
+    bindir="$MY_BASEDIR_VERSION/bin"
+# Since we didn't find anything, used the compiled-in defaults
+  else
+    MY_BASEDIR_VERSION=@prefix@
+    bindir=@bindir@
+  fi
+else
+  bindir="$MY_BASEDIR_VERSION/bin"
+fi
+
+#
+# Try to find the data directory
+#
+
+if test -z "$DATADIR"
+then
+  # Try where the binary installs put it
+  if test -d $MY_BASEDIR_VERSION/data/mysql
+  then
+    DATADIR=$MY_BASEDIR_VERSION/data
+  # Next try where the source installs put it
+  elif test -d $MY_BASEDIR_VERSION/var/mysql
+  then
+    DATADIR=$MY_BASEDIR_VERSION/var
+  # Or just give up and use our compiled-in default
+  else
+    DATADIR=@localstatedir@
+  fi
+fi
+
+if test ! -x "$bindir/mysqlcheck"
+then
+  echo "Can't find program '$bindir/mysqlcheck'"
+  echo "Please restart with --basedir=mysql-install-directory"
+  exit 1
+fi
+
+if test ! -f "$DATADIR/mysql/user.frm"
+then
+  echo "Can't find data directory. Please restart with --datadir=path-to-data-dir"
+  exit 1
+fi
+
+CHECK_FILE=$DATADIR/mysql_upgrade.info
+
+if test -f $CHECK_FILE -a $force = 0
+then
+  version=`cat $CHECK_FILE`
+  if test "$version" = "@MYSQL_BASE_VERSION@"
+  then
+    if test $verbose = 1
+    then
+       echo "mysql_upgrade already done for this version"
+    fi
+    $bindir/mysql_fix_privilege_tables --silent $args
+    exit 0
+  fi
+fi
+
+#
+# Run the upgrade
+#
+
+check_args="--check-upgrade --all-databases --auto-repair --user=$user"
+
+if test $verbose = 1
+then
+  echo "Running $bindir/mysqlcheck $args $check_args"
+fi
+
+$bindir/mysqlcheck $check_args $args
+if [ $? = 0 ]
+then
+  # Remember base version so that we don't run this script again on the
+  # same base version
+  echo "@MYSQL_BASE_VERSION@" > $CHECK_FILE
+fi
+
+$bindir/mysql_fix_privilege_tables --silent --user=$user $args
diff --git a/sql/handler.cc b/sql/handler.cc
index 4e128eb5938..006a0eb2407 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -425,6 +425,7 @@ static int ha_init_errors(void)
   SETMSG(HA_ERR_TABLE_EXIST,            ER(ER_TABLE_EXISTS_ERROR));
   SETMSG(HA_ERR_NO_CONNECTION,          "Could not connect to storage engine");
   SETMSG(HA_ERR_TABLE_DEF_CHANGED,      ER(ER_TABLE_DEF_CHANGED));
+  SETMSG(HA_ERR_TABLE_NEEDS_UPGRADE,    ER(ER_TABLE_NEEDS_UPGRADE));
 
   /* Register the error messages for use with my_error(). */
   return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -1795,6 +1796,9 @@ void handler::print_error(int error, myf errflag)
     my_error(ER_NO_SUCH_TABLE, MYF(0), db, table->alias);
     break;
   }
+  case HA_ERR_TABLE_NEEDS_UPGRADE:
+    textno=ER_TABLE_NEEDS_UPGRADE;
+    break;
   default:
     {
       /* The error was "unknown" to this function.
@@ -1836,6 +1840,103 @@ bool handler::get_error_message(int error, String* buf)
 }
 
 
+int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt)
+{
+  KEY *keyinfo, *keyend;
+  KEY_PART_INFO *keypart, *keypartend;
+
+  if (!table->s->mysql_version)
+  {
+    /* check for blob-in-key error */
+    keyinfo= table->key_info;
+    keyend= table->key_info + table->s->keys;
+    for (; keyinfo < keyend; keyinfo++)
+    {
+      keypart= keyinfo->key_part;
+      keypartend= keypart + keyinfo->key_parts;
+      for (; keypart < keypartend; keypart++)
+      {
+        if (!keypart->fieldnr)
+          continue;
+        Field *field= table->field[keypart->fieldnr-1];
+        if (field->type() == FIELD_TYPE_BLOB)
+        {
+          if (check_opt->sql_flags & TT_FOR_UPGRADE)
+            check_opt->flags= T_MEDIUM;
+          return HA_ADMIN_NEEDS_CHECK;
+        }
+      }
+    }
+  }
+  return check_for_upgrade(check_opt);
+}
+
+
+int handler::check_old_types()
+{
+  Field** field;
+
+  if (!table->s->mysql_version)
+  {
+    /* check for bad DECIMAL field */
+    for (field= table->field; (*field); field++)
+    {
+      if ((*field)->type() == FIELD_TYPE_NEWDECIMAL)
+      {
+        return HA_ADMIN_NEEDS_ALTER;
+      }
+    }
+  }
+  return 0;
+}
+
+
+static bool update_frm_version(TABLE *table, bool needs_lock)
+{
+  char path[FN_REFLEN];
+  File file;
+  int result= 1;
+  DBUG_ENTER("update_frm_version");
+
+  if (table->s->mysql_version != MYSQL_VERSION_ID)
+    DBUG_RETURN(0);
+
+  strxnmov(path, sizeof(path)-1, mysql_data_home, "/", table->s->db, "/",
+           table->s->table_name, reg_ext, NullS);
+  if (!unpack_filename(path, path))
+    DBUG_RETURN(1);
+
+  if (needs_lock)
+    pthread_mutex_lock(&LOCK_open);
+
+  if ((file= my_open(path, O_RDWR|O_BINARY, MYF(MY_WME))) >= 0)
+  {
+    uchar version[4];
+    char *key= table->s->table_cache_key;
+    uint key_length= table->s->key_length;
+    TABLE *entry;
+    HASH_SEARCH_STATE state;
+
+    int4store(version, MYSQL_VERSION_ID);
+
+    if ((result= my_pwrite(file,(byte*) version,4,51L,MYF_RW)))
+      goto err;
+
+    for (entry=(TABLE*) hash_first(&open_cache,(byte*) key,key_length, &state);
+         entry;
+         entry= (TABLE*) hash_next(&open_cache,(byte*) key,key_length, &state))
+      entry->s->mysql_version= MYSQL_VERSION_ID;
+  }
+err:
+  if (file >= 0)
+    VOID(my_close(file,MYF(MY_WME)));
+  if (needs_lock)
+    pthread_mutex_unlock(&LOCK_open);
+  DBUG_RETURN(result);
+}
+
+
+
 /* Return key if error because of duplicated keys */
 
 uint handler::get_dup_key(int error)
@@ -1903,6 +2004,57 @@ int handler::rename_table(const char * from, const char * to)
   return error;
 }
 
+
+/*
+   Performs checks upon the table.
+
+   SYNOPSIS
+   check()
+   thd                thread doing CHECK TABLE operation
+   check_opt          options from the parser
+
+   NOTES
+
+   RETURN
+   HA_ADMIN_OK                 Successful upgrade
+   HA_ADMIN_NEEDS_UPGRADE      Table has structures requiring upgrade
+   HA_ADMIN_NEEDS_ALTER        Table has structures requiring ALTER TABLE
+   HA_ADMIN_NOT_IMPLEMENTED
+*/
+
+int handler::ha_check(THD *thd, HA_CHECK_OPT *check_opt)
+{
+  int error;
+
+  if ((table->s->mysql_version >= MYSQL_VERSION_ID) &&
+      (check_opt->sql_flags & TT_FOR_UPGRADE))
+    return 0;
+
+  if (table->s->mysql_version < MYSQL_VERSION_ID)
+  {
+    if ((error= check_old_types()))
+      return error;
+    error= ha_check_for_upgrade(check_opt);
+    if (error && (error != HA_ADMIN_NEEDS_CHECK))
+      return error;
+    if (!error && (check_opt->sql_flags & TT_FOR_UPGRADE))
+      return 0;
+  }
+  if ((error= check(thd, check_opt)))
+    return error;
+  return update_frm_version(table, 0);
+}
+
+
+int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
+{
+  int result;
+  if ((result= repair(thd, check_opt)))
+    return result;
+  return update_frm_version(table, 0);
+}
+
+
 /*
   Tell the storage engine that it is allowed to "disable transaction" in the
   handler. It is a hint that ACID is not required - it is used in NDB for
diff --git a/sql/handler.h b/sql/handler.h
index 91c5be9ba39..24cb9646d36 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -46,6 +46,9 @@
 #define HA_ADMIN_TRY_ALTER       -7
 #define HA_ADMIN_WRONG_CHECKSUM  -8
 #define HA_ADMIN_NOT_BASE_TABLE  -9
+#define HA_ADMIN_NEEDS_UPGRADE  -10
+#define HA_ADMIN_NEEDS_ALTER    -11
+#define HA_ADMIN_NEEDS_CHECK    -12
 
 /* Bits in table_flags() to show what database can do */
 
@@ -702,10 +705,26 @@ public:
   { return HA_ERR_WRONG_COMMAND; }
 
   virtual void update_create_info(HA_CREATE_INFO *create_info) {}
+protected:
+  /* to be implemented in handlers */
 
   /* admin commands - called from mysql_admin_table */
   virtual int check(THD* thd, HA_CHECK_OPT* check_opt)
   { return HA_ADMIN_NOT_IMPLEMENTED; }
+
+  /*
+     in these two methods check_opt can be modified
+     to specify CHECK option to use to call check()
+     upon the table
+  */
+  virtual int check_for_upgrade(HA_CHECK_OPT *check_opt)
+  { return 0; }
+public:
+  int ha_check_for_upgrade(HA_CHECK_OPT *check_opt);
+  int check_old_types();
+  /* to be actually called to get 'check()' functionality*/
+  int ha_check(THD *thd, HA_CHECK_OPT *check_opt);
+   
   virtual int backup(THD* thd, HA_CHECK_OPT* check_opt)
   { return HA_ADMIN_NOT_IMPLEMENTED; }
   /*
@@ -714,8 +733,11 @@ public:
   */
   virtual int restore(THD* thd, HA_CHECK_OPT* check_opt)
   { return HA_ADMIN_NOT_IMPLEMENTED; }
+protected:
   virtual int repair(THD* thd, HA_CHECK_OPT* check_opt)
   { return HA_ADMIN_NOT_IMPLEMENTED; }
+public:
+  int ha_repair(THD* thd, HA_CHECK_OPT* check_opt);
   virtual int optimize(THD* thd, HA_CHECK_OPT* check_opt)
   { return HA_ADMIN_NOT_IMPLEMENTED; }
   virtual int analyze(THD* thd, HA_CHECK_OPT* check_opt)
diff --git a/sql/lex.h b/sql/lex.h
index efcb9b84f81..1acfbaac211 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -514,6 +514,7 @@ static SYMBOL symbols[] = {
   { "UNSIGNED",		SYM(UNSIGNED)},
   { "UNTIL",		SYM(UNTIL_SYM)},
   { "UPDATE",		SYM(UPDATE_SYM)},
+  { "UPGRADE",          SYM(UPGRADE_SYM)},
   { "USAGE",		SYM(USAGE)},
   { "USE",		SYM(USE_SYM)},
   { "USER",		SYM(USER)},
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 8017ba3ef9f..378e205b29a 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5607,3 +5607,5 @@ ER_SP_PROC_TABLE_CORRUPT
 	eng "Failed to load routine %s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)"
 ER_SP_WRONG_NAME 42000
 	eng "Incorrect routine name '%-.64s'"
+ER_TABLE_NEEDS_UPGRADE
+         eng "Table upgrade required. Please do \"REPAIR TABLE `%-.32s`\" to fix it!"
diff --git a/sql/slave.cc b/sql/slave.cc
index 3795cbaf7c0..fa7ccc4427d 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -1622,7 +1622,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
   save_vio = thd->net.vio;
   thd->net.vio = 0;
   /* Rebuild the index file from the copied data file (with REPAIR) */
-  error=file->repair(thd,&check_opt) != 0;
+  error=file->ha_repair(thd,&check_opt) != 0;
   thd->net.vio = save_vio;
   if (error)
     my_error(ER_INDEX_REBUILD, MYF(0), tables.table->s->table_name);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index b1a24543a6b..e48ca8636ae 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2328,7 +2328,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
       open_for_modify= 0;
     }
 
-    if (table->table->s->crashed && operator_func == &handler::check)
+    if (table->table->s->crashed && operator_func == &handler::ha_check)
     {
       protocol->prepare_for_resend();
       protocol->store(table_name, system_charset_info);
@@ -2340,6 +2340,21 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
         goto err;
     }
 
+    if (operator_func == &handler::ha_repair)
+    {
+      if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
+          (table->table->file->ha_check_for_upgrade(check_opt) ==
+           HA_ADMIN_NEEDS_ALTER))
+      {
+        close_thread_tables(thd);
+        tmp_disable_binlog(thd); // binlogging is done by caller if wanted
+        result_code= mysql_recreate_table(thd, table, 0);
+        reenable_binlog(thd);
+        goto send_result;
+      }
+
+    }
+
     result_code = (table->table->file->*operator_func)(thd, check_opt);
 
 send_result:
@@ -2466,6 +2481,19 @@ send_result_message:
       break;
     }
 
+    case HA_ADMIN_NEEDS_UPGRADE:
+    case HA_ADMIN_NEEDS_ALTER:
+    {
+      char buf[ERRMSGSIZE];
+      uint length;
+
+      protocol->store(STRING_WITH_LEN("error"), system_charset_info);
+      length=my_snprintf(buf, ERRMSGSIZE, ER(ER_TABLE_NEEDS_UPGRADE), table->table_name);
+      protocol->store(buf, length, system_charset_info);
+      fatal_error=1;
+      break;
+    }
+
     default:				// Probably HA_ADMIN_INTERNAL_ERROR
       {
         char buf[ERRMSGSIZE+20];
@@ -2535,7 +2563,7 @@ bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
                                 test(check_opt->sql_flags & TT_USEFRM),
                                 HA_OPEN_FOR_REPAIR,
 				&prepare_for_repair,
-				&handler::repair, 0));
+				&handler::ha_repair, 0));
 }
 
 
@@ -2847,7 +2875,7 @@ bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
   DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
 				"check", lock_type,
 				0, HA_OPEN_FOR_REPAIR, 0, 0,
-				&handler::check, &view_checksum));
+				&handler::ha_check, &view_checksum));
 }
 
 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index d1ef0e08d57..3a269a3349b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -628,6 +628,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
 %token  UNTIL_SYM
 %token  UPDATE_SYM
 %token  UPDATE_SYM
+%token  UPGRADE_SYM
 %token  USAGE
 %token  USER
 %token  USE_FRM
@@ -3836,7 +3837,8 @@ mi_check_type:
 	| FAST_SYM { Lex->check_opt.flags|= T_FAST; }
 	| MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
 	| EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
-	| CHANGED  { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; };
+	| CHANGED  { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
+        | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; };
 
 optimize:
 	OPTIMIZE opt_no_write_to_binlog table_or_tables

From c61fb3c359e0712d0796937b6fed673c4409084a Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Fri, 17 Feb 2006 12:07:45 +0100
Subject: [PATCH 023/103] Replace win filename s with unix equivalent Evaluate
 commands passed to "exec" and "system" to expand any $variables before
 executing command.

client/mysqltest.c:
  do_exec, do_system
   - call do_eval on the command to be executed in order to expand any $variables
   - Remove old subst_env_var and my_popen, not needed anymore
  Rewrite 'replace_strings' into 'replace_strings_append'
   - copy whole strings instead of byte by byte copy
   - insert result directly inito dynamic_string, no need to check if out
     string needs to be realloced for every byte.
   - Add comments and DBUG_PRINT's
  New function 'fix_win_paths', detect filenames in win format that should be converted
  do_eval
  - Only set "escaped" if next char is \ or $
mysql-test/mysql-test-run.pl:
  Always pass path for DBUG .trace file in unix format
  Add search path client_debug to find debug compiled windows binaries
  Remove unused MYSQL_TEST_WINDIR and MASTER_WINMYSOCK
mysql-test/r/mysqldump.result:
  Update test result
mysql-test/t/client_xml.test:
  Use " instead of '
mysql-test/t/mysql_client_test.test:
  Remove the useless "exec echo" command
mysql-test/t/mysqltest.test:
  Escape $variables passed to --exec, that should not be evaluated in exec.
mysql-test/t/rpl000015.test:
  Remove unneccessary replace
mysql-test/t/system_mysql_db_fix.test:
  Call the "shell script" $MYSQL_FIX_SYSTEM_TABLE using --system
---
 client/mysqltest.c                    | 478 ++++++++++++++------------
 mysql-test/mysql-test-run.pl          |  36 +-
 mysql-test/r/mysqldump.result         |   2 +-
 mysql-test/t/client_xml.test          |  12 +-
 mysql-test/t/mysql_client_test.test   |   1 -
 mysql-test/t/mysqltest.test           |  36 +-
 mysql-test/t/rpl000015.test           |   2 +-
 mysql-test/t/system_mysql_db_fix.test |   3 +-
 8 files changed, 292 insertions(+), 278 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6a2a7b072de..0ff8667a7de 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -74,7 +74,6 @@
 #define MAX_QUERY     (256*1024)
 #define MAX_VAR_NAME	256
 #define MAX_COLUMNS	256
-#define PAD_SIZE	128
 #define MAX_CONS	128
 #define MAX_INCLUDE_DEPTH 16
 #define INIT_Q_LINES	  1024
@@ -275,18 +274,6 @@ typedef struct
   int alloced;
 } VAR;
 
-#if defined(__NETWARE__) || defined(__WIN__)
-/*
-  Netware doesn't proved environment variable substitution that is done
-  by the shell in unix environments. We do this in the following function:
-*/
-
-static char *subst_env_var(const char *cmd);
-static FILE *my_popen(const char *cmd, const char *mode);
-#undef popen
-#define popen(A,B) my_popen((A),(B))
-#endif /* __NETWARE__ */
-
 VAR var_reg[10];
 /*Perl/shell-like variable registers */
 HASH var_hash;
@@ -465,19 +452,19 @@ typedef struct st_pointer_array {		/* when using array-strings */
 struct st_replace;
 struct st_replace *init_replace(my_string *from, my_string *to, uint count,
 				my_string word_end_chars);
-uint replace_strings(struct st_replace *rep, my_string *start,
-		     uint *max_length, const char *from);
 void free_replace();
 static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
+static void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
+                                   const char *from, int len);
 void free_pointer_array(POINTER_ARRAY *pa);
-static int initialize_replace_buffer(void);
 static void do_eval(DYNAMIC_STRING *query_eval, const char *query);
 static void str_to_file(const char *fname, char *str, int size);
-int do_server_op(struct st_query *q,const char *op);
+
+#ifdef __WIN__
+static void free_win_path_patterns();
+#endif
 
 struct st_replace *glob_replace;
-static char *out_buff;
-static uint out_length;
 static int eval_result = 0;
 
 /* For column replace */
@@ -505,7 +492,7 @@ static void handle_no_error(struct st_query *q);
 static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
 {
   const char *p;
-  register char c;
+  register char c, next_c;
   register int escaped = 0;
   VAR* v;
   DBUG_ENTER("do_eval");
@@ -527,13 +514,19 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
       }
       break;
     case '\\':
+      next_c= *(p+1);
       if (escaped)
       {
 	escaped = 0;
 	dynstr_append_mem(query_eval, p, 1);
       }
-      else
+      else if (next_c == '\\' || next_c == '$')
+      {
+        /* Set escaped only if next char is \ or $ */
 	escaped = 1;
+      }
+      else
+	dynstr_append_mem(query_eval, p, 1);
       break;
     default:
       dynstr_append_mem(query_eval, p, 1);
@@ -609,6 +602,9 @@ static void free_used_memory()
   free_defaults(default_argv);
   mysql_server_end();
   free_re();
+#ifdef __WIN__
+  free_win_path_patterns();
+#endif
   DBUG_VOID_RETURN;
 }
 
@@ -971,17 +967,7 @@ int do_require_manager(struct st_query *query __attribute__((unused)) )
 }
 
 #ifndef EMBEDDED_LIBRARY
-int do_server_start(struct st_query *q)
-{
-  return do_server_op(q, "start");
-}
-
-int do_server_stop(struct st_query *q)
-{
-  return do_server_op(q, "stop");
-}
-
-int do_server_op(struct st_query *q, const char *op)
+static int do_server_op(struct st_query *q, const char *op)
 {
   char *p= q->first_argument;
   char com_buf[256], *com_p;
@@ -1011,6 +997,17 @@ int do_server_op(struct st_query *q, const char *op)
   q->last_argument= p;
   return 0;
 }
+
+int do_server_start(struct st_query *q)
+{
+  return do_server_op(q, "start");
+}
+
+int do_server_stop(struct st_query *q)
+{
+  return do_server_op(q, "stop");
+}
+
 #endif
 
 
@@ -1064,16 +1061,21 @@ int do_source(struct st_query *query)
     expected error array, previously set with the --error command.
     It can thus be used to execute a command that shall fail.
 
+  NOTE
+     Although mysqltest is executed from cygwin shell, the command will be
+     executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use
+     system for those commands.
 */
 
 static void do_exec(struct st_query *query)
 {
   int error;
-  DYNAMIC_STRING *ds= NULL;
   char buf[1024];
   FILE *res_file;
   char *cmd= query->first_argument;
+  DYNAMIC_STRING ds_cmd;
   DBUG_ENTER("do_exec");
+  DBUG_PRINT("enter", ("cmd: '%s'", cmd));
 
   while (*cmd && my_isspace(charset_info, *cmd))
     cmd++;
@@ -1081,24 +1083,28 @@ static void do_exec(struct st_query *query)
     die("Missing argument in exec");
   query->last_argument= query->end;
 
-  DBUG_PRINT("info", ("Executing '%s'", cmd));
+  init_dynamic_string(&ds_cmd, 0, strlen(cmd)+256, 256);
+  /* Eval the command, thus replacing all environment variables */
+  do_eval(&ds_cmd, cmd);
+  cmd= ds_cmd.str;
+
+  DBUG_PRINT("info", ("Executing '%' as '%s'",
+                      query->first_argument, cmd));
 
   if (!(res_file= popen(cmd, "r")) && query->abort_on_error)
-    die("popen(\"%s\", \"r\") failed", cmd);
+    die("popen(\"%s\", \"r\") failed", query->first_argument);
 
-  if (disable_result_log)
+  while (fgets(buf, sizeof(buf), res_file))
   {
-    while (fgets(buf, sizeof(buf), res_file))
+    if (disable_result_log)
     {
       buf[strlen(buf)-1]=0;
       DBUG_PRINT("exec_result",("%s", buf));
     }
-  }
-  else
-  {
-    ds= &ds_res;
-    while (fgets(buf, sizeof(buf), res_file))
-      replace_dynstr_append(ds, buf);
+    else
+    {
+      replace_dynstr_append(&ds_res, buf);
+    }
   }
   error= pclose(res_file);
   if (error != 0)
@@ -1107,7 +1113,7 @@ static void do_exec(struct st_query *query)
     my_bool ok= 0;
 
     if (query->abort_on_error)
-      die("command \"%s\" failed", cmd);
+      die("command \"%s\" failed", query->first_argument);
 
     DBUG_PRINT("info",
                ("error: %d, status: %d", error, status));
@@ -1122,19 +1128,19 @@ static void do_exec(struct st_query *query)
       {
         ok= 1;
         DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d",
-                            cmd, status));
+                            query->first_argument, status));
       }
     }
     if (!ok)
       die("command \"%s\" failed with wrong error: %d",
-          cmd, status);
+          query->first_argument, status);
   }
   else if (query->expected_errno[0].type == ERR_ERRNO &&
            query->expected_errno[0].code.errnum != 0)
   {
     /* Error code we wanted was != 0, i.e. not an expected success */
     die("command \"%s\" succeeded - should have failed with errno %d...",
-        cmd, query->expected_errno[0].code.errnum);
+        query->first_argument, query->expected_errno[0].code.errnum);
   }
 
   free_replace();
@@ -1346,38 +1352,49 @@ int do_modify_var(struct st_query *query, const char *name,
 }
 
 
-int do_system(struct st_query *q)
+/*
+
+  SYNOPSIS
+  do_system
+    command	called command
+
+  DESCRIPTION
+    system <command>
+
+    Eval the query to expand any $variables in the command.
+    Execute the command withe the "system" command.
+
+  NOTE
+   If mysqltest is executed from cygwin shell, the command will be
+   executed in cygwin shell. Thus commands like "rm" etc can be used.
+ */
+
+int do_system(struct st_query *command)
 {
-  DYNAMIC_STRING *ds;
-  char *p=q->first_argument;
-  VAR v;
-  var_init(&v, 0, 0, 0, 0);
-  eval_expr(&v, p, 0); /* NULL terminated */
-  ds= &ds_res;
+  DYNAMIC_STRING ds_cmd;
 
-  if (v.str_val_len)
-  {
-    char expr_buf[1024];
-    if ((uint)v.str_val_len > sizeof(expr_buf) - 1)
-      v.str_val_len = sizeof(expr_buf) - 1;
-    memcpy(expr_buf, v.str_val, v.str_val_len);
-    expr_buf[v.str_val_len] = 0;
-    DBUG_PRINT("info", ("running system command '%s'", expr_buf));
-    if (system(expr_buf))
-    {
-      if (q->abort_on_error)
-        die("system command '%s' failed", expr_buf);
-
-      /* If ! abort_on_error, log message and continue */
-      dynstr_append(ds, "system command '");
-      replace_dynstr_append(ds, expr_buf);
-      dynstr_append(ds, "' failed\n");
-    }
-  }
-  else
+  if (strlen(command->first_argument) == 0)
     die("Missing arguments to system, nothing to do!");
-  var_free(&v);
-  q->last_argument= q->end;
+
+  init_dynamic_string(&ds_cmd, 0, strlen(command->first_argument) + 64, 256);
+
+  /* Eval the system command, thus replacing all environment variables */
+  do_eval(&ds_cmd, command->first_argument);
+
+  DBUG_PRINT("info", ("running system command '%s' as '%s'",
+                      command->first_argument, ds_cmd.str));
+  if (system(ds_cmd.str))
+  {
+    if (command->abort_on_error)
+      die("system command '%s' failed", command->first_argument);
+
+    /* If ! abort_on_error, log message and continue */
+    dynstr_append(&ds_res, "system command '");
+    replace_dynstr_append(&ds_res, command->first_argument);
+    dynstr_append(&ds_res, "' failed\n");
+  }
+
+  command->last_argument= command->end;
   return 0;
 }
 
@@ -1857,8 +1874,7 @@ static void get_replace(struct st_query *q)
   if (!(glob_replace=init_replace((char**) from_array.typelib.type_names,
 				  (char**) to_array.typelib.type_names,
 				  (uint) from_array.typelib.count,
-				  word_end_chars)) ||
-      initialize_replace_buffer())
+				  word_end_chars)))
     die("Can't initialize replace from '%s'", q->query);
   free_pointer_array(&from_array);
   free_pointer_array(&to_array);
@@ -1874,7 +1890,6 @@ void free_replace()
   {
     my_free((char*) glob_replace,MYF(0));
     glob_replace=0;
-    my_free(out_buff,MYF(MY_WME));
   }
   DBUG_VOID_RETURN;
 }
@@ -2530,7 +2545,11 @@ int read_line(char *buf, int size)
 
     /* Line counting is independent of state */
     if (c == '\n')
+    {
       cur_file->lineno++;
+      if (p != buf && *(p-1) == '\r')
+        *(p-1)=0;
+    }
 
     switch(state) {
     case R_NORMAL:
@@ -2700,7 +2719,7 @@ int read_query(struct st_query** q_ptr)
     check_eol_junk(read_query_buf);
     DBUG_RETURN(1);
   }
-
+  
   DBUG_PRINT("info", ("query: %s", read_query_buf));
   if (*p == '#')
   {
@@ -3015,24 +3034,127 @@ void dump_result_to_reject_file(const char *record_file, char *buf, int size)
 }
 
 
-/* Append the string to ds, with optional replace */
+#ifdef __WIN__
 
-static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
-				      int len)
+DYNAMIC_ARRAY patterns;
+
+/*
+  init_win_path_patterns
+
+  DESCRIPTION
+   Setup string patterns that will be used to detect filenames that
+   needs to be converted from Win to Unix format
+
+*/
+
+static void init_win_path_patterns()
 {
-  if (glob_replace)
+  /* List of string patterns to match in order to find paths */
+  const char* paths[] = { "$MYSQL_TEST_DIR", "./test/", 0 };
+  int num_paths= 2;
+  int i;
+  char* p;
+
+  DBUG_ENTER("init_win_path_patterns");
+
+  my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16);
+
+  /* Loop through all paths in the array */
+  for (i= 0; i < num_paths; i++)
   {
-    len=(int) replace_strings(glob_replace, &out_buff, &out_length, val);
-    if (len == -1)
-      die("Out of memory in replace");
-    val=out_buff;
+    VAR* v;
+    if (*(paths[i]) == '$')
+    {
+      v= var_get(paths[i], 0, 0, 0);
+      p= my_strdup(v->str_val, MYF(MY_FAE));
+    }
+    else
+      p= my_strdup(paths[i], MYF(MY_FAE));
+
+    if (insert_dynamic(&patterns, (gptr) &p))
+        die(NullS);
+
+    DBUG_PRINT("info", ("p: %s", p));
+    while (*p)
+    {
+      if (*p == '/')
+        *p='\\';
+      p++;
+    }
   }
-  dynstr_append_mem(ds, val, len);
+  DBUG_VOID_RETURN;
+}
+
+static void free_win_path_patterns()
+{
+  int i= 0;
+  for (i=0 ; i < patterns.elements ; i++)
+  {
+    const char** pattern= dynamic_element(&patterns, i, const char**);
+    my_free((gptr) *pattern, MYF(0));
+  }
+  delete_dynamic(&patterns);
+}
+
+/*
+  fix_win_paths
+
+  DESCRIPTION
+   Search the string 'val' for the patterns that are known to be
+   strings that contain filenames. Convert all \ to / in the
+   filenames that are found.
+
+   Ex:
+   val = 'Error "c:\mysql\mysql-test\var\test\t1.frm" didn't exist'
+          => $MYSQL_TEST_DIR is found by strstr
+          => all \ from c:\mysql\m... until next space is converted into /
+*/
+
+static void fix_win_paths(const char* val, int len)
+{
+  uint i;
+  char *p;
+
+  DBUG_ENTER("fix_win_paths");
+  for (i= 0; i < patterns.elements; i++)
+  {
+    const char** pattern= dynamic_element(&patterns, i, const char**);
+    DBUG_PRINT("info", ("pattern: %s", *pattern));
+    /* Search for the path in string */
+    while ((p= strstr(val, *pattern)))
+    {
+      DBUG_PRINT("info", ("Found %s in val p: %s", *pattern, p));
+
+      while (*p && !my_isspace(charset_info, *p))
+      {
+        if (*p == '\\')
+          *p= '/';
+        p++;
+      }
+      DBUG_PRINT("info", ("Converted \\ to /, p: %s", p));
+    }
+  }
+  DBUG_PRINT("exit", (" val: %s, len: %d", val, len));
+  DBUG_VOID_RETURN;
+}
+#endif
+
+/* Append the string to ds, with optional replace */
+static void replace_dynstr_append_mem(DYNAMIC_STRING *ds,
+                                      const char *val,  int len)
+{
+#ifdef __WIN__
+  fix_win_paths(val, len);
+#endif
+
+  if (glob_replace)
+    replace_strings_append(glob_replace, ds, val, len);
+  else
+    dynstr_append_mem(ds, val, len);
 }
 
 
 /* Append zero-terminated string to ds, with optional replace */
-
 static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
 {
   replace_dynstr_append_mem(ds, val, strlen(val));
@@ -4353,6 +4475,10 @@ int main(int argc, char **argv)
 
   init_var_hash(&cur_con->mysql);
 
+#ifdef __WIN__
+  init_win_path_patterns();
+#endif
+
   /*
     Initialize $mysql_errno with -1, so we can
     - distinguish it from valid values ( >= 0 ) and
@@ -5414,60 +5540,57 @@ static uint replace_len(my_string str)
 }
 
 
-	/* Replace strings;  Return length of result string */
-
-uint replace_strings(REPLACE *rep, my_string *start,uint *max_length,
-		     const char *from)
+/* Replace strings while appending to ds */
+void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds,
+                            const char *str, int len)
 {
   reg1 REPLACE *rep_pos;
   reg2 REPLACE_STRING *rep_str;
-  my_string to,end,pos,new_str;
+  const char *start, *from;
+  DBUG_ENTER("replace_strings_append");
 
-  end=(to= *start) + *max_length-1;
+  start= from= str;
   rep_pos=rep+1;
   for (;;)
   {
+    /* Loop through states */
+    DBUG_PRINT("info", ("Looping through states"));
     while (!rep_pos->found)
-    {
-      rep_pos= rep_pos->next[(uchar) *from];
-      if (to == end)
-      {
-	(*max_length)+=8192;
-	if (!(new_str=my_realloc(*start,*max_length,MYF(MY_WME))))
-	  return (uint) -1;
-	to=new_str+(to - *start);
-	end=(*start=new_str)+ *max_length-1;
-      }
-      *to++= *from++;
-    }
+      rep_pos= rep_pos->next[(uchar) *from++];
+
+    /* Does this state contain a string to be replaced */
     if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string)
-      return (uint) (to - *start)-1;
-    to-=rep_str->to_offset;
-    for (pos=rep_str->replace_string; *pos ; pos++)
     {
-      if (to == end)
-      {
-	(*max_length)*=2;
-	if (!(new_str=my_realloc(*start,*max_length,MYF(MY_WME))))
-	  return (uint) -1;
-	to=new_str+(to - *start);
-	end=(*start=new_str)+ *max_length-1;
-      }
-      *to++= *pos;
+      /* No match found */
+      dynstr_append_mem(ds, start, from - start - 1);
+      DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start));
+      DBUG_VOID_RETURN;
     }
+
+    /* Found a string that needs to be replaced */
+    DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s",
+                        rep_str->found, rep_str->to_offset,
+                        rep_str->from_offset, rep_str->replace_string));
+
+    /* Append part of original string before replace string */
+    dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start);
+
+    /* Append replace string */
+    dynstr_append_mem(ds, rep_str->replace_string,
+                      strlen(rep_str->replace_string));
+
     if (!*(from-=rep_str->from_offset) && rep_pos->found != 2)
-      return (uint) (to - *start);
+    {
+      /* End of from string */
+      DBUG_PRINT("exit", ("Found end of from string"));
+      DBUG_VOID_RETURN;
+    }
+    DBUG_ASSERT(from <= str+len);
+    start= from;
     rep_pos=rep;
   }
 }
 
-static int initialize_replace_buffer(void)
-{
-  out_length=8192;
-  if (!(out_buff=my_malloc(out_length,MYF(MY_WME))))
-    return(1);
-  return 0;
-}
 
 /****************************************************************************
  Replace results for a column
@@ -5526,105 +5649,6 @@ static void get_replace_column(struct st_query *q)
   q->last_argument= q->end;
 }
 
-#if defined(__NETWARE__) || defined(__WIN__)
-/*
-  Substitute environment variables with text.
-
-  SYNOPSIS
-    subst_env_var()
-    arg			String that should be substitute
-
-  DESCRIPTION
-    This function takes a string as an input and replaces the
-    environment variables, that starts with '$' character, with it value.
-
-  NOTES
-    Return string must be freed with my_free()
-
-  RETURN
-    String with environment variables replaced.
-*/
-
-static char *subst_env_var(const char *str)
-{
-  char *result;
-  char *pos;
-
-  result= pos= my_malloc(MAX_QUERY, MYF(MY_FAE));
-  while (*str)
-  {
-    /*
-      need this only when we want to provide the functionality of
-      escaping through \ 'backslash'
-      if ((result == pos && *str=='$') ||
-          (result != pos && *str=='$' && str[-1] !='\\'))
-    */
-    if (*str == '$')
-    {
-      char env_var[256], *env_pos= env_var, *subst;
-
-      /* Search for end of environment variable */
-      for (str++;
-           *str && !isspace(*str) && *str != '\\' && *str != '/' &&
-             *str != '$';
-           str++)
-        *env_pos++= *str;
-      *env_pos= 0;
-
-      if (!(subst= getenv(env_var)))
-      {
-        my_free(result, MYF(0));
-        die("MYSQLTEST.NLM: Environment variable %s is not defined",
-            env_var);
-      }
-
-      /* get the string to be substitued for env_var  */
-      pos= strmov(pos, subst);
-      /* Process delimiter in *str again */
-    }
-    else
-      *pos++= *str++;
-  }
-  *pos= 0;
-  return result;
-}
 
 
-/*
-  popen replacement for Netware
-
-  SYNPOSIS
-    my_popen()
-    name		Command to execute (with possible env variables)
-    mode		Mode for popen.
-
-  NOTES
-    Environment variable expansion does not take place for popen function
-    on NetWare, so we use this function to wrap around popen to do this.
-
-    For the moment we ignore 'mode' and always use 'r0'
-
-  RETURN
-    # >= 0	File handle
-    -1		Error
-*/
-
-#undef popen                                    /* Remove wrapper */
-#ifdef __WIN__
-#define popen _popen                           /* redefine for windows */
-#endif
-
-FILE *my_popen(const char *cmd, const char *mode __attribute__((unused)))
-{
-  char *subst_cmd;
-  FILE *res_file;
-
-  subst_cmd= subst_env_var(cmd);
-  res_file= popen(subst_cmd, "r0");
-  my_free(subst_cmd, MYF(0));
-  return res_file;
-}
-
-#endif /* __NETWARE__ or  __WIN__*/
-
 
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index fdee6d96d3a..9f78d7c2708 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -156,6 +156,7 @@ our $path_mysqltest_log;
 our $path_slave_load_tmpdir;     # What is this?!
 our $path_my_basedir;
 our $opt_vardir;                 # A path but set directly on cmd line
+our $opt_vardir_unix;            # Always unix formatted opt_vardir
 our $opt_tmpdir;                 # A path but set directly on cmd line
 
 our $opt_usage;
@@ -640,7 +641,7 @@ sub command_line_setup () {
   {
     $opt_vardir= "$glob_mysql_test_dir/var";
   }
-
+  $opt_vardir_unix= $opt_vardir;
   # We make the path absolute, as the server will do a chdir() before usage
   unless ( $opt_vardir =~ m,^/, or
            ($glob_win32 and $opt_vardir =~ m,^[a-z]:/,i) )
@@ -937,7 +938,8 @@ sub executable_setup () {
     if ( $glob_win32 )
     {
       $path_client_bindir= mtr_path_exists("$glob_basedir/client_release",
-                                           "$glob_basedir/bin");
+					   "$glob_basedir/client_debug",
+                                           "$glob_basedir/bin",);
       $exe_mysqld=         mtr_exe_exists ("$path_client_bindir/mysqld-nt",
                                            "$path_client_bindir/mysqld",
                                            "$path_client_bindir/mysqld-debug",);
@@ -980,6 +982,7 @@ sub executable_setup () {
       }
       $exe_mysql_client_test=
         mtr_exe_exists("$glob_basedir/tests/mysql_client_test",
+                       "$path_client_bindir/mysql_client_test",
 		       "/usr/bin/false");
     }
     $exe_mysqlcheck=     mtr_exe_exists("$path_client_bindir/mysqlcheck");
@@ -1093,14 +1096,11 @@ sub environment_setup () {
   $ENV{'LC_COLLATE'}=         "C";
   $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server;
   $ENV{'MYSQL_TEST_DIR'}=     $glob_mysql_test_dir;
-  $ENV{'MYSQL_TEST_WINDIR'}=  $glob_mysql_test_dir;
   $ENV{'MASTER_MYSOCK'}=      $master->[0]->{'path_mysock'};
-  $ENV{'MASTER_WINMYSOCK'}=   $master->[0]->{'path_mysock'};
   $ENV{'MASTER_MYSOCK1'}=     $master->[1]->{'path_mysock'};
   $ENV{'MASTER_MYPORT'}=      $master->[0]->{'path_myport'};
   $ENV{'MASTER_MYPORT1'}=     $master->[1]->{'path_myport'};
   $ENV{'SLAVE_MYPORT'}=       $slave->[0]->{'path_myport'};
-# $ENV{'MYSQL_TCP_PORT'}=     '@MYSQL_TCP_PORT@'; # FIXME
   $ENV{'MYSQL_TCP_PORT'}=     3306;
 
   $ENV{'IM_PATH_PID'}=        $instance_manager->{path_pid};
@@ -1112,16 +1112,6 @@ sub environment_setup () {
   $ENV{'IM_MYSQLD2_PORT'}=    $instance_manager->{instances}->[1]->{port};
   $ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid};
 
-  if ( $glob_cygwin_perl )
-  {
-    foreach my $key ('MYSQL_TEST_WINDIR','MASTER_MYSOCK')
-    {
-      $ENV{$key}= `cygpath -w $ENV{$key}`;
-      $ENV{$key} =~ s,\\,\\\\,g;
-      chomp($ENV{$key});
-    }
-  }
-
   # We are nice and report a bit about our settings
   print "Using MTR_BUILD_THREAD = ",$ENV{MTR_BUILD_THREAD} || 0,"\n";
   print "Using MASTER_MYPORT    = $ENV{MASTER_MYPORT}\n";
@@ -2171,12 +2161,12 @@ sub mysqld_arguments ($$$$$) {
     if ( $type eq 'master' )
     {
       mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/master%s.trace",
-                  $prefix, $opt_vardir, $sidx);
+                  $prefix, $opt_vardir_unix, $sidx);
     }
     if ( $type eq 'slave' )
     {
       mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/slave%s.trace",
-                  $prefix, $opt_vardir, $sidx);
+                  $prefix, $opt_vardir_unix, $sidx);
     }
   }
 
@@ -2506,7 +2496,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlcheck .=
-      " --debug=d:t:A,$opt_vardir/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_unix/log/mysqldump.trace";
   }
 
   my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
@@ -2515,7 +2505,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqldump .=
-      " --debug=d:t:A,$opt_vardir/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_unix/log/mysqldump.trace";
   }
   my $cmdline_mysqlimport= "$exe_mysqlimport -uroot " .
                          "--port=$master->[0]->{'path_myport'} " .
@@ -2523,7 +2513,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlimport .=
-      " --debug=d:t:A,$opt_vardir/log/mysqlimport.trace";
+      " --debug=d:t:A,$opt_vardir_unix/log/mysqlimport.trace";
   }
 
   my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " .
@@ -2532,7 +2522,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlshow .=
-      " --debug=d:t:A,$opt_vardir/log/mysqlshow.trace";
+      " --debug=d:t:A,$opt_vardir_unix/log/mysqlshow.trace";
   }
 
   my $cmdline_mysqlbinlog=
@@ -2543,7 +2533,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlbinlog .=
-      " --debug=d:t:A,$opt_vardir/log/mysqlbinlog.trace";
+      " --debug=d:t:A,$opt_vardir_unix/log/mysqlbinlog.trace";
   }
 
   my $cmdline_mysql=
@@ -2675,7 +2665,7 @@ sub run_mysqltest ($) {
 
   if ( $opt_debug )
   {
-    mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir);
+    mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir_unix);
   }
 
   if ( $opt_ssl_supported )
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 717d9f67774..1418d4d1be6 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2330,10 +2330,10 @@ drop table t1;
 set global time_zone=default;
 set time_zone=default;
 DROP TABLE IF EXISTS `t1 test`;
+DROP TABLE IF EXISTS `t2 test`;
 CREATE TABLE `t1 test` (
 `a1` int(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
-DROP TABLE IF EXISTS `t2 test`;
 CREATE TABLE `t2 test` (
 `a2` int(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
diff --git a/mysql-test/t/client_xml.test b/mysql-test/t/client_xml.test
index 58e9178ef3a..017b7a1569a 100644
--- a/mysql-test/t/client_xml.test
+++ b/mysql-test/t/client_xml.test
@@ -9,13 +9,13 @@ create table t1 (
   `a>b` text
 );
 insert into t1 values (1, 2, 'a&b a<b a>b');
---exec $MYSQL --xml test -e 'select * from t1'
+--exec $MYSQL --xml test -e "select * from t1"
 --exec $MYSQL_DUMP --xml --skip-create test
 
---exec $MYSQL --xml test -e 'select count(*) from t1'
---exec $MYSQL --xml test -e 'select 1 < 2 from dual'
---exec $MYSQL --xml test -e 'select 1 > 2 from dual'
---exec $MYSQL --xml test -e 'select 1 & 3 from dual'
---exec $MYSQL --xml test -e 'select null from dual'
+--exec $MYSQL --xml test -e "select count(*) from t1"
+--exec $MYSQL --xml test -e "select 1 < 2 from dual"
+--exec $MYSQL --xml test -e "select 1 > 2 from dual"
+--exec $MYSQL --xml test -e "select 1 & 3 from dual"
+--exec $MYSQL --xml test -e "select null from dual"
 
 drop table t1;
diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test
index 9cacb008d09..4899ef9cecc 100644
--- a/mysql-test/t/mysql_client_test.test
+++ b/mysql-test/t/mysql_client_test.test
@@ -6,7 +6,6 @@
 # var/log/mysql_client_test.trace
 
 --disable_result_log
---exec echo $MYSQL_CLIENT_TEST --getopt-ll-test=25600M
 --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M
 
 # End of 4.1 tests
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 5cf49185c30..50f8c02dbae 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -429,7 +429,7 @@ echo ;
 # Illegal use of echo
 
 --error 1
---exec echo "echo $;" | $MYSQL_TEST 2>&1
+--exec echo "echo \$;" | $MYSQL_TEST 2>&1
 
 
 # ----------------------------------------------------------------------------
@@ -516,22 +516,22 @@ echo $novar1;
 --exec echo "let ;" | $MYSQL_TEST 2>&1
 
 --error 1
---exec echo "let $=hi;" | $MYSQL_TEST  2>&1
+--exec echo "let \$=hi;" | $MYSQL_TEST  2>&1
 
 --error 1
 --exec echo "let hi=hi;" | $MYSQL_TEST  2>&1
 
 --error 1
---exec echo "let $1 hi;" | $MYSQL_TEST  2>&1
+--exec echo "let \$1 hi;" | $MYSQL_TEST  2>&1
 
 --error 1
---exec echo "let $m hi;" | $MYSQL_TEST  2>&1
+--exec echo "let \$m hi;" | $MYSQL_TEST  2>&1
 
 --error 1
---exec echo "let $hi;" | $MYSQL_TEST  2>&1
+--exec echo "let \$hi;" | $MYSQL_TEST  2>&1
 
 --error 1
---exec echo "let $ hi;" | $MYSQL_TEST  2>&1
+--exec echo "let \$ hi;" | $MYSQL_TEST  2>&1
 
 --error 1
 --exec echo "let =hi;" | $MYSQL_TEST  2>&1
@@ -678,7 +678,7 @@ echo $i;
 --error 1
 --exec echo "inc i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \$i=100; inc \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \\\$i=100; inc \\\$i 1000; echo \\\$i;" | $MYSQL_TEST 2>&1
 
 inc $i; inc $i; inc $i; --echo $i
 echo $i;
@@ -706,7 +706,7 @@ echo $d;
 --error 1
 --exec echo "dec i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \$i=100; dec \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \\\$i=100; dec \\\$i 1000; echo \\\$i;" | $MYSQL_TEST 2>&1
 
 
 # ----------------------------------------------------------------------------
@@ -761,11 +761,11 @@ while ($i)
 --error 1
 --exec echo "source include/mysqltest_while.inc;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "while \$i;" | $MYSQL_TEST 2>&1
+--exec echo "while \\\$i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "while (\$i;" | $MYSQL_TEST 2>&1
+--exec echo "while (\\\$i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \$i=1; while (\$i) dec \$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \\\$i=1; while (\\\$i) dec \\\$i;" | $MYSQL_TEST 2>&1
 --error 1
 --exec echo "};" | $MYSQL_TEST 2>&1
 --error 1
@@ -877,22 +877,22 @@ select "a" as col1, "c" as col2;
 --exec echo "connect (con1,localhost,root,,,,,SMTP POP);" | $MYSQL_TEST 2>&1
 
 # Repeat connect/disconnect
---exec echo "let \$i=100;"                              > var/tmp/con.sql
---exec echo "while (\$i)"                              >> var/tmp/con.sql
+--exec echo "let \\\$i=100;"                            > var/tmp/con.sql
+--exec echo "while (\\\$i)"                            >> var/tmp/con.sql
 --exec echo "{"                                        >> var/tmp/con.sql
 --exec echo " connect (test_con1,localhost,root,,); "  >> var/tmp/con.sql
 --exec echo " disconnect test_con1; "                  >> var/tmp/con.sql
---exec echo " dec \$i;                               " >> var/tmp/con.sql
+--exec echo " dec \\\$i;                             " >> var/tmp/con.sql
 --exec echo "}"                                        >> var/tmp/con.sql
 --exec echo "source var/tmp/con.sql; echo OK;" | $MYSQL_TEST 2>&1
 
 # Repeat connect/disconnect, exceed max number of connections
---exec echo "let \$i=200;"                              > var/tmp/con.sql
---exec echo "while (\$i)"                              >> var/tmp/con.sql
+--exec echo "let \\\$i=200;"                            > var/tmp/con.sql
+--exec echo "while (\\\$i)"                            >> var/tmp/con.sql
 --exec echo "{"                                        >> var/tmp/con.sql
 --exec echo " connect (test_con1,localhost,root,,); "  >> var/tmp/con.sql
 --exec echo " disconnect test_con1; "                  >> var/tmp/con.sql
---exec echo " dec \$i;                               " >> var/tmp/con.sql
+--exec echo " dec \\\$i;                             " >> var/tmp/con.sql
 --exec echo "}"                                        >> var/tmp/con.sql
 --error 1
 --exec echo "source var/tmp/con.sql;" | $MYSQL_TEST 2>&1
@@ -1001,7 +1001,7 @@ select "this will be executed";
 #
 # Test that a test file that does not generate any output fails.
 #
---exec echo "let \$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
+--exec echo "let \\\$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
 --error 1
 --exec $MYSQL_TEST -x var/tmp/query.sql  2>&1
 
diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test
index a53049386af..df4bf6f977b 100644
--- a/mysql-test/t/rpl000015.test
+++ b/mysql-test/t/rpl000015.test
@@ -12,7 +12,7 @@ show slave status;
 
 change master to master_host='127.0.0.1';
 # The following needs to be cleaned up when change master is fixed
---replace_result $MASTER_MYPORT MASTER_PORT $MYSQL_TCP_PORT MASTER_PORT
+--replace_result $MYSQL_TCP_PORT MASTER_PORT
 --replace_column 1 # 8 # 9 # 23 # 33 #
 show slave status;
 --replace_result $MASTER_MYPORT MASTER_PORT
diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test
index 4621b2f50ef..0a2ab180806 100644
--- a/mysql-test/t/system_mysql_db_fix.test
+++ b/mysql-test/t/system_mysql_db_fix.test
@@ -77,7 +77,8 @@ type=ISAM;
 INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y');
 INSERT INTO user VALUES ('localhost','',    '','N','N','N','N','N','N','N','N','N');
 
--- exec $MYSQL_FIX_SYSTEM_TABLES --database=test
+# Call the "shell script" $MYSQL_FIX_SYSTEM_TABLES using system
+-- system $MYSQL_FIX_SYSTEM_TABLES --database=test > /dev/null
 -- enable_query_log
 -- enable_result_log
 

From 010fb090e851041e464092dd1124bd4e88acc7e6 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Fri, 17 Feb 2006 12:19:05 +0100
Subject: [PATCH 024/103] Set opt_vardir_trace for path for tracefiles

---
 mysql-test/mysql-test-run.pl | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 9f78d7c2708..e1d7c927a35 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -156,7 +156,7 @@ our $path_mysqltest_log;
 our $path_slave_load_tmpdir;     # What is this?!
 our $path_my_basedir;
 our $opt_vardir;                 # A path but set directly on cmd line
-our $opt_vardir_unix;            # Always unix formatted opt_vardir
+our $opt_vardir_trace;           # unix formatted opt_vardir for trace files
 our $opt_tmpdir;                 # A path but set directly on cmd line
 
 our $opt_usage;
@@ -641,7 +641,7 @@ sub command_line_setup () {
   {
     $opt_vardir= "$glob_mysql_test_dir/var";
   }
-  $opt_vardir_unix= $opt_vardir;
+  $opt_vardir_trace= $opt_vardir;
   # We make the path absolute, as the server will do a chdir() before usage
   unless ( $opt_vardir =~ m,^/, or
            ($glob_win32 and $opt_vardir =~ m,^[a-z]:/,i) )
@@ -2161,12 +2161,12 @@ sub mysqld_arguments ($$$$$) {
     if ( $type eq 'master' )
     {
       mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/master%s.trace",
-                  $prefix, $opt_vardir_unix, $sidx);
+                  $prefix, $opt_vardir_trace, $sidx);
     }
     if ( $type eq 'slave' )
     {
       mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/slave%s.trace",
-                  $prefix, $opt_vardir_unix, $sidx);
+                  $prefix, $opt_vardir_trace, $sidx);
     }
   }
 
@@ -2496,7 +2496,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlcheck .=
-      " --debug=d:t:A,$opt_vardir_unix/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace";
   }
 
   my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .
@@ -2505,7 +2505,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqldump .=
-      " --debug=d:t:A,$opt_vardir_unix/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace";
   }
   my $cmdline_mysqlimport= "$exe_mysqlimport -uroot " .
                          "--port=$master->[0]->{'path_myport'} " .
@@ -2513,7 +2513,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlimport .=
-      " --debug=d:t:A,$opt_vardir_unix/log/mysqlimport.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqlimport.trace";
   }
 
   my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " .
@@ -2522,7 +2522,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlshow .=
-      " --debug=d:t:A,$opt_vardir_unix/log/mysqlshow.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqlshow.trace";
   }
 
   my $cmdline_mysqlbinlog=
@@ -2533,7 +2533,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlbinlog .=
-      " --debug=d:t:A,$opt_vardir_unix/log/mysqlbinlog.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqlbinlog.trace";
   }
 
   my $cmdline_mysql=
@@ -2665,7 +2665,7 @@ sub run_mysqltest ($) {
 
   if ( $opt_debug )
   {
-    mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir_unix);
+    mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir_trace);
   }
 
   if ( $opt_ssl_supported )

From 128e5df7e9c5b7ea0c17e8c3fb645be9bb764e57 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Fri, 17 Feb 2006 08:32:52 -0600
Subject: [PATCH 025/103] mysqlcheck.c:   Tweak --check-upgrade help text.

client/mysqlcheck.c:
  Tweak --check-upgrade help text.
---
 client/mysqlcheck.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index 7ddfbbd7211..804fa14956f 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -79,7 +79,7 @@ static struct my_option my_long_options[] =
    "Check only tables that have changed since last check or haven't been closed properly.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"check-upgrade", 'g',
-   "Check tables for version dependent changes.May be used with auto-repair to correct tables requiring version dependent updates.",
+   "Check tables for version-dependent changes. May be used with --auto-repair to correct tables requiring version-dependent updates.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"compress", OPT_COMPRESS, "Use compression in server/client protocol.",
    (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,

From eae6679fd4a55a1798f2c20385507f869c85e7a6 Mon Sep 17 00:00:00 2001
From: unknown <jimw@mysql.com>
Date: Fri, 17 Feb 2006 10:02:59 -0800
Subject: [PATCH 026/103] Fix subselect results (there was a bad merge when
 subselect test was disabled)

BitKeeper/etc/ignore:
  Added scripts/mysql_upgrade to the ignore list
mysql-test/r/subselect.result:
  Update results
---
 .bzrignore                    | 1 +
 mysql-test/r/subselect.result | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/.bzrignore b/.bzrignore
index a210762d46a..a16ed70a812 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -1273,3 +1273,4 @@ vio/viotest-sslconnect.cpp
 vio/viotest.cpp
 zlib/*.ds?
 zlib/*.vcproj
+scripts/mysql_upgrade
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 85976c211c5..6094d23b0d0 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -215,9 +215,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
 a
 select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
 b	(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
-8	7.5
-8	4.5
-9	7.5
+8	7.5000
+8	4.5000
+9	7.5000
 explain extended select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
 id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
 1	PRIMARY	t4	ALL	NULL	NULL	NULL	NULL	3	

From 187aab97b6936ed88b5021de0bc0ae342ac991c8 Mon Sep 17 00:00:00 2001
From: unknown <petr@mysql.com>
Date: Sat, 18 Feb 2006 03:22:13 +0300
Subject: [PATCH 027/103] Add a shift in the parser. Forgotten in the previous
 commit.

server-tools/instance-manager/parse.cc:
  shift the second value for the log
---
 server-tools/instance-manager/parse.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/server-tools/instance-manager/parse.cc b/server-tools/instance-manager/parse.cc
index 4a8e85faf8f..14b3db16b45 100644
--- a/server-tools/instance-manager/parse.cc
+++ b/server-tools/instance-manager/parse.cc
@@ -290,6 +290,7 @@ Command *parse_command(Instance_map *map, const char *text)
                 get_word(&text, &word_len);
                 if (!word_len)
                   goto syntax_error;
+                text+= word_len;
                 command= new Show_instance_log(map, instance_name,
                                                instance_name_len, log_type,
                                                log_size, text);

From 1d96eaddb9ab49e3c12e87e81bde45125c69e30e Mon Sep 17 00:00:00 2001
From: unknown <holyfoot@deer.(none)>
Date: Sat, 18 Feb 2006 14:55:31 +0400
Subject: [PATCH 028/103] --help option added to mysql_upgrade script

scripts/mysql_upgrade.sh:
  --help option implemented
---
 scripts/mysql_upgrade.sh | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/scripts/mysql_upgrade.sh b/scripts/mysql_upgrade.sh
index db5dc6a9516..ed52f5126ce 100644
--- a/scripts/mysql_upgrade.sh
+++ b/scripts/mysql_upgrade.sh
@@ -39,6 +39,7 @@ parse_arguments() {
       --ldata=*|--data=*|--datadir=*) DATADIR=`echo "$arg" | sed -e 's/^[^=]*=//'` ;;
       --force) force=1 ;;
       --verbose) verbose=1 ;;
+      --help) help_option=1 ;;
       *)
         if test -n "$pick_args"
         then
@@ -84,10 +85,27 @@ bindir=
 MY_BASEDIR_VERSION=
 verbose=0
 force=0
+help_option=0
 
 parse_arguments `$print_defaults $defaults mysqld mysql_upgrade`
 parse_arguments PICK-ARGS-FROM-ARGV "$@"
 
+if test $help_option = 1
+then
+  echo "MySQL utility script to upgrade database to the current server version"
+  echo ""
+  echo "It takes the following arguments:"
+  echo "  --basedir  Specifies the directory where MySQL is installed"
+  echo "  --user     user for database login if not current user"
+  echo "  --datadir  data directory"
+  echo "  --force    keep process ignoring errors"
+  echo "  --verbose  give more output about the process"
+  echo "  --help     Show this help message"
+  echo ""
+
+  exit 0
+fi
+
 #
 # Try to find where binaries are installed
 #

From cefc0b6dffcf3f7cd0e1ee7ebc6dd14eca622757 Mon Sep 17 00:00:00 2001
From: unknown <guilhem@mysql.com>
Date: Sat, 18 Feb 2006 17:19:16 +0100
Subject: [PATCH 029/103] Fix for BUG#16559 "Replication Problems with Non
 transactional tables inside an interrupted trans.": problem was: when a
 connection disconnects having an open transaction affecting MyISAM and
 InnoDB, the ROLLBACK event stored in the binary log contained a non-zero
 error code (1053 because of the disconnection), so when slave applied the
 transaction, slave complained that its ROLLBACK succeeded (error_code=0)
 while master's had 1053, so slave stopped. But internally generated binlog
 events such as this ROLLBACK should always have 0 as error code, as is true
 in 4.1 and was accidentally broken in 5.0, so that there is no false alarm.

mysql-test/r/mix_innodb_myisam_binlog.result:
  result update
mysql-test/t/mix_innodb_myisam_binlog.test:
  test for BUG#16559
sql/log.cc:
  Internally generated binlog events should always have an error code of zero (like in 4.1; in 5.0 this was accidentally broken).
---
 mysql-test/r/mix_innodb_myisam_binlog.result | 23 ++++++++++++++
 mysql-test/t/mix_innodb_myisam_binlog.test   | 33 +++++++++++++++++++-
 sql/log.cc                                   |  6 +++-
 3 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index c84bd65e748..2273b8c8756 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -256,3 +256,26 @@ master-bin.000001	1648	Query	1	#	use `test`; create table t2 (n int) engine=inno
 master-bin.000001	1748	Query	1	#	use `test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `test`.`t1`,`test`.`ti`
 do release_lock("lock1");
 drop table t0,t2;
+reset master;
+create table t1 (a int) engine=innodb;
+create table t2 (a int) engine=myisam;
+select get_lock("a",10);
+get_lock("a",10)
+1
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+select get_lock("a",10);
+get_lock("a",10)
+1
+select
+(@a:=load_file("MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+is not null;
+(@a:=load_file("MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+is not null
+1
+select
+@a like "%#%error_code=0%ROLLBACK;%ROLLBACK /* added by mysqlbinlog */;%",
+@a not like "%#%error_code=%error_code=%";
+@a like "%#%error_code=0%ROLLBACK;%ROLLBACK /* added by mysqlbinlog */;%"	@a not like "%#%error_code=%error_code=%"
+1	1
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index 658584b625e..7ba7b634b22 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -259,5 +259,36 @@ show binlog events from 98;
 do release_lock("lock1");
 drop table t0,t2;
 
-
 # End of 4.1 tests
+
+# Test for BUG#16559 (ROLLBACK should always have a zero error code in
+# binlog). Has to be here and not earlier, as the SELECTs influence
+# XIDs differently between normal and ps-protocol (and SHOW BINLOG
+# EVENTS above read XIDs).
+
+connect (con4,localhost,root,,);
+connection con3;
+reset master;
+create table t1 (a int) engine=innodb;
+create table t2 (a int) engine=myisam;
+select get_lock("a",10);
+begin;
+insert into t1 values(8);
+insert into t2 select * from t1;
+disconnect con3;
+
+connection con4;
+select get_lock("a",10); # wait for rollback to finish
+
+# we check that the error code of the "ROLLBACK" event is 0 and not
+# ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction
+# and does not make slave to stop)
+--exec $MYSQL_BINLOG --start-position=547 $MYSQL_TEST_DIR/var/log/master-bin.000001 > var/tmp/mix_innodb_myisam_binlog.output
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+eval select
+(@a:=load_file("$MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+is not null;
+--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+eval select
+@a like "%#%error_code=0%ROLLBACK;%ROLLBACK /* added by mysqlbinlog */;%",
+@a not like "%#%error_code=%error_code=%";
diff --git a/sql/log.cc b/sql/log.cc
index 6c37cb04c61..85e8c4dae2f 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -132,6 +132,7 @@ static int binlog_commit(THD *thd, bool all)
     DBUG_RETURN(0);
   }
   Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
+  qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
   DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev));
 }
 
@@ -156,6 +157,7 @@ static int binlog_rollback(THD *thd, bool all)
   if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
   {
     Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
+    qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
     error= binlog_end_trans(thd, trans_log, &qev);
   }
   else
@@ -1826,7 +1828,9 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
         Imagine this is rollback due to net timeout, after all statements of
         the transaction succeeded. Then we want a zero-error code in BEGIN.
         In other words, if there was a really serious error code it's already
-        in the statement's events.
+        in the statement's events, there is no need to put it also in this
+        internally generated event, and as this event is generated late it
+        would lead to false alarms.
         This is safer than thd->clear_error() against kills at shutdown.
       */
       qinfo.error_code= 0;

From 8470ae9cb1327ee5089b98a148e26bb207662fd7 Mon Sep 17 00:00:00 2001
From: unknown <guilhem@mysql.com>
Date: Sat, 18 Feb 2006 17:26:30 +0100
Subject: [PATCH 030/103] Fix for BUG#14769 "Function fails to replicate if
 fails half-way (slave stops)": if the function, invoked in a non-binlogged
 caller (e.g. SELECT, DO), failed half-way on the master, slave would stop and
 complain that error code between him and master mismatch. To solve this, when
 a stored function is invoked in a non-binlogged caller (e.g. SELECT, DO), we
 binlog the function call as SELECT instead of as DO (see revision comment of
 sp_head.cc for more). And: minor wording change in the help text. This cset
 will cause conflicts in 5.1, I'll merge.

mysql-test/r/rpl_sp.result:
  result update
mysql-test/t/rpl_sp-slave.opt:
  bug just fixed so option not needed
mysql-test/t/rpl_sp.test:
  test for more half-failed functions with DO and SELECT, to test the bug of this changeset.
  cleanup at the end.
sql/mysqld.cc:
  function -> stored function (change suggested by Paul)
sql/sp_head.cc:
  When a function updates data and is called from a non-binlogged statement (SELECT, DO), we binlog it
  as SELECT myfunc(), and not DO myfunc() like before.
---
 mysql-test/r/rpl_sp.result    | 21 +++++++++++++--------
 mysql-test/t/rpl_sp-slave.opt |  2 +-
 mysql-test/t/rpl_sp.test      | 12 +++++-------
 sql/mysqld.cc                 |  4 ++--
 sql/sp_head.cc                | 12 +++---------
 5 files changed, 24 insertions(+), 27 deletions(-)

diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result
index 7180b677b8e..a42c33ce333 100644
--- a/mysql-test/r/rpl_sp.result
+++ b/mysql-test/r/rpl_sp.result
@@ -233,20 +233,25 @@ end	@	#	#
 delete from t2;
 alter table t2 add unique (a);
 drop function fn1;
-create function fn1()
+create function fn1(x int)
 returns int
 begin
-insert into t2 values(20),(20);
+insert into t2 values(x),(x);
 return 10;
 end|
-select fn1();
+do fn1(100);
+Warnings:
+Error	1062	Duplicate entry '100' for key 1
+select fn1(20);
 ERROR 23000: Duplicate entry '20' for key 1
 select * from t2;
 a
 20
+100
 select * from t2;
 a
 20
+100
 create trigger trg before insert on t1 for each row set new.a= 10;
 ERROR 42000: Access denied; you need the SUPER privilege for this operation
 delete from t1;
@@ -324,7 +329,7 @@ insert into t1 values (x);
 return x+2;
 end
 master-bin.000001	#	Query	1	#	use `mysqltest1`; delete t1,t2 from t1,t2
-master-bin.000001	#	Query	1	#	use `mysqltest1`; DO `fn1`(20)
+master-bin.000001	#	Query	1	#	use `mysqltest1`; SELECT `fn1`(20)
 master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t2 values(fn1(21))
 master-bin.000001	#	Query	1	#	use `mysqltest1`; drop function fn1
 master-bin.000001	#	Query	1	#	use `mysqltest1`; create function fn1()
@@ -351,13 +356,14 @@ end
 master-bin.000001	#	Query	1	#	use `mysqltest1`; delete from t2
 master-bin.000001	#	Query	1	#	use `mysqltest1`; alter table t2 add unique (a)
 master-bin.000001	#	Query	1	#	use `mysqltest1`; drop function fn1
-master-bin.000001	#	Query	1	#	use `mysqltest1`; create function fn1()
+master-bin.000001	#	Query	1	#	use `mysqltest1`; create function fn1(x int)
 returns int
 begin
-insert into t2 values(20),(20);
+insert into t2 values(x),(x);
 return 10;
 end
-master-bin.000001	#	Query	1	#	use `mysqltest1`; DO `fn1`()
+master-bin.000001	#	Query	1	#	use `mysqltest1`; SELECT `fn1`(100)
+master-bin.000001	#	Query	1	#	use `mysqltest1`; SELECT `fn1`(20)
 master-bin.000001	#	Query	1	#	use `mysqltest1`; delete from t1
 master-bin.000001	#	Query	1	#	use `mysqltest1`; CREATE DEFINER=`root`@`localhost` trigger trg before insert on t1 for each row set new.a= 10
 master-bin.000001	#	Query	1	#	use `mysqltest1`; insert into t1 values (1)
@@ -415,4 +421,3 @@ col
 test
 DROP PROCEDURE p1;
 drop table t1;
-reset master;
diff --git a/mysql-test/t/rpl_sp-slave.opt b/mysql-test/t/rpl_sp-slave.opt
index 611ee1f33be..709a224fd92 100644
--- a/mysql-test/t/rpl_sp-slave.opt
+++ b/mysql-test/t/rpl_sp-slave.opt
@@ -1 +1 @@
---log_bin_trust_routine_creators=0 --slave-skip-errors=1062
+--log_bin_trust_routine_creators=0
diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test
index c0eaf6f817f..8be17be3822 100644
--- a/mysql-test/t/rpl_sp.test
+++ b/mysql-test/t/rpl_sp.test
@@ -294,21 +294,19 @@ alter table t2 add unique (a);
 drop function fn1;
 
 delimiter |;
-create function fn1()
+create function fn1(x int)
        returns int
 begin
-  insert into t2 values(20),(20);
+  insert into t2 values(x),(x);
   return 10;
 end|
 
 delimiter ;|
 
-# Because of BUG#14769 the following statement requires that we start
-# slave with --slave-skip-errors=1062. When that bug is fixed, that
-# option can be removed.
+do fn1(100);
 
 --error 1062
-select fn1();
+select fn1(20);
 
 select * from t2;
 sync_slave_with_master;
@@ -440,4 +438,4 @@ DROP PROCEDURE p1;
 # cleanup
 connection master;
 drop table t1;
-reset master;
+sync_slave_with_master;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index c19fdcfde82..4c32d7f9de5 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4923,8 +4923,8 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
   */
   {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
    "If equal to 0 (the default), then when --log-bin is used, creation of "
-   "a function is allowed only to users having the SUPER privilege and only "
-   "if this function may not break binary logging.",
+   "a stored function is allowed only to users having the SUPER privilege and"
+   " only if this function may not break binary logging.",
    (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 27dc0103335..aff773a32bc 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -736,13 +736,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
   Statements that have is_update_query(stmt) == FALSE (e.g. SELECTs) are not
   written into binary log. Instead we catch function calls the statement
   makes and write it into binary log separately (see #3).
-  
-  We actually can easily write SELECT statements into the binary log in the 
-  right order (we don't have issues with const tables being unlocked early
-  because SELECTs that use FUNCTIONs unlock all tables at once) We don't do 
-  it because replication slave thread currently can't execute SELECT
-  statements. Fixing this is on the TODO.
-  
+
   2. PROCEDURE calls
 
   CALL statements are not written into binary log. Instead
@@ -763,7 +757,7 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
      function execution (grep for start_union_events and stop_union_events)
 
    If the answers are No and Yes, we write the function call into the binary
-   log as "DO spfunc(<param1value>, <param2value>, ...)"
+   log as "SELECT spfunc(<param1value>, <param2value>, ...)".
   
   
   4. Miscellaneous issues.
@@ -1310,7 +1304,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
     char buf[256];
     String bufstr(buf, sizeof(buf), &my_charset_bin);
     bufstr.length(0);
-    bufstr.append(STRING_WITH_LEN("DO "));
+    bufstr.append(STRING_WITH_LEN("SELECT "));
     append_identifier(thd, &bufstr, m_name.str, m_name.length);
     bufstr.append('(');
     for (uint i=0; i < argcount; i++)

From 8dc567dbed7ab9c6489d0b2f2c72d723c87c68e5 Mon Sep 17 00:00:00 2001
From: unknown <guilhem@mysql.com>
Date: Sat, 18 Feb 2006 17:32:15 +0100
Subject: [PATCH 031/103] Fix for BUG#13897 "failure to do SET SQL_MODE=N where
 N is a number > 31" (the original bug's title isn't the simplest symptom).
 sys_var::check_set() was wrong. mysqlbinlog makes use of such SET SQL_MODE=N
 (where N is interpreted like if SQL_MODE was a field of type SET), so this
 bug affected recovery from binlogs if the server was running with certain
 SQL_MODE values, for example the default values on Windows
 (STRICT_TRANS_TABLES); to work around this bug people had to edit
 mysqlbinlog's output.

mysql-test/r/sql_mode.result:
  result update
mysql-test/t/sql_mode.test:
  test for various numeric SQL_MODE values
sql/set_var.cc:
  For a set, it does not make sense to test if the supplied argument exceeds the number of elements in the set
  (such test would make sense for an enum), but rather to check if it exceeds 2^this (to verify
  that only reasonable bits are set).
---
 mysql-test/r/sql_mode.result | 16 ++++++++++++++++
 mysql-test/t/sql_mode.test   |  9 +++++++++
 sql/set_var.cc               |  7 ++++++-
 3 files changed, 31 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/sql_mode.result b/mysql-test/r/sql_mode.result
index 7d9d7fb333c..66df424919b 100644
--- a/mysql-test/r/sql_mode.result
+++ b/mysql-test/r/sql_mode.result
@@ -478,4 +478,20 @@ v1	CREATE ALGORITHM=UNDEFINED DEFINER="root"@"localhost" SQL SECURITY DEFINER VI
 create view v2 as select a from t2 where a in (select a from v1);
 drop view v2, v1;
 drop table t1, t2;
+select @@sql_mode;
+@@sql_mode
+ANSI_QUOTES
+set sql_mode=2097152;
+select @@sql_mode;
+@@sql_mode
+STRICT_TRANS_TABLES
+set sql_mode=16384+(65536*4);
+select @@sql_mode;
+@@sql_mode
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
+set sql_mode=2147483648;
+ERROR 42000: Variable 'sql_mode' can't be set to the value of '2147483648'
+select @@sql_mode;
+@@sql_mode
+REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,NO_TABLE_OPTIONS,ANSI
 SET @@SQL_MODE=@OLD_SQL_MODE;
diff --git a/mysql-test/t/sql_mode.test b/mysql-test/t/sql_mode.test
index 8ae9ced6c68..b67f1a73db6 100644
--- a/mysql-test/t/sql_mode.test
+++ b/mysql-test/t/sql_mode.test
@@ -255,4 +255,13 @@ create view v2 as select a from t2 where a in (select a from v1);
 drop view v2, v1;
 drop table t1, t2;
 
+select @@sql_mode;
+set sql_mode=2097152;
+select @@sql_mode;
+set sql_mode=16384+(65536*4);
+select @@sql_mode;
+--error 1231
+set sql_mode=2147483648; # that mode does not exist
+select @@sql_mode;
+
 SET @@SQL_MODE=@OLD_SQL_MODE;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 02216fb2113..7be79ab59f0 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -1659,7 +1659,12 @@ bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
   else
   {
     ulonglong tmp= var->value->val_int();
-    if (tmp >= enum_names->count)
+   /*
+     For when the enum is made to contain 64 elements, as 1ULL<<64 is
+     undefined, we guard with a "count<64" test.
+   */
+    if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
+                 (enum_names->count < 64)))
     {
       llstr(tmp, buff);
       goto err;

From 34d8c572086ca203fb113e6c1d3a56e009ce43d3 Mon Sep 17 00:00:00 2001
From: unknown <guilhem@mysql.com>
Date: Sat, 18 Feb 2006 21:08:41 +0100
Subject: [PATCH 032/103] In previous push, a DROP TABLE at the end of test was
 missing.

mysql-test/r/mix_innodb_myisam_binlog.result:
  result update
mysql-test/t/mix_innodb_myisam_binlog.test:
  cleanup in the end
---
 mysql-test/r/mix_innodb_myisam_binlog.result | 1 +
 mysql-test/t/mix_innodb_myisam_binlog.test   | 1 +
 2 files changed, 2 insertions(+)

diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index 2273b8c8756..4e3d9217fb3 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -279,3 +279,4 @@ select
 @a not like "%#%error_code=%error_code=%";
 @a like "%#%error_code=0%ROLLBACK;%ROLLBACK /* added by mysqlbinlog */;%"	@a not like "%#%error_code=%error_code=%"
 1	1
+drop table t1, t2;
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index 7ba7b634b22..3a9aff271d5 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -292,3 +292,4 @@ is not null;
 eval select
 @a like "%#%error_code=0%ROLLBACK;%ROLLBACK /* added by mysqlbinlog */;%",
 @a not like "%#%error_code=%error_code=%";
+drop table t1, t2;

From 8aac108d9114c55de355e450d091ae69ab6970cf Mon Sep 17 00:00:00 2001
From: unknown <knielsen@mysql.com>
Date: Mon, 20 Feb 2006 09:34:02 +0100
Subject: [PATCH 033/103] Remove hard-coded ../var/.. path in test
 mix_innodb_myisam_binlog, fails with --vardir option.

---
 mysql-test/r/mix_innodb_myisam_binlog.result | 4 ++--
 mysql-test/t/mix_innodb_myisam_binlog.test   | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result
index 4e3d9217fb3..e7fc22dac7c 100644
--- a/mysql-test/r/mix_innodb_myisam_binlog.result
+++ b/mysql-test/r/mix_innodb_myisam_binlog.result
@@ -269,9 +269,9 @@ select get_lock("a",10);
 get_lock("a",10)
 1
 select
-(@a:=load_file("MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
 is not null;
-(@a:=load_file("MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+(@a:=load_file("MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
 is not null
 1
 select
diff --git a/mysql-test/t/mix_innodb_myisam_binlog.test b/mysql-test/t/mix_innodb_myisam_binlog.test
index 3a9aff271d5..66440f1236e 100644
--- a/mysql-test/t/mix_innodb_myisam_binlog.test
+++ b/mysql-test/t/mix_innodb_myisam_binlog.test
@@ -283,10 +283,10 @@ select get_lock("a",10); # wait for rollback to finish
 # we check that the error code of the "ROLLBACK" event is 0 and not
 # ER_SERVER_SHUTDOWN (i.e. disconnection just rolls back transaction
 # and does not make slave to stop)
---exec $MYSQL_BINLOG --start-position=547 $MYSQL_TEST_DIR/var/log/master-bin.000001 > var/tmp/mix_innodb_myisam_binlog.output
---replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
+--exec $MYSQL_BINLOG --start-position=547 $MYSQLTEST_VARDIR/log/master-bin.000001 > $MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
 eval select
-(@a:=load_file("$MYSQL_TEST_DIR/var/tmp/mix_innodb_myisam_binlog.output"))
+(@a:=load_file("$MYSQLTEST_VARDIR/tmp/mix_innodb_myisam_binlog.output"))
 is not null;
 --replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
 eval select

From b24e7ca0af20d1625bed4dc56151275a62e19506 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot@deer.(none)>
Date: Mon, 20 Feb 2006 14:26:32 +0400
Subject: [PATCH 034/103] Messgges corrected in mysql_upgrade script

scripts/mysql_upgrade.sh:
  messages corrected
---
 scripts/mysql_upgrade.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/scripts/mysql_upgrade.sh b/scripts/mysql_upgrade.sh
index ed52f5126ce..c9f375b6c5b 100644
--- a/scripts/mysql_upgrade.sh
+++ b/scripts/mysql_upgrade.sh
@@ -95,12 +95,12 @@ then
   echo "MySQL utility script to upgrade database to the current server version"
   echo ""
   echo "It takes the following arguments:"
-  echo "  --basedir  Specifies the directory where MySQL is installed"
-  echo "  --user     user for database login if not current user"
-  echo "  --datadir  data directory"
-  echo "  --force    keep process ignoring errors"
-  echo "  --verbose  give more output about the process"
   echo "  --help     Show this help message"
+  echo "  --basedir  Specifies the directory where MySQL is installed"
+  echo "  --datadir  Specifies the data directory"
+  echo "  --force    Mysql_upgrade.info file will be ignored"
+  echo "  --user     Username for server login if not current user"
+  echo "  --verbose  Display more output about the process"
   echo ""
 
   exit 0

From e46f214fd997feccf448edd07abed2b9c6a972f7 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 20 Feb 2006 12:05:45 +0100
Subject: [PATCH 035/103] Fix typo

client/mysqltest.c:
  Typo % should be %s
---
 client/mysqltest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 0ff8667a7de..6bf361c17aa 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1088,7 +1088,7 @@ static void do_exec(struct st_query *query)
   do_eval(&ds_cmd, cmd);
   cmd= ds_cmd.str;
 
-  DBUG_PRINT("info", ("Executing '%' as '%s'",
+  DBUG_PRINT("info", ("Executing '%s' as '%s'",
                       query->first_argument, cmd));
 
   if (!(res_file= popen(cmd, "r")) && query->abort_on_error)

From 06d4f8838ce239f0e273fd3080f578e33b53abac Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 20 Feb 2006 15:03:16 +0100
Subject: [PATCH 036/103] Escape \ in "exec"

mysql-test/t/ndb_config.test:
  Add extra \ to escape \.
  \\\n => \n
---
 mysql-test/t/ndb_config.test | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mysql-test/t/ndb_config.test b/mysql-test/t/ndb_config.test
index e40e89d76bd..4787abe86e2 100644
--- a/mysql-test/t/ndb_config.test
+++ b/mysql-test/t/ndb_config.test
@@ -4,7 +4,7 @@
 
 --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host 2> /dev/null
 --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null
---exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null
+--exec $NDB_TOOLS_DIR/ndb_config --no-defaults -r \\\n -f " " --query=nodeid,host,DataMemory,IndexMemory --type=ndbd 2> /dev/null
 --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=nodeid --type=ndbd --host=localhost 2> /dev/null
 --exec $NDB_TOOLS_DIR/ndb_config --no-defaults --query=type,nodeid,host --config-file=$NDB_BACKUP_DIR/config.ini 2> /dev/null
 

From 15c37025987829150a164ed93dcf0aa7f9c675cf Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Tue, 21 Feb 2006 13:21:17 +0100
Subject: [PATCH 037/103] Bug#14871 mysqldump: invalid view dump output  - Add
 comments with embeded veriosn info around the parts of the view syntax that
 are only supported by a certain version of MySQL Server

client/mysqldump.c:
  Use information_schema.views to gather information about the view, then replace some parts of the output from "SHOW CREATE VIEW" with comment markers with version, to make thos parts of the view syntax become parsed only of MySQL servers that supports it.
  Create common function "open_sql_file_for_table" to open the individual .sql file where to dump the table or view.
mysql-test/r/mysqldump.result:
  Update results
mysql-test/t/mysqldump.test:
  Add test to see that views can be deumped and reloaded alos when they contain "SECURITY TYPE", "CHECK OPTION" and "DEFINER"
---
 client/mysqldump.c            | 203 ++++++++++++++++++++++++++++------
 mysql-test/r/mysqldump.result |  64 +++++++++--
 mysql-test/t/mysqldump.test   |  30 +++++
 3 files changed, 254 insertions(+), 43 deletions(-)

diff --git a/client/mysqldump.c b/client/mysqldump.c
index b24d67ec302..6f185ff2245 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -851,6 +851,27 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res,
   return 0;
 }
 
+/*
+  Open a new .sql file to dump the table or view into
+
+  SYNOPSIS
+    open_sql_file_for_table
+    name      name of the table or view
+
+  RETURN VALUES
+    0        Failed to open file
+    > 0      Handle of the open file
+*/
+static FILE* open_sql_file_for_table(const char* table)
+{
+  FILE* res;
+  char filename[FN_REFLEN], tmp_path[FN_REFLEN];
+  convert_dirname(tmp_path,path,NullS);
+  res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
+		O_WRONLY, MYF(MY_WME));
+  return res;
+}
+
 
 static void safe_exit(int error)
 {
@@ -1402,11 +1423,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
 
       if (path)
       {
-        char filename[FN_REFLEN], tmp_path[FN_REFLEN];
-        convert_dirname(tmp_path,path,NullS);
-        sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
-				 O_WRONLY, MYF(MY_WME));
-        if (!sql_file)			/* If file couldn't be opened */
+        if (!(sql_file= open_sql_file_for_table(table)))
         {
 	  safe_exit(EX_MYSQLERR);
 	  DBUG_RETURN(0);
@@ -1568,11 +1585,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
     {
       if (path)
       {
-        char filename[FN_REFLEN], tmp_path[FN_REFLEN];
-        convert_dirname(tmp_path,path,NullS);
-        sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
-				 O_WRONLY, MYF(MY_WME));
-        if (!sql_file)			/* If file couldn't be opened */
+        if (!(sql_file= open_sql_file_for_table(table)))
         {
 	  safe_exit(EX_MYSQLERR);
 	  DBUG_RETURN(0);
@@ -3202,6 +3215,41 @@ cleanup:
 }
 
 
+/*
+  Replace a substring
+
+  SYNOPSIS
+    replace
+    ds_str      The string to search and perform the replace in
+    search_str  The string to search for
+    search_len  Length of the string to search for
+    replace_str The string to replace with
+    replace_len Length of the string to replace with
+
+  RETURN
+    0 String replaced
+    1 Could not find search_str in str
+*/
+
+static int replace(DYNAMIC_STRING *ds_str,
+                   const char *search_str, ulong search_len,
+                   const char *replace_str, ulong replace_len)
+{
+  const char *start= strstr(ds_str->str, search_str);
+  if (!start)
+    return 1;
+  DYNAMIC_STRING ds_tmp;
+  init_dynamic_string(&ds_tmp, "",
+		      ds_str->length + replace_len, 256);
+  dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str);
+  dynstr_append_mem(&ds_tmp, replace_str, replace_len);
+  dynstr_append(&ds_tmp, start + search_len);
+  dynstr_set(ds_str, ds_tmp.str);
+  dynstr_free(&ds_tmp);
+  return 0;
+}
+
+
 /*
   Getting VIEW structure
 
@@ -3223,11 +3271,11 @@ static my_bool get_view_structure(char *table, char* db)
   char	     *result_table, *opt_quoted_table;
   char	     table_buff[NAME_LEN*2+3];
   char	     table_buff2[NAME_LEN*2+3];
-  char       buff[20+FN_REFLEN];
+  char       query[QUERY_LENGTH];
   FILE       *sql_file = md_result_file;
   DBUG_ENTER("get_view_structure");
 
-  if (tFlag)
+  if (tFlag) /* Don't write table creation info */
     DBUG_RETURN(0);
 
   if (verbose)
@@ -3241,29 +3289,14 @@ static my_bool get_view_structure(char *table, char* db)
   result_table=     quote_name(table, table_buff, 1);
   opt_quoted_table= quote_name(table, table_buff2, 0);
 
-  sprintf(buff,"show create table %s", result_table);
-  if (mysql_query(sock, buff))
+  snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
+  if (mysql_query_with_error_report(sock, &table_res, query))
   {
-    fprintf(stderr, "%s: Can't get CREATE TABLE for view %s (%s)\n",
-            my_progname, result_table, mysql_error(sock));
     safe_exit(EX_MYSQLERR);
     DBUG_RETURN(0);
   }
 
-  if (path)
-  {
-    char filename[FN_REFLEN], tmp_path[FN_REFLEN];
-    convert_dirname(tmp_path,path,NullS);
-    sql_file= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4),
-                       O_WRONLY, MYF(MY_WME));
-    if (!sql_file)			/* If file couldn't be opened */
-    {
-      safe_exit(EX_MYSQLERR);
-      DBUG_RETURN(1);
-    }
-    write_header(sql_file, db);
-  }
-  table_res= mysql_store_result(sock);
+  /* Check if this is a view */
   field= mysql_fetch_field_direct(table_res, 0);
   if (strcmp(field->name, "View") != 0)
   {
@@ -3272,6 +3305,17 @@ static my_bool get_view_structure(char *table, char* db)
     DBUG_RETURN(0);
   }
 
+  /* If requested, open separate .sql file for this view */
+  if (path)
+  {
+    if (!(sql_file= open_sql_file_for_table(table)))
+    {
+      safe_exit(EX_MYSQLERR);
+      DBUG_RETURN(1);
+    }
+    write_header(sql_file, db);
+  }
+
   if (!opt_xml && opt_comments)
   {
     fprintf(sql_file, "\n--\n-- View structure for view %s\n--\n\n",
@@ -3287,11 +3331,102 @@ static my_bool get_view_structure(char *table, char* db)
     check_io(sql_file);
   }
 
-  row= mysql_fetch_row(table_res);
-  fprintf(sql_file, "/*!50001 %s*/;\n", row[1]);
-  check_io(sql_file);
-  mysql_free_result(table_res);
 
+  snprintf(query, sizeof(query),
+           "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE "               \
+           "FROM information_schema.views "                             \
+           "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
+  if (mysql_query(sock, query))
+  {
+    /*
+      Use the raw output from SHOW CREATE TABLE if
+       information_schema query fails.
+     */
+    row= mysql_fetch_row(table_res);
+    fprintf(sql_file, "/*!50001 %s */;\n", row[1]);
+    check_io(sql_file);
+    mysql_free_result(table_res);
+  }
+  else
+  {
+    char *ptr;
+    ulong *lengths;
+    char search_buf[256], replace_buf[256];
+    ulong search_len, replace_len;
+    DYNAMIC_STRING ds_view;
+
+    /* Save the result of SHOW CREATE TABLE in ds_view */
+    row= mysql_fetch_row(table_res);
+    lengths= mysql_fetch_lengths(table_res);
+    init_dynamic_string(&ds_view, row[1], lengths[1] + 1, 1024);
+    mysql_free_result(table_res);
+
+    /* Get the result from "select ... information_schema" */
+    if (!(table_res= mysql_store_result(sock)))
+    {
+      safe_exit(EX_MYSQLERR);
+      DBUG_RETURN(1);
+    }
+    row= mysql_fetch_row(table_res);
+    lengths= mysql_fetch_lengths(table_res);
+
+    /*
+      "WITH %s CHECK OPTION" is available from 5.0.2
+      Surround it with !50002 comments
+    */
+    if (strcmp(row[0], "NONE"))
+    {
+
+      ptr= search_buf;
+      search_len= (ulong)(strxmov(ptr, "WITH ", row[0],
+                                  " CHECK OPTION", NullS) - ptr);
+      ptr= replace_buf;
+      replace_len=(ulong)(strxmov(ptr, "*/\n/*!50002 WITH ", row[0],
+                                  " CHECK OPTION", NullS) - ptr);
+      replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
+    }
+
+    /*
+      "DEFINER=%s SQL SECURITY %s" is available from 5.0.13
+      Surround it with !50013 comments
+    */
+    {
+      uint       user_name_len;
+      char       user_name_str[USERNAME_LENGTH + 1];
+      char       quoted_user_name_str[USERNAME_LENGTH * 2 + 3];
+      uint       host_name_len;
+      char       host_name_str[HOSTNAME_LENGTH + 1];
+      char       quoted_host_name_str[HOSTNAME_LENGTH * 2 + 3];
+
+      parse_user(row[1], lengths[1], user_name_str, &user_name_len,
+		 host_name_str, &host_name_len);
+
+      ptr= search_buf;
+      search_len=
+        (ulong)(strxmov(ptr, "DEFINER=",
+                        quote_name(user_name_str, quoted_user_name_str, FALSE),
+                        "@",
+                        quote_name(host_name_str, quoted_host_name_str, FALSE),
+                        " SQL SECURITY ", row[2], NullS) - ptr);
+      ptr= replace_buf;
+      replace_len=
+        (ulong)(strxmov(ptr, "*/\n/*!50013 DEFINER=",
+                        quote_name(user_name_str, quoted_user_name_str, FALSE),
+                        "@",
+                        quote_name(host_name_str, quoted_host_name_str, FALSE),
+                        " SQL SECURITY ", row[2],
+                        " */\n/*!50001", NullS) - ptr);
+      replace(&ds_view, search_buf, search_len, replace_buf, replace_len);
+    }
+
+    /* Dump view structure to file */
+    fprintf(sql_file, "/*!50001 %s */;\n", ds_view.str);
+    check_io(sql_file);
+    mysql_free_result(table_res);
+    dynstr_free(&ds_view);
+  }
+
+  /* If a separate .sql file was opened, close it now */
   if (sql_file != md_result_file)
   {
     fputs("\n", sql_file);
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 717d9f67774..2f4d512d670 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1464,7 +1464,10 @@ DROP TABLE IF EXISTS `v2`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') WITH CASCADED CHECK OPTION*/;
+/*!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 */;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1728,7 +1731,9 @@ DROP TABLE IF EXISTS `v1`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a` from `t1`*/;
+/*!50001 CREATE ALGORITHM=UNDEFINED */
+/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
+/*!50001 VIEW `v1` AS select `t1`.`a` AS `a` from `t1` */;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1784,7 +1789,10 @@ DROP TABLE IF EXISTS `v2`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where (`t2`.`a` like _latin1'a%') WITH CASCADED CHECK OPTION*/;
+/*!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 */;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -1890,13 +1898,19 @@ DROP TABLE IF EXISTS `v3`;
 ) */;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER 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))*/;
+/*!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)) */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v3`.`a` AS `a` from (`v3` join `v1`) where ((`v1`.`a` = `v3`.`a`) and (`v3`.`b` = 3)) limit 1*/;
+/*!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 */;
 /*!50001 DROP TABLE IF EXISTS `v3`*/;
 /*!50001 DROP VIEW IF EXISTS `v3`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1`*/;
+/*!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` */;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -2465,13 +2479,19 @@ CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET l
 USE `test`;
 /*!50001 DROP TABLE IF EXISTS `v0`*/;
 /*!50001 DROP VIEW IF EXISTS `v0`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v0` AS select `v1`.`a` AS `a`,`v1`.`b` AS `b`,`v1`.`c` AS `c` from `v1`*/;
+/*!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` */;
 /*!50001 DROP TABLE IF EXISTS `v1`*/;
 /*!50001 DROP VIEW IF EXISTS `v1`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b`,`t1`.`c` AS `c` from `t1`*/;
+/*!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` */;
 /*!50001 DROP TABLE IF EXISTS `v2`*/;
 /*!50001 DROP VIEW IF EXISTS `v2`*/;
-/*!50001 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `v0`.`a` AS `a`,`v0`.`b` AS `b`,`v0`.`c` AS `c` from `v0`*/;
+/*!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` */;
 /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
 
 /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
@@ -2611,3 +2631,29 @@ UNLOCK TABLES;
 /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
 
 drop table t1;
+create table t1 (a int);
+insert into t1 values (289), (298), (234), (456), (789);
+create definer = CURRENT_USER view v1 as select * from t1;
+create SQL SECURITY INVOKER view v2 as select * from t1;
+create view v3 as select * from t1 with local check option;
+create algorithm=merge view v4 as select * from t1 with cascaded check option;
+create algorithm =temptable view v5 as select * from t1;
+drop table t1;
+drop view v1, v2, v3, v4, v5;
+show tables;
+Tables_in_test
+t1
+v1
+v2
+v3
+v4
+v5
+select * from v3 order by a;
+a
+234
+289
+298
+456
+789
+drop table t1;
+drop view v1, v2, v3, v4, v5;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index e54bf6386c5..95fc1757ad5 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1036,3 +1036,33 @@ insert into t1 values ('','');
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug 14871 Invalid view dump output
+#
+
+create table t1 (a int);
+insert into t1 values (289), (298), (234), (456), (789);
+create definer = CURRENT_USER view v1 as select * from t1;
+create SQL SECURITY INVOKER view v2 as select * from t1;
+create view v3 as select * from t1 with local check option;
+create algorithm=merge view v4 as select * from t1 with cascaded check option;
+create algorithm =temptable view v5 as select * from t1;
+
+# dump tables and views
+--exec $MYSQL_DUMP test > var/tmp/bug14871.sql
+
+# drop the db, tables and views
+drop table t1;
+drop view v1, v2, v3, v4, v5;
+
+# Reload dump
+--exec $MYSQL test < var/tmp/bug14871.sql
+
+# check that all tables and views could be created
+show tables;
+select * from v3 order by a;
+
+drop table t1;
+drop view v1, v2, v3, v4, v5;
+

From 8a1dd17b5ed0330030a66f66f2e9400173c078cf Mon Sep 17 00:00:00 2001
From: unknown <petr@mysql.com>
Date: Tue, 21 Feb 2006 15:32:52 +0300
Subject: [PATCH 038/103] Fix for Bug #12674  "Instance Manager: IM doesn't
 handle client connections correctly". Recommit with the max timeout value in
 sync with the comment.

server-tools/instance-manager/options.cc:
  add new option to set wait timeout
server-tools/instance-manager/priv.h:
  add a const for max wait timeout
---
 server-tools/instance-manager/options.cc | 6 ++++++
 server-tools/instance-manager/priv.h     | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
index 8119e8fc0ea..e7d366e7457 100644
--- a/server-tools/instance-manager/options.cc
+++ b/server-tools/instance-manager/options.cc
@@ -79,6 +79,7 @@ enum options {
 #endif
   OPT_MONITORING_INTERVAL,
   OPT_PORT,
+  OPT_WAIT_TIMEOUT,
   OPT_BIND_ADDRESS
 };
 
@@ -151,6 +152,11 @@ static struct my_option my_long_options[] =
   { "version", 'V', "Output version information and exit.", 0, 0, 0,
     GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
 
+  { "wait-timeout", OPT_WAIT_TIMEOUT, "The number of seconds IM waits "
+    "for activity on a connection before closing it.",
+    (gptr *) &net_read_timeout, (gptr *) &net_read_timeout, 0, GET_ULONG,
+    REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0 },
+
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
 };
 
diff --git a/server-tools/instance-manager/priv.h b/server-tools/instance-manager/priv.h
index af6d2837933..52d7aa1d23d 100644
--- a/server-tools/instance-manager/priv.h
+++ b/server-tools/instance-manager/priv.h
@@ -28,6 +28,8 @@
 #define SERVER_DEFAULT_PORT 3306
 #define DEFAULT_MONITORING_INTERVAL 20
 #define DEFAULT_PORT 2273
+/* three-week timeout should be enough */
+#define LONG_TIMEOUT ((ulong) 3600L*24L*21L)
 
 /* the pid of the manager process (of the signal thread on the LinuxThreads) */
 extern pid_t manager_pid;

From 1f12107f00c8a6ce946dccd60e53f0de66736a1e Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Tue, 21 Feb 2006 13:43:29 +0100
Subject: [PATCH 039/103] Bug#14857 Reading dump files with single statement
 stored routines fails.Bug #14857  	Reading dump files with single
 statement stored routines fails.  - Add tests, fixed by patch for 16878

mysql-test/r/mysqldump.result:
  Update test results
mysql-test/t/mysqldump.test:
  Add tests for bug 14857
---
 mysql-test/r/mysqldump.result | 14 ++++++++++++++
 mysql-test/t/mysqldump.test   | 18 ++++++++++++++++++
 2 files changed, 32 insertions(+)

diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 46056edcd5e..01d90cb0901 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -2633,3 +2633,17 @@ end	AFTER	#		root@localhost
 drop trigger tr1;
 drop trigger tr2;
 drop table t1, t2;
+/*!50003 CREATE FUNCTION `f`() RETURNS bigint(20)
+return 42 */|
+/*!50003 CREATE PROCEDURE `p`()
+select 42 */|
+show create function f;
+Function	sql_mode	Create Function
+f		CREATE FUNCTION `f`() RETURNS bigint(20)
+return 42
+show create procedure p;
+Procedure	sql_mode	Create Procedure
+p		CREATE PROCEDURE `p`()
+select 42
+drop function f;
+drop procedure p;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index caa1ae0d837..b76c82958f2 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1066,3 +1066,21 @@ show triggers;
 drop trigger tr1;
 drop trigger tr2;
 drop table t1, t2;
+
+
+#
+# Bug#14857 Reading dump files with single statement stored routines fails.
+# fixed by patch for bug#16878
+#
+#
+DELIMITER |;
+/*!50003 CREATE FUNCTION `f`() RETURNS bigint(20)
+return 42 */|
+/*!50003 CREATE PROCEDURE `p`()
+select 42 */|
+DELIMITER ;|
+show create function f;
+show create procedure p;
+drop function f;
+drop procedure p;
+

From 21aa5867142d421b34a3f04820fea6e6a9ea527c Mon Sep 17 00:00:00 2001
From: unknown <petr@mysql.com>
Date: Tue, 21 Feb 2006 15:57:56 +0300
Subject: [PATCH 040/103] Fix race condition: instance map wasn't locked for
 the duration of the whole 'flush instances'. As a consequence, it was
 possible to query instance map, while it is in the inconsistent state. The
 patch was reworked after review.

server-tools/instance-manager/guardian.cc:
  do not lock instance map in Guardian_thread::init()
server-tools/instance-manager/instance_map.cc:
  Eliminate race condition: lock instance map and guardian
  for the duration of the whole "FLUSH INSTANCES" execution.
server-tools/instance-manager/instance_map.h:
  add new method. cleanup interface. add comments.
server-tools/instance-manager/manager.cc:
  use instance_map.flush_instances instead of instance_map.load() and guardian_thread.init()
---
 server-tools/instance-manager/guardian.cc     |  2 -
 server-tools/instance-manager/instance_map.cc | 83 +++++++++++++++----
 server-tools/instance-manager/instance_map.h  | 17 ++--
 server-tools/instance-manager/manager.cc      | 22 ++---
 4 files changed, 85 insertions(+), 39 deletions(-)

diff --git a/server-tools/instance-manager/guardian.cc b/server-tools/instance-manager/guardian.cc
index 291b685ef1b..7a532263846 100644
--- a/server-tools/instance-manager/guardian.cc
+++ b/server-tools/instance-manager/guardian.cc
@@ -256,7 +256,6 @@ int Guardian_thread::init()
   Instance *instance;
   Instance_map::Iterator iterator(instance_map);
 
-  instance_map->lock();
   /* clear the list of guarded instances */
   free_root(&alloc, MYF(0));
   init_alloc_root(&alloc, MEM_ROOT_BLOCK_SIZE, 0);
@@ -272,7 +271,6 @@ int Guardian_thread::init()
       }
   }
 
-  instance_map->unlock();
   return 0;
 }
 
diff --git a/server-tools/instance-manager/instance_map.cc b/server-tools/instance-manager/instance_map.cc
index 611eda457f2..883be15b571 100644
--- a/server-tools/instance-manager/instance_map.cc
+++ b/server-tools/instance-manager/instance_map.cc
@@ -80,19 +80,44 @@ static void delete_instance(void *u)
 static int process_option(void *ctx, const char *group, const char *option)
 {
   Instance_map *map= NULL;
+
+  map = (Instance_map*) ctx;
+  return map->process_one_option(group, option);
+}
+
+C_MODE_END
+
+
+/*
+  Process one option from the configuration file.
+
+  SYNOPSIS
+    Instance_map::process_one_option()
+      group         group name
+      option        option string (e.g. "--name=value")
+
+  DESCRIPTION
+    This is an auxiliary function and should not be used externally.
+    It is used only by flush_instances(), which pass it to
+    process_option(). The caller ensures proper locking
+    of the instance map object.
+*/
+
+int Instance_map::process_one_option(const char *group, const char *option)
+{
   Instance *instance= NULL;
   static const char prefix[]= { 'm', 'y', 's', 'q', 'l', 'd' };
 
-  map = (Instance_map*) ctx;
   if (strncmp(group, prefix, sizeof prefix) == 0 &&
       ((my_isdigit(default_charset_info, group[sizeof prefix]))
        || group[sizeof(prefix)] == '\0'))
     {
-      if ((instance= map->find(group, strlen(group))) == NULL)
+      if (!(instance= (Instance *) hash_search(&hash, (byte *) group,
+                                               strlen(group))))
       {
-        if ((instance= new Instance) == 0)
+        if (!(instance= new Instance))
           goto err;
-        if (instance->init(group) || map->add_instance(instance))
+        if (instance->init(group) || my_hash_insert(&hash, (byte *) instance))
           goto err_instance;
       }
 
@@ -108,8 +133,6 @@ err:
   return 1;
 }
 
-C_MODE_END
-
 
 Instance_map::Instance_map(const char *default_mysqld_path_arg):
 mysqld_path(default_mysqld_path_arg)
@@ -144,30 +167,61 @@ void Instance_map::unlock()
   pthread_mutex_unlock(&LOCK_instance_map);
 }
 
+/*
+  Re-read instance configuration file.
+
+  SYNOPSIS
+    Instance_map::flush_instances()
+
+  DESCRIPTION
+    This function will:
+     - clear the current list of instances. This removes both
+       running and stopped instances.
+     - load a new instance configuration from the file.
+     - pass on the new map to the guardian thread: it will start
+       all instances that are marked `guarded' and not yet started.
+    Note, as the check whether an instance is started is currently
+    very simple (returns true if there is a MySQL server running
+    at the given port), this function has some peculiar
+    side-effects:
+     * if the port number of a running instance was changed, the
+       old instance is forgotten, even if it was running. The new
+       instance will be started at the new port.
+     * if the configuration was changed in a way that two
+       instances swapped their port numbers, the guardian thread
+       will not notice that and simply report that both instances
+       are configured successfully and running.
+    In order to avoid such side effects one should never call
+    FLUSH INSTANCES without prior stop of all running instances.
+
+  TODO
+    FLUSH INSTANCES should return an error if it's called
+    while there is a running instance.
+*/
 
 int Instance_map::flush_instances()
 {
   int rc;
 
+  /*
+    Guardian thread relies on the instance map repository for guarding
+    instances. This is why refreshing instance map, we need (1) to stop
+    guardian (2) reload the instance map (3) reinitialize the guardian
+    with new instances.
+  */
   guardian->lock();
   pthread_mutex_lock(&LOCK_instance_map);
   hash_free(&hash);
   hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
             get_instance_key, delete_instance, 0);
-  pthread_mutex_unlock(&LOCK_instance_map);
   rc= load();
   guardian->init();
+  pthread_mutex_unlock(&LOCK_instance_map);
   guardian->unlock();
   return rc;
 }
 
 
-int Instance_map::add_instance(Instance *instance)
-{
-  return my_hash_insert(&hash, (byte *) instance);
-}
-
-
 Instance *
 Instance_map::find(const char *name, uint name_len)
 {
@@ -190,10 +244,9 @@ int Instance_map::complete_initialization()
     if ((instance= new Instance) == 0)
       goto err;
 
-    if (instance->init("mysqld") || add_instance(instance))
+    if (instance->init("mysqld") || my_hash_insert(&hash, (byte *) instance))
       goto err_instance;
 
-
     /*
       After an instance have been added to the instance_map,
       hash_free should handle it's deletion => goto err, not
diff --git a/server-tools/instance-manager/instance_map.h b/server-tools/instance-manager/instance_map.h
index 51971db4c2f..d3de42f4d80 100644
--- a/server-tools/instance-manager/instance_map.h
+++ b/server-tools/instance-manager/instance_map.h
@@ -63,21 +63,24 @@ public:
   void lock();
   void unlock();
   int init();
+  /*
+    Process a given option and assign it to appropricate instance. This is
+    required for the option handler, passed to my_search_option_files().
+  */
+  int process_one_option(const char *group, const char *option);
 
   Instance_map(const char *default_mysqld_path_arg);
   ~Instance_map();
 
-  /* loads options from config files */
-  int load();
-  /* adds instance to internal hash */
-  int add_instance(Instance *instance);
-  /* inits instances argv's after all options have been loaded */
-  int complete_initialization();
-
 public:
   const char *mysqld_path;
   Guardian_thread *guardian;
 
+private:
+  /* loads options from config files */
+  int load();
+  /* inits instances argv's after all options have been loaded */
+  int complete_initialization();
 private:
   enum { START_HASH_SIZE = 16 };
   pthread_mutex_t LOCK_instance_map;
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index 3ecd5fbc0d0..95f9029f648 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -135,15 +135,6 @@ void manager(const Options &options)
   if (instance_map.init() || user_map.init())
     return;
 
-
-  if (instance_map.load())
-  {
-    log_error("Cannot init instances repository. This might be caused by "
-               "the wrong config file options. For instance, missing mysqld "
-               "binary. Aborting.");
-    return;
-  }
-
   if (user_map.load(options.password_file_name))
     return;
 
@@ -207,12 +198,13 @@ void manager(const Options &options)
 
   shutdown_complete= FALSE;
 
-  /* init list of guarded instances */
-  guardian_thread.lock();
-
-  guardian_thread.init();
-
-  guardian_thread.unlock();
+  if (instance_map.flush_instances())
+  {
+    log_error("Cannot init instances repository. This might be caused by "
+               "the wrong config file options. For instance, missing mysqld "
+               "binary. Aborting.");
+    return;
+  }
 
   /*
     After the list of guarded instances have been initialized,

From 71ee8615c34db5299d51bc440309371ea08b5923 Mon Sep 17 00:00:00 2001
From: unknown <evgen@moonbone.local>
Date: Tue, 21 Feb 2006 18:09:32 +0300
Subject: [PATCH 041/103] Fixed bug#17530: Incorrect key truncation on table
 creation caused server crash.

When a too long field is used for a key, only a prefix part of the field is
used. Length is reduced to the max key length allowed for storage. But if the
field have a multibyte charset it is possible to break multibyte char
sequence. This leads to the failed assertion in the innodb code and
server crash when a record is inserted.

The make_prepare_table() now aligns truncated key length to the boundary of
multibyte char.


mysql-test/t/create.test:
  Added test case for bug#17530: Incorrect key truncation on table creation caused server crash.
mysql-test/r/create.result:
  Added test case for bug#17530: Incorrect key truncation on table creation caused server crash.
sql/sql_table.cc:
  Fixed bug#17530: Incorrect key truncation on table creation caused server crash.
  The make_prepare_table() now aligns truncated key length to the boundary of
  multibyte char.
---
 mysql-test/r/create.result | 6 ++++++
 mysql-test/t/create.test   | 8 ++++++++
 sql/sql_table.cc           | 4 +++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result
index 848b84e2b8c..8c1943486b5 100644
--- a/mysql-test/r/create.result
+++ b/mysql-test/r/create.result
@@ -765,3 +765,9 @@ t1	CREATE TABLE `t1` (
   `i` int(11) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=4294967295
 drop table t1;
+create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb 
+character set utf8 collate utf8_general_ci;
+Warnings:
+Warning	1071	Specified key was too long; max key length is 765 bytes
+insert into t1 values('aaa');
+drop table t1;
diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test
index f7b9002faa0..9fcbb53e24d 100644
--- a/mysql-test/t/create.test
+++ b/mysql-test/t/create.test
@@ -660,4 +660,12 @@ alter table t1 max_rows=100000000000;
 show create table t1;
 drop table t1;
 
+#
+# Bug#17530: Incorrect key truncation on table creation caused server crash.
+#
+create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb 
+  character set utf8 collate utf8_general_ci;
+insert into t1 values('aaa');
+drop table t1;
+
 # End of 5.0 tests
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index de350b83985..a84d70f7835 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1299,7 +1299,9 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
       }
       if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
       {
-	length=file->max_key_part_length();
+        length= file->max_key_part_length();
+        /* Align key length to multibyte char boundary */
+        length-= length % sql_field->charset->mbmaxlen;
 	if (key->type == Key::MULTIPLE)
 	{
 	  /* not a critical problem */

From 9cf3f255bded9642b6b6b23b4510514c08bcbe84 Mon Sep 17 00:00:00 2001
From: unknown <konstantin@mysql.com>
Date: Tue, 21 Feb 2006 19:52:20 +0300
Subject: [PATCH 042/103] A fix and a test case for Bug#13134 "Length of
 VARCHAR() utf8 column is increasing when table is recreated with PS/SP": make
 use of create_field::char_length more consistent in the code. Reinit
 create_field::length from create_field::char_length for every execution of a
 prepared statement (actually fixes the bug).

mysql-test/r/ps.result:
  Test results fixed (Bug#13134)
mysql-test/t/ps.test:
  A test case for Bug#13134 "Length of VARCHAR() utf8 column is
  increasing when table is recreated with PS/SP"
sql/field.cc:
  Move initialization of create_field::char_length to the constructor
  of create_field.
sql/field.h:
  Rename chars_length to char_length (to be consistent with
  how this term is used throughout the rest of the code).
sql/sql_parse.cc:
  Initialize char_length in add_field_to_list. This function
  effectively works as another create_field constructor.
sql/sql_table.cc:
  Reinit length from char_length for every field in
  mysql_prepare_table. This is not needed if we're executing
  a statement for the first time, however, at subsequent executions
  length contains the number of bytes, not characters (as it's expected
  to).
---
 mysql-test/r/ps.result | 17 +++++++++++++++++
 mysql-test/t/ps.test   | 24 +++++++++++++++++++++++-
 sql/field.cc           |  5 ++---
 sql/field.h            |  2 +-
 sql/sql_parse.cc       |  2 ++
 sql/sql_table.cc       |  8 +++++++-
 6 files changed, 52 insertions(+), 6 deletions(-)

diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index ba9336c20bb..5404681e222 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -733,3 +733,20 @@ count(*)
 5
 deallocate prepare stmt;
 drop table t1;
+drop table if exists t1;
+Warnings:
+Note	1051	Unknown table 't1'
+prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+deallocate prepare stmt;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index b0755d06414..b1f6be819d4 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -763,5 +763,27 @@ execute stmt using @like;
 deallocate prepare stmt;
 drop table t1;
 
-# End of 4.1 tests
 
+#
+# Bug#13134 "Length of VARCHAR() utf8 column is increasing when table is
+# recreated with PS/SP"
+#
+
+drop table if exists t1;
+prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
+execute stmt;
+--disable_warnings
+insert into t1 (a) values (repeat('a', 20));
+--enable_warnings
+select length(a) from t1;
+drop table t1;
+execute stmt;
+--disable_warnings
+insert into t1 (a) values (repeat('a', 20));
+--enable_warnings
+# Check that the data is truncated to the same length
+select length(a) from t1;
+drop table t1;
+deallocate prepare stmt;
+
+# End of 4.1 tests
diff --git a/sql/field.cc b/sql/field.cc
index b1d9167aee2..fd6eba9e492 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -6516,13 +6516,11 @@ bool Field_num::eq_def(Field *field)
     create_field::create_length_to_internal_length()
   
   DESCRIPTION
-    Convert create_field::length from number of characters to number of bytes,
-    save original value in chars_length.
+    Convert create_field::length from number of characters to number of bytes.
 */
 
 void create_field::create_length_to_internal_length(void)
 {
-  chars_length= length;
   switch (sql_type) {
   case MYSQL_TYPE_TINY_BLOB:
   case MYSQL_TYPE_MEDIUM_BLOB:
@@ -6775,6 +6773,7 @@ create_field::create_field(Field *old_field,Field *orig_field)
       break;
   }
 
+  char_length= length;
   decimals= old_field->decimals();
   if (sql_type == FIELD_TYPE_STRING)
   {
diff --git a/sql/field.h b/sql/field.h
index 04f1bd68c7a..966549516b1 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1188,7 +1188,7 @@ public:
   /*
     The value of 'length' before a call to create_length_to_internal_length
   */
-  uint32 chars_length;
+  uint32 char_length;
   uint decimals,flags,pack_length;
   Field::utype unireg_check;
   TYPELIB *interval;			// Which interval to use
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 1daa0a5ffec..21a335637b9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4480,6 +4480,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
 						  NOT_FIXED_DEC-1) : 0;
   new_field->sql_type=type;
   new_field->length=0;
+  new_field->char_length= 0;
   new_field->change=change;
   new_field->interval=0;
   new_field->pack_length=0;
@@ -4750,6 +4751,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
 					    FIELD_TYPE_STRING :
 					    new_field->sql_type,
 					    new_field->length);
+  new_field->char_length= new_field->length;
   lex->create_list.push_back(new_field);
   lex->last_field=new_field;
   DBUG_RETURN(0);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 71cbc0be1e3..616db8b0424 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -488,6 +488,12 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
 
   for (field_no=0; (sql_field=it++) ; field_no++)
   {
+    /*
+      Initialize length from its original value (number of characters),
+      which was set in the parser. This is necessary if we're
+      executing a prepared statement for the second time.
+    */
+    sql_field->length= sql_field->char_length;
     if (!sql_field->charset)
       sql_field->charset= create_info->default_table_charset;
     /*
@@ -665,7 +671,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
 	  sql_field->charset=		(dup_field->charset ?
 					 dup_field->charset :
 					 create_info->default_table_charset);
-	  sql_field->length=		dup_field->chars_length;
+	  sql_field->length=		dup_field->char_length;
           sql_field->pack_length=	dup_field->pack_length;
 	  sql_field->create_length_to_internal_length();
 	  sql_field->decimals=		dup_field->decimals;

From 475797a34622bb740409238f9ee63a5777476b4f Mon Sep 17 00:00:00 2001
From: unknown <timour@mysql.com>
Date: Wed, 22 Feb 2006 10:04:10 +0200
Subject: [PATCH 043/103] Fix for BUG#17523: natural join and information
 schema.

The cause of the bug was an ASSERT that checked the consistency
of TABLE_SHARE::db and TABLE_LIST::db and failed for I_S tables.
The fix relaxes the requirement for consistency for I_S.


mysql-test/r/join.result:
  Added test for BUG#17523
mysql-test/t/join.test:
  Added test for BUG#17523
sql/table.cc:
  Take into account that for I_S tables, TABLE_SHARE::db == 0,
  while TABLE_LIST::db contains the database name of a table.
  The only change is in the ASSERTs.
---
 mysql-test/r/join.result |  5 +++++
 mysql-test/t/join.test   |  6 ++++++
 sql/table.cc             | 19 +++++++++++++++++--
 3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index 724d1b1e39f..54536d6c32a 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -677,6 +677,11 @@ select t1.b from v1a;
 ERROR 42S22: Unknown column 't1.b' in 'field list'
 select * from v1a join v1b on t1.b = t2.b;
 ERROR 42S22: Unknown column 't1.b' in 'on clause'
+select * from information_schema.statistics join information_schema.columns
+using(table_name,column_name) where table_name='user';
+TABLE_NAME	COLUMN_NAME	TABLE_CATALOG	TABLE_SCHEMA	NON_UNIQUE	INDEX_SCHEMA	INDEX_NAME	SEQ_IN_INDEX	COLLATION	CARDINALITY	SUB_PART	PACKED	NULLABLE	INDEX_TYPE	COMMENT	TABLE_CATALOG	TABLE_SCHEMA	ORDINAL_POSITION	COLUMN_DEFAULT	IS_NULLABLE	DATA_TYPE	CHARACTER_MAXIMUM_LENGTH	CHARACTER_OCTET_LENGTH	NUMERIC_PRECISION	NUMERIC_SCALE	CHARACTER_SET_NAME	COLLATION_NAME	COLUMN_TYPE	COLUMN_KEY	EXTRA	PRIVILEGES	COLUMN_COMMENT
+user	Host	NULL	mysql	0	mysql	PRIMARY	1	A	NULL	NULL	NULL		BTREE		NULL	mysql	1		NO	char	20	60	NULL	NULL	utf8	utf8_bin	char(60)	PRI		select,insert,update,references	
+user	User	NULL	mysql	0	mysql	PRIMARY	2	A	5	NULL	NULL		BTREE		NULL	mysql	2		NO	char	5	16	NULL	NULL	utf8	utf8_bin	char(16)	PRI		select,insert,update,references	
 drop table t1;
 drop table t2;
 drop table t3;
diff --git a/mysql-test/t/join.test b/mysql-test/t/join.test
index 553aaf987bb..90abc61ca07 100644
--- a/mysql-test/t/join.test
+++ b/mysql-test/t/join.test
@@ -523,6 +523,12 @@ select t1.b from v1a;
 -- error 1054
 select * from v1a join v1b on t1.b = t2.b;
 
+#
+# Bug #17523 natural join and information_schema
+#
+select * from information_schema.statistics join information_schema.columns
+              using(table_name,column_name) where table_name='user';
+
 drop table t1;
 drop table t2;
 drop table t3;
diff --git a/sql/table.cc b/sql/table.cc
index 9ae5348b5c6..1a2c2b8f073 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -2595,8 +2595,15 @@ const char *Natural_join_column::db_name()
   if (view_field)
     return table_ref->view_db.str;
 
+  /*
+    Test that TABLE_LIST::db is the same as st_table_share::db to
+    ensure consistency. An exception are I_S schema tables, which
+    are inconsistent in this respect.
+  */
   DBUG_ASSERT(!strcmp(table_ref->db,
-                      table_ref->table->s->db));
+                      table_ref->table->s->db) ||
+              (table_ref->schema_table &&
+               table_ref->table->s->db[0] == 0));
   return table_ref->db;
 }
 
@@ -2798,7 +2805,15 @@ const char *Field_iterator_table_ref::db_name()
   else if (table_ref->is_natural_join)
     return natural_join_it.column_ref()->db_name();
 
-  DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db));
+  /*
+    Test that TABLE_LIST::db is the same as st_table_share::db to
+    ensure consistency. An exception are I_S schema tables, which
+    are inconsistent in this respect.
+  */
+  DBUG_ASSERT(!strcmp(table_ref->db, table_ref->table->s->db) ||
+              (table_ref->schema_table &&
+               table_ref->table->s->db[0] == 0));
+
   return table_ref->db;
 }
 

From 85e54a08c4fc468ab89f8df27bc981027cb22e6c Mon Sep 17 00:00:00 2001
From: unknown <anozdrin@mysql.com>
Date: Wed, 22 Feb 2006 13:44:04 +0300
Subject: [PATCH 044/103] Fix for BUG#7787: Stored procedures: improper warning
 for "grant execute" statement.

The problem was that error flag was not reset.


mysql-test/r/sp-security.result:
  Results for test case for BUG#7787.
mysql-test/t/sp-security.test:
  A test case for BUG#7787.
sql/sp.cc:
  Reset errors after sp_find_routine().
---
 mysql-test/r/sp-security.result |  9 +++++++++
 mysql-test/t/sp-security.test   | 22 ++++++++++++++++++++++
 sql/sp.cc                       | 11 +++++++----
 3 files changed, 38 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result
index ff729e87f97..d8abc387677 100644
--- a/mysql-test/r/sp-security.result
+++ b/mysql-test/r/sp-security.result
@@ -314,3 +314,12 @@ select * from db_bug14533.t1;
 ERROR 42000: SELECT command denied to user 'user_bug14533'@'localhost' for table 't1'
 drop user user_bug14533@localhost;
 drop database db_bug14533;
+CREATE DATABASE db_bug7787;
+use db_bug7787;
+CREATE PROCEDURE p1()
+SHOW INNODB STATUS;
+Warnings:
+Warning	1287	'SHOW INNODB STATUS' is deprecated; use 'SHOW ENGINE INNODB STATUS' instead
+GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost;
+DROP DATABASE db_bug7787;
+use test;
diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test
index 90160780618..19f94a32d9c 100644
--- a/mysql-test/t/sp-security.test
+++ b/mysql-test/t/sp-security.test
@@ -525,4 +525,26 @@ disconnect user_bug14533;
 drop user user_bug14533@localhost;
 drop database db_bug14533;
 
+
+#
+# BUG#7787: Stored procedures: improper warning for "grant execute" statement
+#
+
+# Prepare.
+
+CREATE DATABASE db_bug7787;
+use db_bug7787;
+
+# Test.
+
+CREATE PROCEDURE p1()
+  SHOW INNODB STATUS; 
+
+GRANT EXECUTE ON PROCEDURE p1 TO user_bug7787@localhost; 
+
+# Cleanup.
+
+DROP DATABASE db_bug7787;
+use test;
+
 # End of 5.0 bugs.
diff --git a/sql/sp.cc b/sql/sp.cc
index fe249141fea..ce0282bf810 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -1012,6 +1012,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
 {
   TABLE_LIST *routine;
   bool result= 0;
+  bool sp_object_found;
   DBUG_ENTER("sp_exists_routine");
   for (routine= routines; routine; routine= routine->next_global)
   {
@@ -1024,10 +1025,12 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error)
     lex_name.str= thd->strmake(routine->table_name, lex_name.length);
     name= new sp_name(lex_db, lex_name);
     name->init_qname(thd);
-    if (sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
-                        &thd->sp_proc_cache, FALSE) != NULL ||
-        sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
-                        &thd->sp_func_cache, FALSE) != NULL)
+    sp_object_found= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
+                                     &thd->sp_proc_cache, FALSE) != NULL ||
+                     sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
+                                     &thd->sp_func_cache, FALSE) != NULL;
+    mysql_reset_errors(thd, TRUE);
+    if (sp_object_found)
     {
       if (any)
         DBUG_RETURN(1);

From 0d3cf6b0fd51ee0f2b1d1988db99add17df766f8 Mon Sep 17 00:00:00 2001
From: unknown <aelkin@mysql.com>
Date: Wed, 22 Feb 2006 17:07:18 +0200
Subject: [PATCH 045/103] BUG#17265 Assertion failure in rpl_row_view01. To
 quote Timour review lines:

The actual cause of the bug is that sql_base.cc:setup_wild()
sets "select_lex->with_wild = 0" (in the end of the function) once
it expands all wild-cards, and wild-card expansion is done during
the prepare phase. During this phase we replace all "*" with the
corresponding items, which for views happen to be references to
references. When we do execute, select_lex->with_wild = 0, and
all "*" are already replaced by the corresponding items, which
in the case of views need to be dereferenced first.

Fixed by refining the assert. Regression test for the bug is rpl_row_view01,
as was reported.


sql/item.cc:
  Refined asssert, suggested by Evgen, due to BUG#17265 prepared statement for select with ps-protocol
  does not hold the former.
---
 sql/item.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/sql/item.cc b/sql/item.cc
index fbdb217f5df..367452444d2 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5116,9 +5116,9 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
     if (item_ref->ref_type() == VIEW_REF)
     {
       Item *item_ref_ref= *(item_ref->ref);
-      DBUG_ASSERT((*ref)->type() == FIELD_ITEM &&
-                  (item_ref_ref->type() == FIELD_ITEM));
-      return (*ref == item_ref_ref);
+      DBUG_ASSERT((*ref)->real_item()->type() == FIELD_ITEM &&
+                  (item_ref_ref->real_item()->type() == FIELD_ITEM));
+      return ((*ref)->real_item() == item_ref_ref->real_item());
     }
   }
   return FALSE;

From 44e286d215a8aab474c98c32a7c3896a581a0a10 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 23 Feb 2006 10:11:57 +0100
Subject: [PATCH 046/103] Add new parameter to do_eval so that only unescaped
 variables in input string is expanded and rest of string is left untouched.

client/mysqltest.c:
  Add new parameter to 'do_eval' that will add any escape chars found in the input string to the output string.
  This is used in 'do_system' and in 'do_exec' where only unescaped variables
  will be expanded, rest of the string will be left untouched.
mysql-test/r/mysqltest.result:
  Update test result
mysql-test/t/mysqldump.test:
  Revert previous patch that added extra \\ in "exec" command
mysql-test/t/mysqltest.test:
  Revert previous patch that added extra \\ in exec command
---
 client/mysqltest.c            | 20 ++++++++++++++------
 mysql-test/r/mysqltest.result |  2 +-
 mysql-test/t/mysqldump.test   |  2 +-
 mysql-test/t/mysqltest.test   | 26 +++++++++++++-------------
 4 files changed, 29 insertions(+), 21 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6bf361c17aa..30cb1839c7a 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -457,7 +457,8 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
 static void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds,
                                    const char *from, int len);
 void free_pointer_array(POINTER_ARRAY *pa);
-static void do_eval(DYNAMIC_STRING *query_eval, const char *query);
+static void do_eval(DYNAMIC_STRING *query_eval, const char *query,
+                    my_bool pass_through_escape_chars);
 static void str_to_file(const char *fname, char *str, int size);
 
 #ifdef __WIN__
@@ -489,7 +490,8 @@ static void handle_error(const char *query, struct st_query *q,
 			 const char *err_sqlstate, DYNAMIC_STRING *ds);
 static void handle_no_error(struct st_query *q);
 
-static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
+static void do_eval(DYNAMIC_STRING* query_eval, const char *query,
+                    my_bool pass_through_escape_chars)
 {
   const char *p;
   register char c, next_c;
@@ -524,6 +526,12 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
       {
         /* Set escaped only if next char is \ or $ */
 	escaped = 1;
+
+        if (pass_through_escape_chars)
+        {
+          /* The escape char should be added to the output string. */
+          dynstr_append_mem(query_eval, p, 1);
+        }
       }
       else
 	dynstr_append_mem(query_eval, p, 1);
@@ -713,7 +721,7 @@ static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
   init_dynamic_string(&res_ds, "", 0, 65536);
   if (eval_result)
   {
-    do_eval(&res_ds, tmp);
+    do_eval(&res_ds, tmp, FALSE);
     res_ptr = res_ds.str;
     if ((res_len = res_ds.length) != ds->length)
     {
@@ -1085,7 +1093,7 @@ static void do_exec(struct st_query *query)
 
   init_dynamic_string(&ds_cmd, 0, strlen(cmd)+256, 256);
   /* Eval the command, thus replacing all environment variables */
-  do_eval(&ds_cmd, cmd);
+  do_eval(&ds_cmd, cmd, TRUE);
   cmd= ds_cmd.str;
 
   DBUG_PRINT("info", ("Executing '%s' as '%s'",
@@ -1379,7 +1387,7 @@ int do_system(struct st_query *command)
   init_dynamic_string(&ds_cmd, 0, strlen(command->first_argument) + 64, 256);
 
   /* Eval the system command, thus replacing all environment variables */
-  do_eval(&ds_cmd, command->first_argument);
+  do_eval(&ds_cmd, command->first_argument, TRUE);
 
   DBUG_PRINT("info", ("running system command '%s' as '%s'",
                       command->first_argument, ds_cmd.str));
@@ -3984,7 +3992,7 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags)
   if (command->type == Q_EVAL)
   {
     init_dynamic_string(&eval_query, "", 16384, 65536);
-    do_eval(&eval_query, command->query);
+    do_eval(&eval_query, command->query, FALSE);
     query = eval_query.str;
     query_len = eval_query.length;
   }
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 067054510c2..d2114280a84 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -218,7 +218,7 @@ mysqltest: At line 1: Missing variable name in let
 mysqltest: At line 1: Variable name in hi=hi does not start with '$'
 mysqltest: At line 1: Missing assignment operator in let
 mysqltest: At line 1: Missing assignment operator in let
-mysqltest: At line 1: Missing arguments to let
+mysqltest: At line 1: Missing assignment operator in let
 mysqltest: At line 1: Missing variable name in let
 mysqltest: At line 1: Variable name in =hi does not start with '$'
 mysqltest: At line 1: Missing assignment operator in let
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index d5e48387203..0564ee9964c 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -647,7 +647,7 @@ select '------ Testing with illegal table names ------' as test_sequence ;
 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\t1" 2>&1
  
 --error 6
---exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\\\\\t1" 2>&1
+--exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "\\\\t1" 2>&1
 
 --error 6
 --exec $MYSQL_DUMP --compact --skip-comments mysqldump_test_db  "t\1" 2>&1
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 50f8c02dbae..3726d6b8096 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -678,7 +678,7 @@ echo $i;
 --error 1
 --exec echo "inc i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \\\$i=100; inc \\\$i 1000; echo \\\$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \$i=100; inc \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1
 
 inc $i; inc $i; inc $i; --echo $i
 echo $i;
@@ -706,7 +706,7 @@ echo $d;
 --error 1
 --exec echo "dec i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \\\$i=100; dec \\\$i 1000; echo \\\$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \$i=100; dec \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1
 
 
 # ----------------------------------------------------------------------------
@@ -761,11 +761,11 @@ while ($i)
 --error 1
 --exec echo "source include/mysqltest_while.inc;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "while \\\$i;" | $MYSQL_TEST 2>&1
+--exec echo "while \$i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "while (\\\$i;" | $MYSQL_TEST 2>&1
+--exec echo "while (\$i;" | $MYSQL_TEST 2>&1
 --error 1
---exec echo "let \\\$i=1; while (\\\$i) dec \\\$i;" | $MYSQL_TEST 2>&1
+--exec echo "let \$i=1; while (\$i) dec \$i;" | $MYSQL_TEST 2>&1
 --error 1
 --exec echo "};" | $MYSQL_TEST 2>&1
 --error 1
@@ -877,22 +877,22 @@ select "a" as col1, "c" as col2;
 --exec echo "connect (con1,localhost,root,,,,,SMTP POP);" | $MYSQL_TEST 2>&1
 
 # Repeat connect/disconnect
---exec echo "let \\\$i=100;"                            > var/tmp/con.sql
---exec echo "while (\\\$i)"                            >> var/tmp/con.sql
+--exec echo "let  \$i=100;"                             > var/tmp/con.sql
+--exec echo "while (\$i)"                              >> var/tmp/con.sql
 --exec echo "{"                                        >> var/tmp/con.sql
---exec echo " connect (test_con1,localhost,root,,); "  >> var/tmp/con.sql
+--exec echo " connect (test_con1,localhost,root,,);  " >> var/tmp/con.sql
 --exec echo " disconnect test_con1; "                  >> var/tmp/con.sql
---exec echo " dec \\\$i;                             " >> var/tmp/con.sql
+--exec echo " dec \$i;                               " >> var/tmp/con.sql
 --exec echo "}"                                        >> var/tmp/con.sql
 --exec echo "source var/tmp/con.sql; echo OK;" | $MYSQL_TEST 2>&1
 
 # Repeat connect/disconnect, exceed max number of connections
---exec echo "let \\\$i=200;"                            > var/tmp/con.sql
---exec echo "while (\\\$i)"                            >> var/tmp/con.sql
+--exec echo "let \$i=200;"                              > var/tmp/con.sql
+--exec echo "while (\$i)"                              >> var/tmp/con.sql
 --exec echo "{"                                        >> var/tmp/con.sql
 --exec echo " connect (test_con1,localhost,root,,); "  >> var/tmp/con.sql
 --exec echo " disconnect test_con1; "                  >> var/tmp/con.sql
---exec echo " dec \\\$i;                             " >> var/tmp/con.sql
+--exec echo " dec \$i;                              "  >> var/tmp/con.sql
 --exec echo "}"                                        >> var/tmp/con.sql
 --error 1
 --exec echo "source var/tmp/con.sql;" | $MYSQL_TEST 2>&1
@@ -1001,7 +1001,7 @@ select "this will be executed";
 #
 # Test that a test file that does not generate any output fails.
 #
---exec echo "let \\\$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
+--exec echo "let \$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
 --error 1
 --exec $MYSQL_TEST -x var/tmp/query.sql  2>&1
 

From 9b1aa7fa075a5250e1c99c9fb4d48feb7ad6e474 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 23 Feb 2006 10:35:53 +0100
Subject: [PATCH 047/103] Merge fixup

client/mysqltest.c:
  Fix after merge, do_eval has three args
  Remove extre return in do_block
---
 client/mysqltest.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 57d76a169a7..cc75aaed3a8 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1438,7 +1438,7 @@ int do_echo(struct st_query *command)
   ds= &ds_res;
 
   init_dynamic_string(&ds_echo, "", 256, 256);
-  do_eval(&ds_echo, command->first_argument);
+  do_eval(&ds_echo, command->first_argument, FALSE);
   dynstr_append_mem(ds, ds_echo.str, ds_echo.length);
   dynstr_append_mem(ds, "\n", 1);
   dynstr_free(&ds_echo);
@@ -2468,7 +2468,6 @@ int do_block(enum block_cmd cmd, struct st_query* q)
 
   var_free(&v);
   DBUG_VOID_RETURN;
-  return 0;
 }
 
 

From 24c44a9bea0f3208e1e28db30e91ca3c49143e75 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 23 Feb 2006 14:06:29 +0100
Subject: [PATCH 048/103] Aix52 build fix

client/mysqldump.c:
  Declare variable in start of function
---
 client/mysqldump.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/mysqldump.c b/client/mysqldump.c
index 815a2832861..aa6e6f649eb 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -3238,10 +3238,10 @@ static int replace(DYNAMIC_STRING *ds_str,
                    const char *search_str, ulong search_len,
                    const char *replace_str, ulong replace_len)
 {
+  DYNAMIC_STRING ds_tmp;
   const char *start= strstr(ds_str->str, search_str);
   if (!start)
     return 1;
-  DYNAMIC_STRING ds_tmp;
   init_dynamic_string(&ds_tmp, "",
 		      ds_str->length + replace_len, 256);
   dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str);

From 258ad72c83154ef23bb4b9c0f492aa3e97b0bbed Mon Sep 17 00:00:00 2001
From: unknown <konstantin@mysql.com>
Date: Thu, 23 Feb 2006 16:21:43 +0300
Subject: [PATCH 049/103] Cleanup.

sql/sql_base.cc:
  Cleanup, remove a warning.
sql/sql_select.h:
  Cleanup: remove a warning.
---
 sql/sql_base.cc  |  3 +--
 sql/sql_select.h | 10 +++-------
 2 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 37d4c80a0d0..4415bb501f8 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -3594,7 +3594,6 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
 {
   Field_iterator_table_ref it_1, it_2;
   Natural_join_column *nj_col_1, *nj_col_2;
-  const char *field_name_1;
   Query_arena *arena, backup;
   bool add_columns= TRUE;
   bool result= TRUE;
@@ -3627,6 +3626,7 @@ mark_common_columns(THD *thd, TABLE_LIST *table_ref_1, TABLE_LIST *table_ref_2,
   {
     bool is_created_1;
     bool found= FALSE;
+    const char *field_name_1;
     if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
       goto err;
     field_name_1= nj_col_1->name();
@@ -3823,7 +3823,6 @@ store_natural_using_join_columns(THD *thd, TABLE_LIST *natural_using_join,
 {
   Field_iterator_table_ref it_1, it_2;
   Natural_join_column *nj_col_1, *nj_col_2;
-  bool is_created;
   Query_arena *arena, backup;
   bool result= TRUE;
   List<Natural_join_column> *non_join_columns;
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 9046398faaf..95a71142426 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -174,7 +174,9 @@ typedef struct st_rollup
 
 class JOIN :public Sql_alloc
 {
- public:
+  JOIN(const JOIN &rhs);                        /* not implemented */
+  JOIN& operator=(const JOIN &rhs);             /* not implemented */
+public:
   JOIN_TAB *join_tab,**best_ref;
   JOIN_TAB **map2table;    // mapping between table indexes and JOIN_TABs
   JOIN_TAB *join_tab_save; // saved join_tab for subquery reexecution
@@ -286,12 +288,6 @@ class JOIN :public Sql_alloc
     init(thd_arg, fields_arg, select_options_arg, result_arg);
   }
 
-  JOIN(JOIN &join)
-    :fields_list(join.fields_list)
-  {
-    init(join.thd, join.fields_list, join.select_options,
-         join.result);
-  }
 
   void init(THD *thd_arg, List<Item> &fields_arg, ulonglong select_options_arg,
        select_result *result_arg)

From 7262273457e55b684a8398edb956638206f9fcd9 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 23 Feb 2006 16:08:28 +0100
Subject: [PATCH 050/103] Change snprintf to my_snprintf

client/mysqldump.c:
  snprintf =>  my_snprintf
---
 client/mysqldump.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/client/mysqldump.c b/client/mysqldump.c
index aa6e6f649eb..161197821d6 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -3292,7 +3292,7 @@ static my_bool get_view_structure(char *table, char* db)
   result_table=     quote_name(table, table_buff, 1);
   opt_quoted_table= quote_name(table, table_buff2, 0);
 
-  snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
+  my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table);
   if (mysql_query_with_error_report(sock, &table_res, query))
   {
     safe_exit(EX_MYSQLERR);
@@ -3335,10 +3335,10 @@ static my_bool get_view_structure(char *table, char* db)
   }
 
 
-  snprintf(query, sizeof(query),
-           "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE "               \
-           "FROM information_schema.views "                             \
-           "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
+  my_snprintf(query, sizeof(query),
+              "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE "            \
+              "FROM information_schema.views "                          \
+              "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db);
   if (mysql_query(sock, query))
   {
     /*

From 5dd2f66eafb131dc1b8bf448741497b4a620dda1 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Thu, 23 Feb 2006 09:11:05 -0600
Subject: [PATCH 051/103] mysqld.cc:   Fix out of order entries in option
 struct.

sql/mysqld.cc:
  Fix out of order entries in option struct.
---
 sql/mysqld.cc | 74 +++++++++++++++++++++++++--------------------------
 1 file changed, 37 insertions(+), 37 deletions(-)

diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 4c32d7f9de5..00ddde46127 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4608,8 +4608,6 @@ struct my_option my_long_options[] =
    (gptr*) &abort_slave_event_count,  (gptr*) &abort_slave_event_count,
    0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 #endif /* HAVE_REPLICATION */
-  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
-   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
    "Allows use of UDFs consisting of only one symbol xxx() "
    "without corresponding xxx_init() or xxx_deinit(). That also means "
@@ -4617,6 +4615,8 @@ struct my_option my_long_options[] =
    "from libc.so",
    (gptr*) &opt_allow_suspicious_udfs, (gptr*) &opt_allow_suspicious_udfs,
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode will also set transaction isolation level 'serializable'.", 0, 0, 0,
+   GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"auto-increment-increment", OPT_AUTO_INCREMENT,
    "Auto-increment columns are incremented by this",
    (gptr*) &global_system_variables.auto_increment_increment,
@@ -4870,16 +4870,16 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
    "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file",
    (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file,
    0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-  {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS,
-   "Enable InnoDB locking in LOCK TABLES",
-   (gptr*) &global_system_variables.innodb_table_locks,
-   (gptr*) &global_system_variables.innodb_table_locks,
-   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
   {"innodb_support_xa", OPT_INNODB_SUPPORT_XA,
    "Enable InnoDB support for the XA two-phase commit",
    (gptr*) &global_system_variables.innodb_support_xa,
    (gptr*) &global_system_variables.innodb_support_xa,
    0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+  {"innodb_table_locks", OPT_INNODB_TABLE_LOCKS,
+   "Enable InnoDB locking in LOCK TABLES",
+   (gptr*) &global_system_variables.innodb_table_locks,
+   (gptr*) &global_system_variables.innodb_table_locks,
+   0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
 #endif /* End HAVE_INNOBASE_DB */
   {"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.",
    (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0,
@@ -4905,6 +4905,16 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
    "File that holds the names for last binary log files.",
    (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR,
    REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  /*
+    This option starts with "log-bin" to emphasize that it is specific of
+    binary logging.
+  */
+  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
+   "If equal to 0 (the default), then when --log-bin is used, creation of "
+   "a stored function is allowed only to users having the SUPER privilege and"
+   " only if this function may not break binary logging.",
+   (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
+   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 #ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
   /*
     In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
@@ -4917,16 +4927,6 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
    (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
-  /*
-    This option starts with "log-bin" to emphasize that it is specific of
-    binary logging.
-  */
-  {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
-   "If equal to 0 (the default), then when --log-bin is used, creation of "
-   "a stored function is allowed only to users having the SUPER privilege and"
-   " only if this function may not break binary logging.",
-   (gptr*) &trust_function_creators, (gptr*) &trust_function_creators, 0,
-   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
    (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR,
    OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -5169,12 +5169,6 @@ thread is in the relay logs.",
   {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
    "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
-   "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar.",
-   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
-   "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
-   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 #ifdef HAVE_REPLICATION
   {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
    "In replication, if set to 1, do not skip events having our server id. \
@@ -5184,6 +5178,12 @@ Can't be set to 1 if --log-slave-updates is used.",
    (gptr*) &replicate_same_server_id,
    0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 #endif
+  {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
+   "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar.",
+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+  {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
+   "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.",
+   0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   // In replication, we may need to tell the other servers how to connect
   {"report-host", OPT_REPORT_HOST,
    "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.",
@@ -5417,6 +5417,11 @@ log and this option does nothing anymore.",
     "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.",
     (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG,
     REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0},
+  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
+   "Precision of the result of '/' operator will be increased on that value.",
+   (gptr*) &global_system_variables.div_precincrement,
+   (gptr*) &max_system_variables.div_precincrement, 0, GET_ULONG,
+   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
   {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
    "If non-zero, binary logs will be purged after expire_logs_days "
    "days; possible purges happen at startup and at binary log rotation.",
@@ -5472,6 +5477,10 @@ log and this option does nothing anymore.",
    (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0,
    GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0,
    1024*1024L, 0},
+  {"innodb_commit_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
+   "Helps in performance tuning in heavily concurrent environments.",
+   (gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency,
+   0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
   {"innodb_concurrency_tickets", OPT_INNODB_CONCURRENCY_TICKETS,
    "Number of times a thread is allowed to enter InnoDB within the same \
     SQL query after it has once got the ticket",
@@ -5523,10 +5532,6 @@ log and this option does nothing anymore.",
    " will disable the thread throttling.",
    (gptr*) &srv_thread_concurrency, (gptr*) &srv_thread_concurrency,
    0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
-  {"innodb_commit_concurrency", OPT_INNODB_THREAD_CONCURRENCY,
-   "Helps in performance tuning in heavily concurrent environments.",
-   (gptr*) &srv_commit_concurrency, (gptr*) &srv_commit_concurrency,
-   0, GET_LONG, REQUIRED_ARG, 0, 0, 1000, 0, 1, 0},
   {"innodb_thread_sleep_delay", OPT_INNODB_THREAD_SLEEP_DELAY,
    "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0"
     " disable a sleep",
@@ -5647,6 +5652,11 @@ The minimum value for this variable is 4096.",
    (gptr*) &global_system_variables.max_sort_length,
    (gptr*) &max_system_variables.max_sort_length, 0, GET_ULONG,
    REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
+  {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
+   "Maximum stored procedure recursion depth. (discussed with docs).",
+   (gptr*) &global_system_variables.max_sp_recursion_depth,
+   (gptr*) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
+   OPT_ARG, 0, 0, 255, 0, 1, 0 },
   {"max_tmp_tables", OPT_MAX_TMP_TABLES,
    "Maximum number of temporary tables a client can keep open at a time.",
    (gptr*) &global_system_variables.max_tmp_tables,
@@ -5802,21 +5812,11 @@ The minimum value for this variable is 4096.",
    (gptr*) &max_system_variables.read_rnd_buff_size, 0,
    GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
    ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
-  {"div_precision_increment", OPT_DIV_PRECINCREMENT,
-   "Precision of the result of '/' operator will be increased on that value.",
-   (gptr*) &global_system_variables.div_precincrement,
-   (gptr*) &max_system_variables.div_precincrement, 0, GET_ULONG,
-   REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
   {"record_buffer", OPT_RECORD_BUFFER,
    "Alias for read_buffer_size",
    (gptr*) &global_system_variables.read_buff_size,
    (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
    128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
-  {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
-   "Maximum stored procedure recursion depth. (discussed with docs).",
-   (gptr*) &global_system_variables.max_sp_recursion_depth,
-   (gptr*) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
-   OPT_ARG, 0, 0, 255, 0, 1, 0 },
 #ifdef HAVE_REPLICATION
   {"relay_log_purge", OPT_RELAY_LOG_PURGE,
    "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",

From ef1316fadda7b7d8c1b00de6d82576ebc21607cc Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Thu, 23 Feb 2006 13:54:55 -0600
Subject: [PATCH 052/103] mysqltest.c:   Rearrange out of order options in
 option struct.

client/mysqltest.c:
  Rearrange out of order options in option struct.
---
 client/mysqltest.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index cc75aaed3a8..7f5ded13d62 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -2819,6 +2819,9 @@ static struct my_option my_long_options[] =
   {"compress", 'C', "Use the compressed server/client protocol.",
    (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
    0, 0, 0},
+  {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statment",
+   (gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0,
+   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0,
    GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
 #ifdef DBUG_OFF
@@ -2851,15 +2854,6 @@ static struct my_option my_long_options[] =
   {"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication",
    (gptr*) &ps_protocol, (gptr*) &ps_protocol, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select",
-   (gptr*) &sp_protocol, (gptr*) &sp_protocol, 0,
-   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statment",
-   (gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0,
-   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select",
-   (gptr*) &view_protocol, (gptr*) &view_protocol, 0,
-   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"quiet", 's', "Suppress all normal output.", (gptr*) &silent,
    (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"record", 'r', "Record output of test_file into result file.",
@@ -2882,6 +2876,9 @@ static struct my_option my_long_options[] =
   {"socket", 'S', "Socket file to use for connection.",
    (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
    0, 0, 0},
+  {"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select",
+   (gptr*) &sp_protocol, (gptr*) &sp_protocol, 0,
+   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
 #include "sslopt-longopts.h"
   {"test-file", 'x', "Read test from/in this file (default stdin).",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -2895,6 +2892,9 @@ static struct my_option my_long_options[] =
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"version", 'V', "Output version information and exit.",
    0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
+  {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select",
+   (gptr*) &view_protocol, (gptr*) &view_protocol, 0,
+   GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 

From ea9ea952be77d51db158df54b8ac627c73ff8713 Mon Sep 17 00:00:00 2001
From: unknown <konstantin@mysql.com>
Date: Thu, 23 Feb 2006 23:41:15 +0300
Subject: [PATCH 053/103] Remove 'delayed' to make the test deterministic
 (already fixed in 5.0). A post-review fix (Bug#13134)

mysql-test/r/heap.result:
  Remove 'delayed' to make the test deterministic.
mysql-test/r/ps.result:
  Remove an unneeded drop table (test case for Bug#13134)
mysql-test/t/heap.test:
  Remove 'delayed' to make the test deterministic.
mysql-test/t/ps.test:
  A post-review fix (Bug#13134)
---
 mysql-test/r/heap.result | 4 ++--
 mysql-test/r/ps.result   | 3 ---
 mysql-test/t/heap.test   | 4 ++--
 mysql-test/t/ps.test     | 1 -
 4 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/mysql-test/r/heap.result b/mysql-test/r/heap.result
index e3b9f7db984..6bb9d0c87ee 100644
--- a/mysql-test/r/heap.result
+++ b/mysql-test/r/heap.result
@@ -297,11 +297,11 @@ insert into t1 values ("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcd
 ERROR 23000: Duplicate entry 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkl' for key 1
 drop table t1;
 CREATE TABLE t1 (a int, key(a)) engine=heap;
-insert delayed into t1 values (0);
+insert into t1 values (0);
 delete from t1;
 select * from t1;
 a
-insert delayed into t1 values (0), (1);
+insert into t1 values (0), (1);
 select * from t1 where a = 0;
 a
 0
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 5404681e222..e94c2952893 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -733,9 +733,6 @@ count(*)
 5
 deallocate prepare stmt;
 drop table t1;
-drop table if exists t1;
-Warnings:
-Note	1051	Unknown table 't1'
 prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
 execute stmt;
 insert into t1 (a) values (repeat('a', 20));
diff --git a/mysql-test/t/heap.test b/mysql-test/t/heap.test
index a8128b79e3b..50147b4182d 100644
--- a/mysql-test/t/heap.test
+++ b/mysql-test/t/heap.test
@@ -238,10 +238,10 @@ drop table t1;
 # Bug 12796: Record doesn't show when selecting through index
 #
 CREATE TABLE t1 (a int, key(a)) engine=heap;
-insert delayed into t1 values (0);
+insert into t1 values (0);
 delete from t1;
 select * from t1;
-insert delayed into t1 values (0), (1);
+insert into t1 values (0), (1);
 select * from t1 where a = 0;
 drop table t1;
 
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index b1f6be819d4..af885a5c02f 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -769,7 +769,6 @@ drop table t1;
 # recreated with PS/SP"
 #
 
-drop table if exists t1;
 prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
 execute stmt;
 --disable_warnings

From f2fd3c2781e889c83f820d8bd5c6a4d25d297b9d Mon Sep 17 00:00:00 2001
From: unknown <konstantin@mysql.com>
Date: Fri, 24 Feb 2006 00:12:04 +0300
Subject: [PATCH 054/103] After-merge fixes (Bug#13134)

---
 sql/field.cc     | 4 +++-
 sql/sql_parse.cc | 1 -
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/sql/field.cc b/sql/field.cc
index 31fbf9868e4..35312caf313 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -8269,7 +8269,7 @@ void create_field::init_for_tmp_table(enum_field_types sql_type_arg,
 {
   field_name= "";
   sql_type= sql_type_arg;
-  length= length_arg;;
+  char_length= length= length_arg;;
   unireg_check= Field::NONE;
   interval= 0;
   charset= &my_charset_bin;
@@ -8597,6 +8597,8 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type,
   case FIELD_TYPE_DECIMAL:
     DBUG_ASSERT(0); /* Was obsolete */
   }
+  /* Remember the value of length */
+  char_length= length;
 
   if (!(flags & BLOB_FLAG) &&
       ((length > max_field_charlength && fld_type != FIELD_TYPE_SET &&
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8cd8a064580..978cab704c0 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5791,7 +5791,6 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
                       interval_list, cs, uint_geom_type))
     DBUG_RETURN(1);
 
-  new_field->char_length= new_field->length;
   lex->create_list.push_back(new_field);
   lex->last_field=new_field;
   DBUG_RETURN(0);

From f1a8a34c6c65f8f8a9e12401dc648edea47e82aa Mon Sep 17 00:00:00 2001
From: unknown <knielsen@mysql.com>
Date: Fri, 24 Feb 2006 13:51:04 +0100
Subject: [PATCH 055/103] Fix mysqldump.test to work with non-standard
 --vardir. (Backported from mysql-5.1-new)

mysql-test/t/mysqldump.test:
  Fix mysqldump.test to work with non-standard --vardir.
---
 mysql-test/t/mysqldump.test | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 6c981ae7577..9008eff6642 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1050,14 +1050,14 @@ create algorithm=merge view v4 as select * from t1 with cascaded check option;
 create algorithm =temptable view v5 as select * from t1;
 
 # dump tables and views
---exec $MYSQL_DUMP test > var/tmp/bug14871.sql
+--exec $MYSQL_DUMP test > $MYSQLTEST_VARDIR/tmp/bug14871.sql
 
 # drop the db, tables and views
 drop table t1;
 drop view v1, v2, v3, v4, v5;
 
 # Reload dump
---exec $MYSQL test < var/tmp/bug14871.sql
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug14871.sql
 
 # check that all tables and views could be created
 show tables;
@@ -1083,13 +1083,13 @@ end|
 delimiter ;|
 
 # dump table and trigger
---exec $MYSQL_DUMP test > var/tmp/bug16878.sql
+--exec $MYSQL_DUMP test > $MYSQLTEST_VARDIR/tmp/bug16878.sql
 drop trigger tr1;
 drop trigger tr2;
 drop table t1, t2;
 
 # reload dump
---exec $MYSQL test < var/tmp/bug16878.sql
+--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug16878.sql
 --replace_column 6 #
 show triggers;
 drop trigger tr1;

From 0afb6ff66082f64c7c0aea62662e4c03e7c987c5 Mon Sep 17 00:00:00 2001
From: unknown <monty@mysql.com>
Date: Fri, 24 Feb 2006 18:34:15 +0200
Subject: [PATCH 056/103] Fixes to embedded server to be able to run tests with
 it (Needed for "list of pushes" web page and autopush)

include/mysql.h:
  Fix to embedded server to be able to run tests on it
libmysql/libmysql.c:
  Fix to embedded server to be able to run tests on it
libmysqld/emb_qcache.cc:
  Fix to embedded server to be able to run tests on it
libmysqld/embedded_priv.h:
  Fix to embedded server to be able to run tests on it
libmysqld/lib_sql.cc:
  Fix to embedded server to be able to run tests on it
libmysqld/libmysqld.c:
  Fix to embedded server to be able to run tests on it
mysql-test/mysql-test-run.sh:
  Fix to embedded server to be able to run tests on it
mysql-test/r/binlog.result:
  Updated test for embedded server
mysql-test/r/ctype_cp932.result:
  Updated test for embedded server
mysql-test/r/innodb.result:
  Updated test for embedded server
mysql-test/r/mysqltest.result:
  Updated test for embedded server
mysql-test/r/query_cache.result:
  Updated test for embedded server
mysql-test/r/query_cache_notembedded.result:
  Updated test for embedded server
mysql-test/r/sp-error.result:
  Updated test for embedded server
mysql-test/r/sp.result:
  Updated test for embedded server
mysql-test/r/subselect.result:
  Updated test for embedded server
mysql-test/r/view.result:
  Updated test for embedded server
mysql-test/r/view_grant.result:
  Updated test for embedded server
mysql-test/t/backup.test:
  Updated test for embedded server
mysql-test/t/binlog.test:
  Updated test for embedded server
mysql-test/t/blackhole.test:
  Updated test for embedded server
mysql-test/t/compress.test:
  Updated test for embedded server
mysql-test/t/ctype_cp932.test:
  Updated test for embedded server
mysql-test/t/delayed.test:
  Updated test for embedded server
mysql-test/t/handler.test:
  Updated test for embedded server
mysql-test/t/innodb.test:
  Updated test for embedded server
mysql-test/t/mysql.test:
  Updated test for embedded server
mysql-test/t/mysql_client_test.test:
  Updated test for embedded server
mysql-test/t/mysqltest.test:
  Updated test for embedded server
mysql-test/t/query_cache.test:
  Updated test for embedded server
mysql-test/t/query_cache_notembedded.test:
  Updated test for embedded server
mysql-test/t/read_only.test:
  Updated test for embedded server
mysql-test/t/skip_grants.test:
  Updated test for embedded server
mysql-test/t/sp-destruct.test:
  Updated test for embedded server
mysql-test/t/sp-error.test:
  Updated test for embedded server
mysql-test/t/sp-threads.test:
  Updated test for embedded server
mysql-test/t/sp.test:
  Updated test for embedded server
mysql-test/t/subselect.test:
  Updated test for embedded server
mysql-test/t/temp_table.test:
  Updated test for embedded server
mysql-test/t/view.test:
  Updated test for embedded server
mysql-test/t/view_grant.test:
  Updated test for embedded server
mysql-test/t/wait_timeout.test:
  Updated test for embedded server
mysys/mf_dirname.c:
  Review fix: Don't access data outside of array
mysys/my_bitmap.c:
  Remove compiler warnings
scripts/mysql_fix_privilege_tables.sql:
  Add flush privileges to .sql script so that one doesn't have to reboot mysqld when one runs the mysql_fix_privilege_script
sql-common/client.c:
  Updated test for embedded server
sql/item.cc:
  Remove DBUG_PRINT statement that can cause crashes when running with --debug
sql/mysqld.cc:
  Fix to embedded server to be able to run tests on it
sql/protocol.cc:
  Fix to embedded server to be able to run tests on it
  (Trivial reconstruction of code)
sql/protocol.h:
  Fix to embedded server to be able to run tests on it
sql/sql_base.cc:
  Better comment
sql/sql_class.cc:
  Fix to embedded server to be able to run tests on it
sql/sql_class.h:
  Fix to embedded server to be able to run tests on it
sql/sql_cursor.cc:
  Fix to embedded server to be able to run tests on it
sql/sql_parse.cc:
  Fix to embedded server to be able to run tests on it
  Don't crash for disabled commands when using embedded server
sql/sql_prepare.cc:
  Fix to embedded server to be able to run tests on it
mysql-test/r/ctype_cp932_notembedded.result:
  New BitKeeper file ``mysql-test/r/ctype_cp932_notembedded.result''
mysql-test/r/innodb_notembedded.result:
  New BitKeeper file ``mysql-test/r/innodb_notembedded.result''
mysql-test/r/sp.result.orig:
  New BitKeeper file ``mysql-test/r/sp.result.orig''
mysql-test/r/sp_notembedded.result:
  New BitKeeper file ``mysql-test/r/sp_notembedded.result''
mysql-test/r/subselect_notembedded.result:
  New BitKeeper file ``mysql-test/r/subselect_notembedded.result''
mysql-test/t/ctype_cp932_notembedded.test:
  New BitKeeper file ``mysql-test/t/ctype_cp932_notembedded.test''
mysql-test/t/innodb_notembedded.test:
  New BitKeeper file ``mysql-test/t/innodb_notembedded.test''
mysql-test/t/sp.test.orig:
  New BitKeeper file ``mysql-test/t/sp.test.orig''
mysql-test/t/sp_notembedded.test:
  New BitKeeper file ``mysql-test/t/sp_notembedded.test''
mysql-test/t/subselect_notembedded.test:
  New BitKeeper file ``mysql-test/t/subselect_notembedded.test''
---
 include/mysql.h                             |    9 +-
 libmysql/libmysql.c                         |   12 +-
 libmysqld/emb_qcache.cc                     |  129 +-
 libmysqld/embedded_priv.h                   |   21 +-
 libmysqld/lib_sql.cc                        |  512 +-
 libmysqld/libmysqld.c                       |   14 +-
 mysql-test/mysql-test-run.sh                |    1 +
 mysql-test/r/binlog.result                  |    4 +-
 mysql-test/r/ctype_cp932.result             |   14 -
 mysql-test/r/ctype_cp932_notembedded.result |   17 +
 mysql-test/r/innodb.result                  |   19 -
 mysql-test/r/innodb_notembedded.result      |   20 +
 mysql-test/r/mysqltest.result               |    4 +-
 mysql-test/r/query_cache.result             |   45 -
 mysql-test/r/query_cache_notembedded.result |  220 +
 mysql-test/r/sp-error.result                |   13 -
 mysql-test/r/sp.result                      |   82 -
 mysql-test/r/sp.result.orig                 | 4853 ++++++++++++++++
 mysql-test/r/sp_notembedded.result          |  206 +
 mysql-test/r/subselect.result               |    1 -
 mysql-test/r/subselect_notembedded.result   |    1 +
 mysql-test/r/view.result                    |    9 -
 mysql-test/r/view_grant.result              |    9 +
 mysql-test/t/backup.test                    |    3 +
 mysql-test/t/binlog.test                    |    5 +-
 mysql-test/t/blackhole.test                 |    1 +
 mysql-test/t/compress.test                  |    3 +
 mysql-test/t/ctype_cp932.test               |   22 -
 mysql-test/t/ctype_cp932_notembedded.test   |   32 +
 mysql-test/t/delayed.test                   |    3 +
 mysql-test/t/handler.test                   |    3 +
 mysql-test/t/innodb.test                    |   29 +-
 mysql-test/t/innodb_notembedded.test        |   40 +
 mysql-test/t/mysql.test                     |    2 +
 mysql-test/t/mysql_client_test.test         |    3 +
 mysql-test/t/mysqltest.test                 |    2 +
 mysql-test/t/query_cache.test               |   15 -
 mysql-test/t/query_cache_notembedded.test   |   84 +
 mysql-test/t/read_only.test                 |    3 +
 mysql-test/t/skip_grants.test               |    3 +
 mysql-test/t/sp-destruct.test               |    3 +
 mysql-test/t/sp-error.test                  |   22 -
 mysql-test/t/sp-threads.test                |    2 +
 mysql-test/t/sp.test                        |  107 +-
 mysql-test/t/sp.test.orig                   | 5716 +++++++++++++++++++
 mysql-test/t/sp_notembedded.test            |  262 +
 mysql-test/t/subselect.test                 |    6 -
 mysql-test/t/subselect_notembedded.test     |    8 +
 mysql-test/t/temp_table.test                |    2 +
 mysql-test/t/view.test                      |   10 -
 mysql-test/t/view_grant.test                |   11 +
 mysql-test/t/wait_timeout.test              |    3 +
 mysys/mf_dirname.c                          |    2 +-
 mysys/my_bitmap.c                           |    4 +-
 scripts/mysql_fix_privilege_tables.sql      |    6 +
 sql-common/client.c                         |    9 +-
 sql/item.cc                                 |    3 -
 sql/mysqld.cc                               |    2 -
 sql/protocol.cc                             |   82 +-
 sql/protocol.h                              |    9 +
 sql/sql_base.cc                             |    9 +
 sql/sql_class.cc                            |    3 +-
 sql/sql_class.h                             |   12 +-
 sql/sql_cursor.cc                           |    1 +
 sql/sql_parse.cc                            |   33 +-
 sql/sql_prepare.cc                          |   11 +-
 66 files changed, 12108 insertions(+), 698 deletions(-)
 create mode 100644 mysql-test/r/ctype_cp932_notembedded.result
 create mode 100644 mysql-test/r/innodb_notembedded.result
 create mode 100644 mysql-test/r/sp.result.orig
 create mode 100644 mysql-test/r/sp_notembedded.result
 create mode 100644 mysql-test/r/subselect_notembedded.result
 create mode 100644 mysql-test/t/ctype_cp932_notembedded.test
 create mode 100644 mysql-test/t/innodb_notembedded.test
 create mode 100644 mysql-test/t/sp.test.orig
 create mode 100644 mysql-test/t/sp_notembedded.test
 create mode 100644 mysql-test/t/subselect_notembedded.test

diff --git a/include/mysql.h b/include/mysql.h
index f3244d4ba36..303cb2af4f5 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -130,14 +130,14 @@ typedef MYSQL_ROWS *MYSQL_ROW_OFFSET;	/* offset to current row */
 
 #include "my_alloc.h"
 
+typedef struct embedded_query_result EMBEDDED_QUERY_RESULT;
 typedef struct st_mysql_data {
   my_ulonglong rows;
   unsigned int fields;
   MYSQL_ROWS *data;
   MEM_ROOT alloc;
-#if !defined(CHECK_EMBEDDED_DIFFERENCES) || defined(EMBEDDED_LIBRARY)
-  MYSQL_ROWS **prev_ptr;
-#endif
+  /* extra info for embedded library */
+  struct embedded_query_result *embedded_info;
 } MYSQL_DATA;
 
 enum mysql_option 
@@ -287,6 +287,8 @@ typedef struct st_mysql
     from mysql_stmt_close if close had to cancel result set of this object.
   */
   my_bool *unbuffered_fetch_owner;
+  /* needed for embedded server - no net buffer to store the 'info' */
+  char *info_buffer;
 } MYSQL;
 
 typedef struct st_mysql_res {
@@ -755,6 +757,7 @@ typedef struct st_mysql_methods
   const char *(*read_statistics)(MYSQL *mysql);
   my_bool (*next_result)(MYSQL *mysql);
   int (*read_change_user_result)(MYSQL *mysql, char *buff, const char *passwd);
+  int (*read_rows_from_cursor)(MYSQL_STMT *stmt);
 #endif
 } MYSQL_METHODS;
 
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 3a532965551..99f173aa153 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2727,13 +2727,13 @@ stmt_read_row_from_cursor(MYSQL_STMT *stmt, unsigned char **row)
     /* Send row request to the server */
     int4store(buff, stmt->stmt_id);
     int4store(buff + 4, stmt->prefetch_rows); /* number of rows to fetch */
-    if (cli_advanced_command(mysql, COM_STMT_FETCH, buff, sizeof(buff),
-                             NullS, 0, 1))
+    if ((*mysql->methods->advanced_command)(mysql, COM_STMT_FETCH,
+                                            buff, sizeof(buff), NullS, 0, 1))
     {
       set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
       return 1;
     }
-    if (cli_read_binary_rows(stmt))
+    if ((*mysql->methods->read_rows_from_cursor)(stmt))
       return 1;
     stmt->server_status= mysql->server_status;
 
@@ -5143,9 +5143,9 @@ my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode)
   DBUG_ENTER("mysql_autocommit");
   DBUG_PRINT("enter", ("mode : %d", auto_mode));
 
-  if (auto_mode) /* set to true */
-    DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=1", 16));
-  DBUG_RETURN((my_bool) mysql_real_query(mysql, "set autocommit=0", 16));
+  DBUG_RETURN((my_bool) mysql_real_query(mysql, auto_mode ?
+                                         "set autocommit=1":"set autocommit=0",
+                                         16));
 }
 
 
diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc
index ecc45096165..078243a6d5e 100644
--- a/libmysqld/emb_qcache.cc
+++ b/libmysqld/emb_qcache.cc
@@ -18,6 +18,7 @@
 #ifdef HAVE_QUERY_CACHE
 #include <mysql.h>
 #include "emb_qcache.h"
+#include "embedded_priv.h"
 
 void Querycache_stream::store_char(char c)
 {
@@ -284,22 +285,25 @@ int Querycache_stream::load_column(MEM_ROOT *alloc, char** column)
 
 uint emb_count_querycache_size(THD *thd)
 {
-  uint result;
-  MYSQL *mysql= thd->mysql;
-  MYSQL_FIELD *field= mysql->fields;
-  MYSQL_FIELD *field_end= field + mysql->field_count;
-  MYSQL_ROWS *cur_row=NULL;
-  my_ulonglong n_rows=0;
+  uint result= 0;
+  MYSQL_FIELD *field;
+  MYSQL_FIELD *field_end;
+  MYSQL_ROWS *cur_row;
+  my_ulonglong n_rows;
+  MYSQL_DATA *data= thd->first_data;
+
+  while (data->embedded_info->next)
+    data= data->embedded_info->next;
+  field= data->embedded_info->fields_list;
+  field_end= field + data->fields;
   
   if (!field)
-    return 0;
-  if (thd->data)
-  {
-    *thd->data->prev_ptr= NULL; // this marks the last record
-    cur_row= thd->data->data;
-    n_rows= thd->data->rows;
-  }
-  result= (uint) (4+8 + (42 + 4*n_rows)*mysql->field_count);
+    return result;
+  *data->embedded_info->prev_ptr= NULL; // this marks the last record
+  cur_row= data->data;
+  n_rows= data->rows;
+  /* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
+  result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
 
   for(; field < field_end; field++)
   {
@@ -313,34 +317,38 @@ uint emb_count_querycache_size(THD *thd)
   for (; cur_row; cur_row=cur_row->next)
   {
     MYSQL_ROW col= cur_row->data;
-    MYSQL_ROW col_end= col + mysql->field_count;
+    MYSQL_ROW col_end= col + data->fields;
     for (; col < col_end; col++)
       if (*col)
-	result+= *(uint *)((*col) - sizeof(uint));
+        result+= *(uint *)((*col) - sizeof(uint));
   }
   return result;
 }
 
 void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
 {
-  MYSQL *mysql= thd->mysql;
-  MYSQL_FIELD *field= mysql->fields;
-  MYSQL_FIELD *field_end= field + mysql->field_count;
-  MYSQL_ROWS *cur_row= NULL;
-  my_ulonglong n_rows= 0;
+  MYSQL_FIELD *field;
+  MYSQL_FIELD *field_end;
+  MYSQL_ROWS *cur_row;
+  my_ulonglong n_rows;
+  MYSQL_DATA *data= thd->first_data;
+
+  DBUG_ENTER("emb_store_querycache_result");
+
+  while (data->embedded_info->next)
+    data= data->embedded_info->next;
+  field= data->embedded_info->fields_list;
+  field_end= field + data->fields;
 
   if (!field)
-    return;
+    DBUG_VOID_RETURN;
 
-  if (thd->data)
-  {
-    *thd->data->prev_ptr= NULL; // this marks the last record
-    cur_row= thd->data->data;
-    n_rows= thd->data->rows;
-  }
+  *data->embedded_info->prev_ptr= NULL; // this marks the last record
+  cur_row= data->data;
+  n_rows= data->rows;
 
-  dst->store_int((uint)mysql->field_count);
-  dst->store_ll((uint)n_rows);
+  dst->store_int((uint)data->fields);
+  dst->store_ll((ulonglong)n_rows);
 
   for(; field < field_end; field++)
   {
@@ -356,14 +364,13 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
     dst->store_str(field->org_table, field->org_table_length);
     dst->store_str(field->db, field->db_length);
     dst->store_str(field->catalog, field->catalog_length);
-
     dst->store_safe_str(field->def, field->def_length);
   }
   
   for (; cur_row; cur_row=cur_row->next)
   {
     MYSQL_ROW col= cur_row->data;
-    MYSQL_ROW col_end= col + mysql->field_count;
+    MYSQL_ROW col_end= col + data->fields;
     for (; col < col_end; col++)
     {
       uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
@@ -371,28 +378,34 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
     }
   }
   DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
+  DBUG_VOID_RETURN;
 }
 
 int emb_load_querycache_result(THD *thd, Querycache_stream *src)
 {
-  MYSQL *mysql= thd->mysql;
-  MYSQL_DATA *data;
+  MYSQL_DATA *data= thd->alloc_new_dataset();
   MYSQL_FIELD *field;
   MYSQL_FIELD *field_end;
-  MEM_ROOT *f_alloc= &mysql->field_alloc;
+  MEM_ROOT *f_alloc;
   MYSQL_ROWS *row, *end_row;
   MYSQL_ROWS **prev_row;
   ulonglong rows;
   MYSQL_ROW columns;
+  DBUG_ENTER("emb_load_querycache_result");
 
-  mysql->field_count= src->load_int();
+  if (!data)
+    goto err;
+  init_alloc_root(&data->alloc, 8192,0);
+  f_alloc= &data->alloc;
+
+  data->fields= src->load_int();
   rows= src->load_ll();
 
   if (!(field= (MYSQL_FIELD *)
-	alloc_root(&mysql->field_alloc,mysql->field_count*sizeof(MYSQL_FIELD))))
+        alloc_root(f_alloc,data->fields*sizeof(MYSQL_FIELD))))
     goto err;
-  mysql->fields= field;
-  for(field_end= field+mysql->field_count; field < field_end; field++)
+  data->embedded_info->fields_list= field;
+  for(field_end= field+data->fields; field < field_end; field++)
   {
     field->length= src->load_int();
     field->max_length= (unsigned int)src->load_int();
@@ -402,47 +415,43 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
     field->decimals= (unsigned int)src->load_char();
 
     if (!(field->name= src->load_str(f_alloc, &field->name_length))          ||
-	!(field->table= src->load_str(f_alloc,&field->table_length))         ||
-	!(field->org_name= src->load_str(f_alloc, &field->org_name_length))  ||
-	!(field->org_table= src->load_str(f_alloc, &field->org_table_length))||
-	!(field->db= src->load_str(f_alloc, &field->db_length))              ||
-	!(field->catalog= src->load_str(f_alloc, &field->catalog_length))    ||
-	src->load_safe_str(f_alloc, &field->def, &field->def_length))
+        !(field->table= src->load_str(f_alloc,&field->table_length))         ||
+        !(field->org_name= src->load_str(f_alloc, &field->org_name_length))  ||
+        !(field->org_table= src->load_str(f_alloc, &field->org_table_length))||
+        !(field->db= src->load_str(f_alloc, &field->db_length))              ||
+        !(field->catalog= src->load_str(f_alloc, &field->catalog_length))    ||
+        src->load_safe_str(f_alloc, &field->def, &field->def_length))
       goto err;
   }
   
-  if (!rows)
-    return 0;
-  if (!(data= (MYSQL_DATA*)my_malloc(sizeof(MYSQL_DATA), 
-				     MYF(MY_WME | MY_ZEROFILL))))
-    goto err;
-  thd->data= data;
-  init_alloc_root(&data->alloc, 8192,0);
-  row= (MYSQL_ROWS *)alloc_root(&data->alloc, (uint) (rows * sizeof(MYSQL_ROWS) +
-				rows * (mysql->field_count+1)*sizeof(char*)));
+  row= (MYSQL_ROWS *)alloc_root(&data->alloc,
+                                (uint) (rows * sizeof(MYSQL_ROWS) +
+                                        rows*(data->fields+1)*sizeof(char*)));
   end_row= row + rows;
   columns= (MYSQL_ROW)end_row;
   
   data->rows= rows;
-  data->fields= mysql->field_count;
   data->data= row;
+  if (!rows)
+    goto return_ok;
 
   for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
   {
     *prev_row= row;
     row->data= columns;
-    MYSQL_ROW col_end= columns + mysql->field_count;
+    MYSQL_ROW col_end= columns + data->fields;
     for (; columns < col_end; columns++)
       src->load_column(&data->alloc, columns);
 
     *(columns++)= NULL;
   }
   *prev_row= NULL;
-  data->prev_ptr= prev_row;
-
-  return 0;
+  data->embedded_info->prev_ptr= prev_row;
+return_ok:
+  send_eof(thd);
+  DBUG_RETURN(0);
 err:
-  return 1;
+  DBUG_RETURN(1);
 }
 
 #endif /*HAVE_QUERY_CACHE*/
diff --git a/libmysqld/embedded_priv.h b/libmysqld/embedded_priv.h
index d4316dff63f..88015340e8c 100644
--- a/libmysqld/embedded_priv.h
+++ b/libmysqld/embedded_priv.h
@@ -16,18 +16,25 @@
 
 /* Prototypes for the embedded version of MySQL */
 
-#include <my_global.h>
-#include <mysql.h>
-#include <mysql_embed.h>
-#include <mysqld_error.h>
-#include <my_pthread.h>
-
 C_MODE_START
 void lib_connection_phase(NET *net, int phase);
 void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db);
 void *create_embedded_thd(int client_flag, char *db);
 int check_embedded_connection(MYSQL *mysql);
 void free_old_query(MYSQL *mysql);
-void embedded_get_error(MYSQL *mysql);
 extern MYSQL_METHODS embedded_methods;
+
+/* This one is used by embedded library to gather returning data */
+typedef struct embedded_query_result
+{
+  MYSQL_ROWS **prev_ptr;
+  unsigned int warning_count, server_status;
+  struct st_mysql_data *next;
+  my_ulonglong affected_rows, insert_id;
+  char info[MYSQL_ERRMSG_SIZE];
+  MYSQL_FIELD *fields_list;
+  unsigned int last_errno;
+  char sqlstate[SQLSTATE_LENGTH+1];
+} EQR;
+
 C_MODE_END
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 8552b1c2b8a..e4c9d8cb4e9 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -42,21 +42,48 @@ C_MODE_START
 #undef ER
 #include "errmsg.h"
 #include <sql_common.h>
+#include "embedded_priv.h"
 
-void embedded_get_error(MYSQL *mysql)
+static my_bool emb_read_query_result(MYSQL *mysql);
+
+void THD::clear_data_list()
+{
+  while (first_data)
+  {
+    MYSQL_DATA *data= first_data;
+    first_data= data->embedded_info->next;
+    free_rows(data);
+  }
+  data_tail= &first_data;
+  free_rows(cur_data);
+  cur_data= 0;
+}
+
+
+/*
+  Reads error information from the MYSQL_DATA and puts
+  it into proper MYSQL members
+
+  SYNOPSIS
+    embedded_get_error()
+    mysql        connection handler
+    data         query result
+
+  NOTES
+    after that function error information will be accessible
+       with usual functions like mysql_error()
+    data is my_free-d in this function
+    most of the data is stored in data->embedded_info structure
+*/
+
+void embedded_get_error(MYSQL *mysql, MYSQL_DATA *data)
 {
-  THD *thd=(THD *) mysql->thd;
   NET *net= &mysql->net;
-  if ((net->last_errno= thd->net.last_errno))
-  {
-    memcpy(net->last_error, thd->net.last_error, sizeof(net->last_error));
-    memcpy(net->sqlstate, thd->net.sqlstate, sizeof(net->sqlstate));
-  }
-  else
-  {
-    net->last_error[0]= 0;
-    strmov(net->sqlstate, not_error_sqlstate);
-  }
+  struct embedded_query_result *ei= data->embedded_info;
+  net->last_errno= ei->last_errno;
+  strmake(net->last_error, ei->info, sizeof(net->last_error));
+  memcpy(net->sqlstate, ei->sqlstate, sizeof(net->sqlstate));
+  my_free((gptr) data, MYF(0));
 }
 
 static my_bool
@@ -68,11 +95,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
   THD *thd=(THD *) mysql->thd;
   NET *net= &mysql->net;
 
-  if (thd->data)
-  {
-    free_rows(thd->data);
-    thd->data= 0;
-  }
+  thd->clear_data_list();
   /* Check that we are calling the client functions in right order */
   if (mysql->status != MYSQL_STATUS_READY)
   {
@@ -104,83 +127,101 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
     arg_length= header_length;
   }
 
+  thd->net.no_send_error= 0;
   result= dispatch_command(command, thd, (char *) arg, arg_length + 1);
+  thd->cur_data= 0;
 
   if (!skip_check)
     result= thd->net.last_errno ? -1 : 0;
 
-  /*
-    If mysql->field_count is set it means the parsing of the query was OK
-    and metadata was returned (see Protocol::send_fields).
-    In this case we postpone the error to be returned in mysql_stmt_store_result
-    (see emb_read_rows) to behave just as standalone server.
-  */
-  if (!mysql->field_count)
-    embedded_get_error(mysql);
-  mysql->server_status= thd->server_status;
-  mysql->warning_count= ((THD*)mysql->thd)->total_warn_count;
   return result;
 }
 
 static void emb_flush_use_result(MYSQL *mysql)
 {
-  MYSQL_DATA *data= ((THD*)(mysql->thd))->data;
-
-  if (data)
+  THD *thd= (THD*) mysql->thd;
+  if (thd->cur_data)
   {
+    free_rows(thd->cur_data);
+    thd->cur_data= 0;
+  }
+  else if (thd->first_data)
+  {
+    MYSQL_DATA *data= thd->first_data;
+    thd->first_data= data->embedded_info->next;
     free_rows(data);
-    ((THD*)(mysql->thd))->data= NULL;
   }
 }
 
+
+/*
+  reads dataset from the next query result
+
+  SYNOPSIS
+  emb_read_rows()
+  mysql		connection handle
+  other parameters are not used
+
+  NOTES
+    It just gets next MYSQL_DATA from the result's queue
+
+  RETURN
+    pointer to MYSQL_DATA with the coming recordset
+*/
+
 static MYSQL_DATA *
 emb_read_rows(MYSQL *mysql, MYSQL_FIELD *mysql_fields __attribute__((unused)),
 	      unsigned int fields __attribute__((unused)))
 {
-  MYSQL_DATA *result= ((THD*)mysql->thd)->data;
-  embedded_get_error(mysql);
-  if (mysql->net.last_errno)
-    return NULL;
-  if (!result)
+  MYSQL_DATA *result= ((THD*)mysql->thd)->cur_data;
+  ((THD*)mysql->thd)->cur_data= 0;
+  if (result->embedded_info->last_errno)
   {
-    if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
-					 MYF(MY_WME | MY_ZEROFILL))))
-    {
-      NET *net = &mysql->net;
-      net->last_errno=CR_OUT_OF_MEMORY;
-      strmov(net->sqlstate, unknown_sqlstate);
-      strmov(net->last_error,ER(net->last_errno));
-      return NULL;
-    }    
-    return result;
+    embedded_get_error(mysql, result);
+    return NULL;
   }
-  *result->prev_ptr= NULL;
-  ((THD*)mysql->thd)->data= NULL;
+  *result->embedded_info->prev_ptr= NULL;
   return result;
 }
 
+
 static MYSQL_FIELD *emb_list_fields(MYSQL *mysql)
 {
+  MYSQL_DATA *res;
+  if (emb_read_query_result(mysql))
+    return 0;
+  res= ((THD*) mysql->thd)->cur_data;
+  ((THD*) mysql->thd)->cur_data= 0;
+  mysql->field_alloc= res->alloc;
+  my_free((gptr) res,MYF(0));
+  mysql->status= MYSQL_STATUS_READY;
   return mysql->fields;
 }
 
 static my_bool emb_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt)
 {
-  THD *thd= (THD*)mysql->thd;
-  if (mysql->net.last_errno)
-    return 1;
+  THD *thd= (THD*) mysql->thd;
+  MYSQL_DATA *res;
+
   stmt->stmt_id= thd->client_stmt_id;
   stmt->param_count= thd->client_param_count;
-  stmt->field_count= mysql->field_count;
+  stmt->field_count= 0;
 
-  if (stmt->field_count != 0)
+  if (thd->first_data)
   {
+    if (emb_read_query_result(mysql))
+      return 1;
+    stmt->field_count= mysql->field_count;
+    mysql->status= MYSQL_STATUS_READY;
+    res= thd->cur_data;
+    thd->cur_data= NULL;
     if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
       mysql->server_status|= SERVER_STATUS_IN_TRANS;
 
     stmt->fields= mysql->fields;
-    stmt->mem_root= mysql->field_alloc;
+    stmt->mem_root= res->alloc;
     mysql->fields= NULL;
+    my_free((gptr) res,MYF(0));
   }
 
   return 0;
@@ -201,13 +242,42 @@ static void emb_fetch_lengths(ulong *to, MYSQL_ROW column,
     *to= *column ? *(uint *)((*column) - sizeof(uint)) : 0;
 }
 
-static my_bool emb_mysql_read_query_result(MYSQL *mysql)
+static my_bool emb_read_query_result(MYSQL *mysql)
 {
-  if (mysql->net.last_errno)
-    return -1;
+  THD *thd= (THD*) mysql->thd;
+  MYSQL_DATA *res= thd->first_data;
+  DBUG_ASSERT(!thd->cur_data);
+  thd->first_data= res->embedded_info->next;
+  if (res->embedded_info->last_errno &&
+      !res->embedded_info->fields_list)
+  {
+    embedded_get_error(mysql, res);
+    return 1;
+  }
 
-  if (mysql->field_count)
+  mysql->warning_count= res->embedded_info->warning_count;
+  mysql->server_status= res->embedded_info->server_status;
+  mysql->field_count= res->fields;
+  mysql->fields= res->embedded_info->fields_list;
+  mysql->affected_rows= res->embedded_info->affected_rows;
+  mysql->insert_id= res->embedded_info->insert_id;
+  mysql->net.last_errno= 0;
+  mysql->net.last_error[0]= 0;
+  mysql->info= 0;
+
+  if (res->embedded_info->info[0])
+  {
+    strmake(mysql->info_buffer, res->embedded_info->info, MYSQL_ERRMSG_SIZE-1);
+    mysql->info= mysql->info_buffer;
+  }
+
+  if (res->embedded_info->fields_list)
+  {
     mysql->status=MYSQL_STATUS_GET_RESULT;
+    thd->cur_data= res;
+  }
+  else
+    my_free((gptr) res, MYF(0));
 
   return 0;
 }
@@ -215,14 +285,18 @@ static my_bool emb_mysql_read_query_result(MYSQL *mysql)
 static int emb_stmt_execute(MYSQL_STMT *stmt)
 {
   DBUG_ENTER("emb_stmt_execute");
-  char header[4];
+  char header[5];
+  MYSQL_DATA *res;
+  THD *thd;
+
   int4store(header, stmt->stmt_id);
-  THD *thd= (THD*)stmt->mysql->thd;
+  header[4]= stmt->flags;
+  thd= (THD*)stmt->mysql->thd;
   thd->client_param_count= stmt->param_count;
   thd->client_params= stmt->params;
   if (emb_advanced_command(stmt->mysql, COM_STMT_EXECUTE,0,0,
                            header, sizeof(header), 1) ||
-      emb_mysql_read_query_result(stmt->mysql))
+      emb_read_query_result(stmt->mysql))
   {
     NET *net= &stmt->mysql->net;
     set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
@@ -230,6 +304,8 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
   }
   stmt->affected_rows= stmt->mysql->affected_rows;
   stmt->insert_id= stmt->mysql->insert_id;
+  stmt->server_status= stmt->mysql->server_status;
+
   DBUG_RETURN(0);
 }
 
@@ -240,22 +316,53 @@ int emb_read_binary_rows(MYSQL_STMT *stmt)
     return 1;
   stmt->result= *data;
   my_free((char *) data, MYF(0));
+  set_stmt_errmsg(stmt, stmt->mysql->net.last_error,
+                  stmt->mysql->net.last_errno, stmt->mysql->net.sqlstate);
   return 0;
 }
 
+int emb_read_rows_from_cursor(MYSQL_STMT *stmt)
+{
+  MYSQL *mysql= stmt->mysql;
+  THD *thd= (THD*) mysql->thd;
+  MYSQL_DATA *res= thd->first_data;
+  DBUG_ASSERT(!thd->first_data->embedded_info->next);
+  thd->first_data= 0;
+  if (res->embedded_info->last_errno)
+  {
+    embedded_get_error(mysql, res);
+    set_stmt_errmsg(stmt, mysql->net.last_error,
+                    mysql->net.last_errno, mysql->net.sqlstate);
+    return 1;
+  }
+
+  thd->cur_data= res;
+  mysql->warning_count= res->embedded_info->warning_count;
+  mysql->server_status= res->embedded_info->server_status;
+  mysql->net.last_errno= 0;
+  mysql->net.last_error[0]= 0;
+
+  return emb_read_binary_rows(stmt);
+}
+
 int emb_unbuffered_fetch(MYSQL *mysql, char **row)
 {
-  MYSQL_DATA *data= ((THD*)mysql->thd)->data;
-  embedded_get_error(mysql);
-  if (mysql->net.last_errno)
-    return mysql->net.last_errno;
+  THD *thd= (THD*) mysql->thd;
+  MYSQL_DATA *data= thd->cur_data;
+  if (data && data->embedded_info->last_errno)
+  {
+    embedded_get_error(mysql, data);
+    thd->cur_data= 0;
+    return 1;
+  }
   if (!data || !data->data)
   {
     *row= NULL;
     if (data)
     {
+      thd->cur_data= thd->first_data;
+      thd->first_data= data->embedded_info->next;
       free_rows(data);
-      ((THD*)mysql->thd)->data= NULL;
     }
   }
   else
@@ -269,9 +376,9 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row)
 static void emb_free_embedded_thd(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  if (thd->data)
-    free_rows(thd->data);
+  thd->clear_data_list();
   thread_count--;
+  thd->store_globals();
   delete thd;
   mysql->thd=0;
 }
@@ -283,23 +390,11 @@ static const char * emb_read_statistics(MYSQL *mysql)
 }
 
 
-static MYSQL_RES * emb_mysql_store_result(MYSQL *mysql)
+static MYSQL_RES * emb_store_result(MYSQL *mysql)
 {
   return mysql_store_result(mysql);
 }
 
-my_bool emb_next_result(MYSQL *mysql)
-{
-  THD *thd= (THD*)mysql->thd;
-  DBUG_ENTER("emb_next_result");
-
-  if (emb_advanced_command(mysql, COM_QUERY,0,0,
-			   thd->query_rest.ptr(),thd->query_rest.length(),1) ||
-      emb_mysql_read_query_result(mysql))
-    DBUG_RETURN(1);
-
-  DBUG_RETURN(0);				/* No more results */
-}
 
 int emb_read_change_user_result(MYSQL *mysql, 
 				char *buff __attribute__((unused)),
@@ -310,10 +405,10 @@ int emb_read_change_user_result(MYSQL *mysql,
 
 MYSQL_METHODS embedded_methods= 
 {
-  emb_mysql_read_query_result,
+  emb_read_query_result,
   emb_advanced_command,
   emb_read_rows,
-  emb_mysql_store_result,
+  emb_store_result,
   emb_fetch_lengths, 
   emb_flush_use_result,
   emb_list_fields,
@@ -323,8 +418,9 @@ MYSQL_METHODS embedded_methods=
   emb_unbuffered_fetch,
   emb_free_embedded_thd,
   emb_read_statistics,
-  emb_next_result,
-  emb_read_change_user_result
+  emb_read_query_result,
+  emb_read_change_user_result,
+  emb_read_rows_from_cursor
 };
 
 C_MODE_END
@@ -483,6 +579,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag, char *db)
   THD *thd = (THD *)mysql->thd;
   thd->mysql= mysql;
   mysql->server_version= server_version;
+  init_alloc_root(&mysql->field_alloc, 8192, 0);
 }
 
 void *create_embedded_thd(int client_flag, char *db)
@@ -490,6 +587,7 @@ void *create_embedded_thd(int client_flag, char *db)
   THD * thd= new THD;
   thd->thread_id= thread_id++;
 
+  thd->thread_stack= (char*) &thd;
   if (thd->store_globals())
   {
     fprintf(stderr,"store_globals failed.\n");
@@ -517,9 +615,10 @@ void *create_embedded_thd(int client_flag, char *db)
   thd->security_ctx->db_access= DB_ACLS;
   thd->security_ctx->master_access= ~NO_ACCESS;
 #endif
-  thd->net.query_cache_query= 0;
-
-  thd->data= 0;
+  thd->cur_data= 0;
+  thd->first_data= 0;
+  thd->data_tail= &thd->first_data;
+  bzero((char*) &thd->net, sizeof(thd->net));
 
   thread_count++;
   return thd;
@@ -531,11 +630,15 @@ err:
 #ifdef NO_EMBEDDED_ACCESS_CHECKS
 int check_embedded_connection(MYSQL *mysql)
 {
+  int result;
   THD *thd= (THD*)mysql->thd;
   Security_context *sctx= thd->security_ctx;
-  sctx->host_or_ip= sctx->host= (char*)my_localhost;
+  sctx->host_or_ip= sctx->host= (char*) my_localhost;
+  strmake(sctx->priv_host, (char*) my_localhost,  MAX_HOSTNAME-1);
   sctx->priv_user= sctx->user= my_strdup(mysql->user, MYF(0));
-  return check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
+  result= check_user(thd, COM_CONNECT, NULL, 0, thd->db, true);
+  emb_read_query_result(mysql);
+  return result;
 }
 
 #else
@@ -616,26 +719,147 @@ static char *dup_str_aux(MEM_ROOT *root, const char *from, uint length,
 }
 
 
+/*
+  creates new result and hooks it to the list
+
+  SYNOPSIS
+  alloc_new_dataset()
+
+  NOTES
+    allocs the MYSQL_DATA + embedded_query_result couple
+    to store the next query result,
+    links these two and attach it to the THD::data_tail
+
+  RETURN
+    pointer to the newly created query result
+*/
+
+MYSQL_DATA *THD::alloc_new_dataset()
+{
+  MYSQL_DATA *data;
+  struct embedded_query_result *emb_data;
+  if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL),
+                       &data, sizeof(*data),
+                       &emb_data, sizeof(*emb_data),
+                       NULL))
+    return NULL;
+
+  emb_data->prev_ptr= &data->data;
+  cur_data= data;
+  *data_tail= data;
+  data_tail= &emb_data->next;
+  data->embedded_info= emb_data;
+  return data;
+}
+
+
+/*
+  stores server_status and warning_count in the current
+  query result structures
+
+  SYNOPSIS
+  write_eof_packet()
+  thd		current thread
+
+  NOTES
+    should be called to after we get the recordset-result
+
+*/
+
+static void write_eof_packet(THD *thd)
+{
+  /*
+    The following test should never be true, but it's better to do it
+    because if 'is_fatal_error' is set the server is not going to execute
+    other queries (see the if test in dispatch_command / COM_QUERY)
+  */
+  if (thd->is_fatal_error)
+    thd->server_status&= ~SERVER_MORE_RESULTS_EXISTS;
+  thd->cur_data->embedded_info->server_status= thd->server_status;
+  /*
+    Don't send warn count during SP execution, as the warn_list
+    is cleared between substatements, and mysqltest gets confused
+  */
+  thd->cur_data->embedded_info->warning_count=
+    (thd->spcont ? 0 : min(thd->total_warn_count, 65535));
+}
+
+
+/*
+  allocs new query result and initialises Protocol::alloc
+
+  SYNOPSIS
+  Protocol::begin_dataset()
+
+  RETURN
+    0 if success
+    1 if memory allocation failed
+*/
+
+int Protocol::begin_dataset()
+{
+  MYSQL_DATA *data= thd->alloc_new_dataset();
+  if (!data)
+    return 1;
+  alloc= &data->alloc;
+  init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
+  alloc->min_malloc=sizeof(MYSQL_ROWS);
+  return 0;
+}
+
+
+/*
+  remove last row of current recordset
+
+  SYNOPSIS
+  Protocol_simple::remove_last_row()
+
+  NOTES
+    does the loop from the beginning of the current recordset to
+    the last record and cuts it off.
+    Not supposed to be frequently called.
+*/
+
+void Protocol_simple::remove_last_row()
+{
+  MYSQL_DATA *data= thd->cur_data;
+  MYSQL_ROWS **last_row_hook= &data->data;
+  uint count= data->rows;
+  DBUG_ENTER("Protocol_simple::remove_last_row");
+  while (--count)
+    last_row_hook= &(*last_row_hook)->next;
+
+  *last_row_hook= 0;
+  data->embedded_info->prev_ptr= last_row_hook;
+  data->rows--;
+
+  DBUG_VOID_RETURN;
+}
+
+
 bool Protocol::send_fields(List<Item> *list, uint flags)
 {
   List_iterator_fast<Item> it(*list);
   Item                     *item;
   MYSQL_FIELD              *client_field;
-  MYSQL                    *mysql= thd->mysql;
   MEM_ROOT                 *field_alloc;
   CHARSET_INFO             *thd_cs= thd->variables.character_set_results;
   CHARSET_INFO             *cs= system_charset_info;
-  
+  MYSQL_DATA               *data;
   DBUG_ENTER("send_fields");
 
-  if (!mysql)            // bootstrap file handling
+  if (!thd->mysql)            // bootstrap file handling
     DBUG_RETURN(0);
 
-  field_count= list->elements;
-  field_alloc= &mysql->field_alloc;
-  if (!(client_field= thd->mysql->fields= 
-	(MYSQL_FIELD *)alloc_root(field_alloc, 
-				  sizeof(MYSQL_FIELD) * field_count)))
+  if (begin_dataset())
+    goto err;
+
+  data= thd->cur_data;
+  data->fields= field_count= list->elements;
+  field_alloc= &data->alloc;
+
+  if (!(client_field= data->embedded_info->fields_list= 
+	(MYSQL_FIELD*)alloc_root(field_alloc, sizeof(MYSQL_FIELD)*field_count)))
     goto err;
 
   while ((item= it++))
@@ -643,6 +867,10 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
     Send_field server_field;
     item->make_field(&server_field);
 
+    /* Keep things compatible for old clients */
+    if (server_field.type == MYSQL_TYPE_VARCHAR)
+      server_field.type= MYSQL_TYPE_VAR_STRING;
+
     client_field->db= dup_str_aux(field_alloc, server_field.db_name,
                                   strlen(server_field.db_name), cs, thd_cs);
     client_field->table= dup_str_aux(field_alloc, server_field.table_name,
@@ -703,7 +931,9 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
     client_field->max_length= 0;
     ++client_field;
   }
-  thd->mysql->field_count= field_count;
+
+  if (flags & SEND_EOF)
+    write_eof_packet(thd);
 
   DBUG_RETURN(prepare_for_send(list));
  err:
@@ -723,25 +953,11 @@ bool Protocol::write()
 bool Protocol_prep::write()
 {
   MYSQL_ROWS *cur;
-  MYSQL_DATA *data= thd->data;
-
-  if (!data)
-  {
-    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
-					MYF(MY_WME | MY_ZEROFILL))))
-      return true;
-    
-    alloc= &data->alloc;
-    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
-    alloc->min_malloc=sizeof(MYSQL_ROWS);
-    data->rows=0;
-    data->fields=field_count;
-    data->prev_ptr= &data->data;
-    thd->data= data;
-  }
+  MYSQL_DATA *data= thd->cur_data;
 
   data->rows++;
-  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+packet->length())))
+  if (!(cur= (MYSQL_ROWS *)alloc_root(alloc,
+                                      sizeof(MYSQL_ROWS)+packet->length())))
   {
     my_error(ER_OUT_OF_RESOURCES,MYF(0));
     return true;
@@ -750,8 +966,8 @@ bool Protocol_prep::write()
   memcpy(cur->data, packet->ptr()+1, packet->length()-1);
   cur->length= packet->length();       /* To allow us to do sanity checks */
 
-  *data->prev_ptr= cur;
-  data->prev_ptr= &cur->next;
+  *data->embedded_info->prev_ptr= cur;
+  data->embedded_info->prev_ptr= &cur->next;
   cur->next= 0;
   
   return false;
@@ -761,46 +977,52 @@ void
 send_ok(THD *thd,ha_rows affected_rows,ulonglong id,const char *message)
 {
   DBUG_ENTER("send_ok");
-  MYSQL *mysql= current_thd->mysql;
+  MYSQL_DATA *data;
+  MYSQL *mysql= thd->mysql;
+  
   if (!mysql)            // bootstrap file handling
     DBUG_VOID_RETURN;
-  mysql->affected_rows= affected_rows;
-  mysql->insert_id= id;
+  if (thd->net.no_send_ok)	// hack for re-parsing queries
+    DBUG_VOID_RETURN;
+  if (!(data= thd->alloc_new_dataset()))
+    return;
+  data->embedded_info->affected_rows= affected_rows;
+  data->embedded_info->insert_id= id;
   if (message)
-  {
-    strmake(thd->net.last_error, message, sizeof(thd->net.last_error)-1);
-    mysql->info= thd->net.last_error;
-  }
+    strmake(data->embedded_info->info, message,
+            sizeof(data->embedded_info->info)-1);
+
+  write_eof_packet(thd);
+  thd->cur_data= 0;
   DBUG_VOID_RETURN;
 }
 
 void
 send_eof(THD *thd)
 {
+  write_eof_packet(thd);
+  thd->cur_data= 0;
 }
 
+
+void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
+{
+  MYSQL_DATA *data= thd->cur_data ? thd->cur_data : thd->alloc_new_dataset();
+  struct embedded_query_result *ei= data->embedded_info;
+
+  ei->last_errno= sql_errno;
+  strmake(ei->info, err, sizeof(ei->info)-1);
+  strmov(ei->sqlstate, mysql_errno_to_sqlstate(sql_errno));
+  thd->cur_data= 0;
+}
+
+
 void Protocol_simple::prepare_for_resend()
 {
   MYSQL_ROWS *cur;
-  MYSQL_DATA *data= thd->data;
-
+  MYSQL_DATA *data= thd->cur_data;
   DBUG_ENTER("send_data");
 
-  if (!data)
-  {
-    if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
-					MYF(MY_WME | MY_ZEROFILL))))
-      goto err;
-    
-    alloc= &data->alloc;
-    init_alloc_root(alloc,8192,0);	/* Assume rowlength < 8192 */
-    alloc->min_malloc=sizeof(MYSQL_ROWS);
-    data->rows=0;
-    data->fields=field_count;
-    data->prev_ptr= &data->data;
-    thd->data= data;
-  }
-
   data->rows++;
   if (!(cur= (MYSQL_ROWS *)alloc_root(alloc, sizeof(MYSQL_ROWS)+(field_count + 1) * sizeof(char *))))
   {
@@ -809,10 +1031,10 @@ void Protocol_simple::prepare_for_resend()
   }
   cur->data= (MYSQL_ROW)(((char *)cur) + sizeof(MYSQL_ROWS));
 
-  *data->prev_ptr= cur;
-  data->prev_ptr= &cur->next;
+  *data->embedded_info->prev_ptr= cur;
+  data->embedded_info->prev_ptr= &cur->next;
   next_field=cur->data;
-  next_mysql_field= thd->mysql->fields;
+  next_mysql_field= data->embedded_info->fields_list;
 err:
   DBUG_VOID_RETURN;
 }
diff --git a/libmysqld/libmysqld.c b/libmysqld/libmysqld.c
index 70074e44c6f..cad1bd4c47b 100644
--- a/libmysqld/libmysqld.c
+++ b/libmysqld/libmysqld.c
@@ -14,6 +14,11 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#include <my_global.h>
+#include <mysql.h>
+#include <mysql_embed.h>
+#include <mysqld_error.h>
+#include <my_pthread.h>
 #include "embedded_priv.h"
 #include <my_sys.h>
 #include <mysys_err.h>
@@ -193,7 +198,12 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
 
   if (!user)
     user= "";
-  mysql->user=my_strdup(user,MYF(0));
+   /* 
+      We need to alloc some space for mysql->info but don't want to
+      put extra 'my_free's in mysql_close.
+      So we alloc it with the 'user' string to be freed at once
+   */
+  mysql->user= my_strdup(user, MYF(0));
 
   port=0;
   unix_socket=0;
@@ -207,6 +217,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
   if (db)
     client_flag|=CLIENT_CONNECT_WITH_DB;
 
+  mysql->info_buffer= my_malloc(MYSQL_ERRMSG_SIZE, MYF(0));
   mysql->thd= create_embedded_thd(client_flag, db_name);
 
   init_embedded_mysql(mysql, client_flag, db_name);
@@ -243,7 +254,6 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
   DBUG_RETURN(mysql);
 
 error:
-  embedded_get_error(mysql);
   DBUG_PRINT("error",("message: %u (%s)", mysql->net.last_errno,
 		      mysql->net.last_error));
   {
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index c4038f88da4..cff655718dd 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -318,6 +318,7 @@ while test $# -gt 0; do
       USE_EMBEDDED_SERVER=1
       USE_MANAGER=0 NO_SLAVE=1
       USE_RUNNING_SERVER=0
+      USE_NDBCLUSTER=""
       TEST_MODE="$TEST_MODE embedded" ;;
     --purify)
       USE_PURIFY=1
diff --git a/mysql-test/r/binlog.result b/mysql-test/r/binlog.result
index 5d5b78abe29..25930c31735 100644
--- a/mysql-test/r/binlog.result
+++ b/mysql-test/r/binlog.result
@@ -17,7 +17,7 @@ master-bin.000001	#	Query	1	#	use `test`; insert t1 values (5)
 master-bin.000001	#	Query	1	#	use `test`; COMMIT
 master-bin.000001	#	Query	1	#	use `test`; BEGIN
 master-bin.000001	#	Query	1	#	use `test`; insert t2 values (5)
-master-bin.000001	#	Xid	1	#	COMMIT /* xid=11 */
+master-bin.000001	#	Xid	1	#	COMMIT /* xid=12 */
 drop table t1,t2;
 reset master;
 create table t1 (n int) engine=innodb;
@@ -128,7 +128,7 @@ master-bin.000001	#	Query	1	#	use `test`; insert into t1 values(4 + 4)
 master-bin.000001	#	Query	1	#	use `test`; insert into t1 values(3 + 4)
 master-bin.000001	#	Query	1	#	use `test`; insert into t1 values(2 + 4)
 master-bin.000001	#	Query	1	#	use `test`; insert into t1 values(1 + 4)
-master-bin.000001	#	Xid	1	#	COMMIT /* xid=18 */
+master-bin.000001	#	Xid	1	#	COMMIT /* xid=19 */
 master-bin.000001	#	Rotate	1	#	master-bin.000002;pos=4
 show binlog events in 'master-bin.000002' from 98;
 Log_name	Pos	Event_type	Server_id	End_log_pos	Info
diff --git a/mysql-test/r/ctype_cp932.result b/mysql-test/r/ctype_cp932.result
index 61540cb8467..ed57b87c1ba 100755
--- a/mysql-test/r/ctype_cp932.result
+++ b/mysql-test/r/ctype_cp932.result
@@ -11315,20 +11315,6 @@ DROP TABLE t1;
 DROP TABLE t2;
 DROP TABLE t3;
 DROP TABLE t4;
-RESET MASTER;
-CREATE TABLE t1(f1 blob);
-PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
-SET @var1= x'8300';
-EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
-Log_name	Pos	Event_type	Server_id	End_log_pos	Info
-master-bin.000001	98	Query	1	185	use `test`; CREATE TABLE t1(f1 blob)
-master-bin.000001	185	User var	1	224	@`var1`=_binary 0x8300 COLLATE binary
-master-bin.000001	224	Query	1	317	use `test`; INSERT INTO t1 VALUES(@'var1')
-SELECT HEX(f1) FROM t1;
-HEX(f1)
-8300
-DROP table t1;
 SET collation_connection='cp932_japanese_ci';
 create table t1 select repeat('a',4000) a;
 delete from t1;
diff --git a/mysql-test/r/ctype_cp932_notembedded.result b/mysql-test/r/ctype_cp932_notembedded.result
new file mode 100644
index 00000000000..d04fce7738c
--- /dev/null
+++ b/mysql-test/r/ctype_cp932_notembedded.result
@@ -0,0 +1,17 @@
+drop table if exists t1;
+set names cp932;
+set character_set_database = cp932;
+RESET MASTER;
+CREATE TABLE t1(f1 blob);
+PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
+SET @var1= x'8300';
+EXECUTE stmt1 USING @var1;
+SHOW BINLOG EVENTS FROM 98;
+Log_name	Pos	Event_type	Server_id	End_log_pos	Info
+master-bin.000001	98	Query	1	185	use `test`; CREATE TABLE t1(f1 blob)
+master-bin.000001	185	User var	1	224	@`var1`=_binary 0x8300 COLLATE binary
+master-bin.000001	224	Query	1	317	use `test`; INSERT INTO t1 VALUES(@'var1')
+SELECT HEX(f1) FROM t1;
+HEX(f1)
+8300
+DROP table t1;
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 026ad53193d..e8af68a6067 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -2673,25 +2673,6 @@ checksum table t1;
 Table	Checksum
 test.t1	2050879373
 drop table t1;
-create table t1 (col1 integer primary key, col2 integer) engine=innodb;
-insert t1 values (1,100);
-create function f1 () returns integer begin
-declare var1 int;
-select col2 into var1 from t1 where col1=1 for update;
-return var1;
-end|
-start transaction;
-select f1();
-f1()
-100
- update t1 set col2=0 where col1=1;
-select * from t1;
-col1	col2
-1	100
-rollback;
-rollback;
-drop table t1;
-drop function f1;
 create table t1 (
 a int, b char(10), c char(10), filler char(10), primary key(a, b(2)), unique key (a, c(2))
 ) character set utf8 engine = innodb;
diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/r/innodb_notembedded.result
new file mode 100644
index 00000000000..9aac20e515d
--- /dev/null
+++ b/mysql-test/r/innodb_notembedded.result
@@ -0,0 +1,20 @@
+drop table if exists t1;
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+start transaction;
+select f1();
+f1()
+100
+ update t1 set col2=0 where col1=1;
+select * from t1;
+col1	col2
+1	100
+rollback;
+rollback;
+drop table t1;
+drop function f1;
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 1a8bc542c27..de07021f217 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -1,6 +1,6 @@
-select -1 as "before_use_test" ;
+select 0 as "before_use_test" ;
 before_use_test
--1
+0
 select otto from (select 1 as otto) as t1;
 otto
 1
diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result
index 5a7c387a650..4bf4ebb910d 100644
--- a/mysql-test/r/query_cache.result
+++ b/mysql-test/r/query_cache.result
@@ -1104,56 +1104,20 @@ call f1();
 s1
 s1
 s1
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	3
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	3
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	0
 call f1();
 s1
 s1
 s1
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	3
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	3
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	3
 call f1();
 s1
 s1
 s1
 select sql_cache * from t1;
 s1
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	4
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	4
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	6
 insert into t1 values (1);
 select sql_cache * from t1;
 s1
 1
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	1
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	5
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	6
 call f1();
 s1
 1
@@ -1171,15 +1135,6 @@ s1
 select sql_cache * from t1;
 s1
 1
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	4
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	8
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	10
 flush query cache;
 reset query cache;
 flush status;
diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result
index e773a63525b..77fa198eb80 100644
--- a/mysql-test/r/query_cache_notembedded.result
+++ b/mysql-test/r/query_cache_notembedded.result
@@ -94,4 +94,224 @@ a
 SELECT * FROM t1;
 a
 drop table t1;
+flush query cache;
+reset query cache;
+flush status;
+create table t1 (s1 int)//
+create procedure f1 () begin
+select sql_cache * from t1;
+select sql_cache * from t1;
+select sql_cache * from t1;
+end;//
+create procedure f2 () begin
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1;
+end;//
+create procedure f3 () begin
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+end;//
+create procedure f4 () begin
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1 where s1=1;
+end;//
+call f1();
+s1
+s1
+s1
+show status like "Qcache_queries_in_cache";
+Variable_name	Value
+Qcache_queries_in_cache	3
+show status like "Qcache_inserts";
+Variable_name	Value
+Qcache_inserts	3
+show status like "Qcache_hits";
+Variable_name	Value
+Qcache_hits	0
+call f1();
+s1
+s1
+s1
+show status like "Qcache_queries_in_cache";
+Variable_name	Value
+Qcache_queries_in_cache	3
+show status like "Qcache_inserts";
+Variable_name	Value
+Qcache_inserts	3
+show status like "Qcache_hits";
+Variable_name	Value
+Qcache_hits	3
+call f1();
+s1
+s1
+s1
+select sql_cache * from t1;
+s1
+show status like "Qcache_queries_in_cache";
+Variable_name	Value
+Qcache_queries_in_cache	4
+show status like "Qcache_inserts";
+Variable_name	Value
+Qcache_inserts	4
+show status like "Qcache_hits";
+Variable_name	Value
+Qcache_hits	6
+insert into t1 values (1);
+select sql_cache * from t1;
+s1
+1
+show status like "Qcache_queries_in_cache";
+Variable_name	Value
+Qcache_queries_in_cache	1
+show status like "Qcache_inserts";
+Variable_name	Value
+Qcache_inserts	5
+show status like "Qcache_hits";
+Variable_name	Value
+Qcache_hits	6
+call f1();
+s1
+1
+s1
+1
+s1
+1
+call f1();
+s1
+1
+s1
+1
+s1
+1
+select sql_cache * from t1;
+s1
+1
+show status like "Qcache_queries_in_cache";
+Variable_name	Value
+Qcache_queries_in_cache	4
+show status like "Qcache_inserts";
+Variable_name	Value
+Qcache_inserts	8
+show status like "Qcache_hits";
+Variable_name	Value
+Qcache_hits	10
+flush query cache;
+reset query cache;
+flush status;
+select sql_cache * from t1;
+s1
+1
+select sql_cache * from t1 where s1=1;
+s1
+1
+call f1();
+s1
+1
+s1
+1
+s1
+1
+call f2();
+s1
+1
+s1
+1
+call f3();
+s1
+1
+s1
+1
+call f4();
+s1
+1
+s1
+1
+s1
+1
+s1
+1
+s1
+1
+call f4();
+s1
+1
+s1
+1
+s1
+1
+s1
+1
+s1
+1
+call f3();
+s1
+1
+s1
+1
+call f2();
+s1
+1
+s1
+1
+select sql_cache * from t1 where s1=1;
+s1
+1
+insert into t1 values (2);
+call f1();
+s1
+1
+2
+s1
+1
+2
+s1
+1
+2
+select sql_cache * from t1 where s1=1;
+s1
+1
+select sql_cache * from t1;
+s1
+1
+2
+call f1();
+s1
+1
+2
+s1
+1
+2
+s1
+1
+2
+call f3();
+s1
+1
+2
+s1
+1
+call f3();
+s1
+1
+2
+s1
+1
+call f1();
+s1
+1
+2
+s1
+1
+2
+s1
+1
+2
+drop procedure f1;
+drop procedure f2;
+drop procedure f3;
+drop procedure f4;
+drop table t1;
 set GLOBAL query_cache_size=0;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index c0e02cbeb6f..67a6e55b29e 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -464,19 +464,6 @@ create table t5 (x int)|
 call bug3294()|
 ERROR 42S02: Unknown table 't5'
 drop procedure bug3294|
-drop procedure if exists bug6807|
-create procedure bug6807()
-begin
-declare id int;
-set id = connection_id();
-kill query id;
-select 'Not reached';
-end|
-call bug6807()|
-ERROR 70100: Query execution was interrupted
-call bug6807()|
-ERROR 70100: Query execution was interrupted
-drop procedure bug6807|
 drop procedure if exists bug8776_1|
 drop procedure if exists bug8776_2|
 drop procedure if exists bug8776_3|
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 663204681f2..a4c920f8e15 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -2463,7 +2463,6 @@ show create database test;
 show databases like 'foo';
 show errors;
 show columns from t1;
-show grants for 'root'@'localhost';
 show keys from t1;
 show open tables like 'foo';
 show privileges;
@@ -2490,8 +2489,6 @@ Level	Code	Message
 Field	Type	Null	Key	Default	Extra
 id	char(16)	NO			
 data	int(11)	NO			
-Grants for root@localhost
-GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
 Database	Table	In_use	Name_locked
 Privilege	Context	Comment
@@ -2544,8 +2541,6 @@ Level	Code	Message
 Field	Type	Null	Key	Default	Extra
 id	char(16)	NO			
 data	int(11)	NO			
-Grants for root@localhost
-GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
 Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
 Database	Table	In_use	Name_locked
 Privilege	Context	Comment
@@ -2581,18 +2576,6 @@ Tables_in_test (foo)
 Variable_name	Value
 Level	Code	Message
 drop procedure bug4902|
-drop procedure if exists bug4902_2|
-create procedure bug4902_2()
-begin
-show processlist;
-end|
-call bug4902_2()|
-Id	User	Host	db	Command	Time	State	Info
-#	root	localhost	test	Query	#	NULL	show processlist
-call bug4902_2()|
-Id	User	Host	db	Command	Time	State	Info
-#	root	localhost	test	Query	#	NULL	show processlist
-drop procedure bug4902_2|
 drop procedure if exists bug4904|
 create procedure bug4904()
 begin
@@ -2735,52 +2718,6 @@ select @x|
 NULL
 delete from t1|
 drop procedure bug4941|
-drop procedure if exists bug3583|
-drop procedure if exists bug3583|
-create procedure bug3583()
-begin
-declare c int;
-select * from t1;
-select count(*) into c from t1;
-select c;
-end|
-insert into t1 values ("x", 3), ("y", 5)|
-set @x = @@query_cache_size|
-set global query_cache_size = 10*1024*1024|
-flush status|
-flush query cache|
-show status like 'Qcache_hits'|
-Variable_name	Value
-Qcache_hits	0
-call bug3583()|
-id	data
-x	3
-y	5
-c
-2
-show status like 'Qcache_hits'|
-Variable_name	Value
-Qcache_hits	0
-call bug3583()|
-id	data
-x	3
-y	5
-c
-2
-call bug3583()|
-id	data
-x	3
-y	5
-c
-2
-show status like 'Qcache_hits'|
-Variable_name	Value
-Qcache_hits	2
-set global query_cache_size = @x|
-flush status|
-flush query cache|
-delete from t1|
-drop procedure bug3583|
 drop procedure if exists bug4905|
 create table t3 (s1 int,primary key (s1))|
 drop procedure if exists bug4905|
@@ -2996,17 +2933,6 @@ select id, bug5240() from t1|
 id	bug5240()
 answer	42
 drop function bug5240|
-drop function if exists bug5278|
-create function bug5278 () returns char
-begin
-SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
-return 'okay';
-end|
-select bug5278()|
-ERROR 42000: Can't find any matching row in the user table
-select bug5278()|
-ERROR 42000: Can't find any matching row in the user table
-drop function bug5278|
 drop procedure if exists p1|
 create table t3(id int)|
 insert into t3 values(1)|
@@ -4352,14 +4278,6 @@ select bug10100f(5)|
 ERROR HY000: Recursive stored functions and triggers are not allowed.
 call bug10100t(5)|
 ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug10100p
-set @@max_sp_recursion_depth=255|
-set @var=1|
-call bug10100p(255, @var)|
-call bug10100pt(1,255)|
-call bug10100pv(1,255)|
-call bug10100pd(1,255)|
-call bug10100pc(1,255)|
-set @@max_sp_recursion_depth=0|
 deallocate prepare stmt2|
 drop function bug10100f|
 drop procedure bug10100p|
diff --git a/mysql-test/r/sp.result.orig b/mysql-test/r/sp.result.orig
new file mode 100644
index 00000000000..663204681f2
--- /dev/null
+++ b/mysql-test/r/sp.result.orig
@@ -0,0 +1,4853 @@
+use test;
+drop table if exists t1,t2,t3,t4;
+create table t1 (
+id   char(16) not null default '',
+data int not null
+);
+create table t2 (
+s   char(16),
+i   int,
+d   double
+);
+drop procedure if exists foo42;
+create procedure foo42()
+insert into test.t1 values ("foo", 42);
+call foo42();
+select * from t1;
+id	data
+foo	42
+delete from t1;
+drop procedure foo42;
+drop procedure if exists bar;
+create procedure bar(x char(16), y int)
+insert into test.t1 values (x, y);
+call bar("bar", 666);
+select * from t1;
+id	data
+bar	666
+delete from t1;
+drop procedure if exists empty|
+create procedure empty()
+begin
+end|
+call empty()|
+drop procedure empty|
+drop procedure if exists scope|
+create procedure scope(a int, b float)
+begin
+declare b int;
+declare c float;
+begin
+declare c int;
+end;
+end|
+drop procedure scope|
+drop procedure if exists two|
+create procedure two(x1 char(16), x2 char(16), y int)
+begin
+insert into test.t1 values (x1, y);
+insert into test.t1 values (x2, y);
+end|
+call two("one", "two", 3)|
+select * from t1|
+id	data
+one	3
+two	3
+delete from t1|
+drop procedure two|
+drop procedure if exists locset|
+create procedure locset(x char(16), y int)
+begin
+declare z1, z2 int;
+set z1 = y;
+set z2 = z1+2;
+insert into test.t1 values (x, z2);
+end|
+call locset("locset", 19)|
+select * from t1|
+id	data
+locset	21
+delete from t1|
+drop procedure locset|
+drop procedure if exists setcontext|
+create procedure setcontext()
+begin
+declare data int default 2;
+insert into t1 (id, data) values ("foo", 1);
+replace t1 set data = data, id = "bar";
+update t1 set id = "kaka", data = 3 where t1.data = data;
+end|
+call setcontext()|
+select * from t1|
+id	data
+foo	1
+kaka	3
+delete from t1|
+drop procedure setcontext|
+create table t3 ( d date, i int, f double, s varchar(32) )|
+drop procedure if exists nullset|
+create procedure nullset()
+begin
+declare ld date;
+declare li int;
+declare lf double;
+declare ls varchar(32);
+set ld = null, li = null, lf = null, ls = null;
+insert into t3 values (ld, li, lf, ls);
+insert into t3 (i, f, s) values ((ld is null), 1,    "ld is null"),
+((li is null), 1,    "li is null"),
+((li = 0),     null, "li = 0"),
+((lf is null), 1,    "lf is null"),
+((lf = 0),     null, "lf = 0"),
+((ls is null), 1,    "ls is null");
+end|
+call nullset()|
+select * from t3|
+d	i	f	s
+NULL	NULL	NULL	NULL
+NULL	1	1	ld is null
+NULL	1	1	li is null
+NULL	NULL	NULL	li = 0
+NULL	1	1	lf is null
+NULL	NULL	NULL	lf = 0
+NULL	1	1	ls is null
+drop table t3|
+drop procedure nullset|
+drop procedure if exists mixset|
+create procedure mixset(x char(16), y int)
+begin
+declare z int;
+set @z = y, z = 666, max_join_size = 100;
+insert into test.t1 values (x, z);
+end|
+call mixset("mixset", 19)|
+show variables like 'max_join_size'|
+Variable_name	Value
+max_join_size	100
+select id,data,@z from t1|
+id	data	@z
+mixset	666	19
+delete from t1|
+drop procedure mixset|
+drop procedure if exists zip|
+create procedure zip(x char(16), y int)
+begin
+declare z int;
+call zap(y, z);
+call bar(x, z);
+end|
+drop procedure if exists zap|
+create procedure zap(x int, out y int)
+begin
+declare z int;
+set z = x+1, y = z;
+end|
+call zip("zip", 99)|
+select * from t1|
+id	data
+zip	100
+delete from t1|
+drop procedure zip|
+drop procedure bar|
+call zap(7, @zap)|
+select @zap|
+@zap
+8
+drop procedure zap|
+drop procedure if exists c1|
+create procedure c1(x int)
+call c2("c", x)|
+drop procedure if exists c2|
+create procedure c2(s char(16), x int)
+call c3(x, s)|
+drop procedure if exists c3|
+create procedure c3(x int, s char(16))
+call c4("level", x, s)|
+drop procedure if exists c4|
+create procedure c4(l char(8), x int, s char(16))
+insert into t1 values (concat(l,s), x)|
+call c1(42)|
+select * from t1|
+id	data
+levelc	42
+delete from t1|
+drop procedure c1|
+drop procedure c2|
+drop procedure c3|
+drop procedure c4|
+drop procedure if exists iotest|
+create procedure iotest(x1 char(16), x2 char(16), y int)
+begin
+call inc2(x2, y);
+insert into test.t1 values (x1, y);
+end|
+drop procedure if exists inc2|
+create procedure inc2(x char(16), y int)
+begin
+call inc(y);
+insert into test.t1 values (x, y);
+end|
+drop procedure if exists inc|
+create procedure inc(inout io int)
+set io = io + 1|
+call iotest("io1", "io2", 1)|
+select * from t1|
+id	data
+io2	2
+io1	1
+delete from t1|
+drop procedure iotest|
+drop procedure inc2|
+drop procedure if exists incr|
+create procedure incr(inout x int)
+call inc(x)|
+select @zap|
+@zap
+8
+call incr(@zap)|
+select @zap|
+@zap
+9
+drop procedure inc|
+drop procedure incr|
+drop procedure if exists cbv1|
+create procedure cbv1()
+begin
+declare y int default 3;
+call cbv2(y+1, y);
+insert into test.t1 values ("cbv1", y);
+end|
+drop procedure if exists cbv2|
+create procedure cbv2(y1 int, inout y2 int)
+begin
+set y2 = 4711;
+insert into test.t1 values ("cbv2", y1);
+end|
+call cbv1()|
+select * from t1|
+id	data
+cbv2	4
+cbv1	4711
+delete from t1|
+drop procedure cbv1|
+drop procedure cbv2|
+insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)|
+drop procedure if exists sub1|
+create procedure sub1(id char(16), x int)
+insert into test.t1 values (id, x)|
+drop procedure if exists sub2|
+create procedure sub2(id char(16))
+begin
+declare x int;
+set x = (select sum(t.i) from test.t2 t);
+insert into test.t1 values (id, x);
+end|
+drop procedure if exists sub3|
+create function sub3(i int) returns int
+return i+1|
+call sub1("sub1a", (select 7))|
+call sub1("sub1b", (select max(i) from t2))|
+call sub1("sub1c", (select i,d from t2 limit 1))|
+ERROR 21000: Operand should contain 1 column(s)
+call sub1("sub1d", (select 1 from (select 1) a))|
+call sub2("sub2")|
+select * from t1|
+id	data
+sub1a	7
+sub1b	3
+sub1d	1
+sub2	6
+select sub3((select max(i) from t2))|
+sub3((select max(i) from t2))
+4
+drop procedure sub1|
+drop procedure sub2|
+drop function sub3|
+delete from t1|
+delete from t2|
+drop procedure if exists a0|
+create procedure a0(x int)
+while x do
+set x = x-1;
+insert into test.t1 values ("a0", x);
+end while|
+call a0(3)|
+select * from t1|
+id	data
+a0	2
+a0	1
+a0	0
+delete from t1|
+drop procedure a0|
+drop procedure if exists a|
+create procedure a(x int)
+while x > 0 do
+set x = x-1;
+insert into test.t1 values ("a", x);
+end while|
+call a(3)|
+select * from t1|
+id	data
+a	2
+a	1
+a	0
+delete from t1|
+drop procedure a|
+drop procedure if exists b|
+create procedure b(x int)
+repeat
+insert into test.t1 values (repeat("b",3), x);
+set x = x-1;
+until x = 0 end repeat|
+call b(3)|
+select * from t1|
+id	data
+bbb	3
+bbb	2
+bbb	1
+delete from t1|
+drop procedure b|
+drop procedure if exists b2|
+create procedure b2(x int)
+repeat(select 1 into outfile 'b2');
+insert into test.t1 values (repeat("b2",3), x);
+set x = x-1;
+until x = 0 end repeat|
+drop procedure b2|
+drop procedure if exists c|
+create procedure c(x int)
+hmm: while x > 0 do
+insert into test.t1 values ("c", x);
+set x = x-1;
+iterate hmm;
+insert into test.t1 values ("x", x);
+end while hmm|
+call c(3)|
+select * from t1|
+id	data
+c	3
+c	2
+c	1
+delete from t1|
+drop procedure c|
+drop procedure if exists d|
+create procedure d(x int)
+hmm: while x > 0 do
+insert into test.t1 values ("d", x);
+set x = x-1;
+leave hmm;
+insert into test.t1 values ("x", x);
+end while|
+call d(3)|
+select * from t1|
+id	data
+d	3
+delete from t1|
+drop procedure d|
+drop procedure if exists e|
+create procedure e(x int)
+foo: loop
+if x = 0 then
+leave foo;
+end if;
+insert into test.t1 values ("e", x);
+set x = x-1;
+end loop foo|
+call e(3)|
+select * from t1|
+id	data
+e	3
+e	2
+e	1
+delete from t1|
+drop procedure e|
+drop procedure if exists f|
+create procedure f(x int)
+if x < 0 then
+insert into test.t1 values ("f", 0);
+elseif x = 0 then
+insert into test.t1 values ("f", 1);
+else
+insert into test.t1 values ("f", 2);
+end if|
+call f(-2)|
+call f(0)|
+call f(4)|
+select * from t1|
+id	data
+f	0
+f	1
+f	2
+delete from t1|
+drop procedure f|
+drop procedure if exists g|
+create procedure g(x int)
+case
+when x < 0 then
+insert into test.t1 values ("g", 0);
+when x = 0 then
+insert into test.t1 values ("g", 1);
+else
+insert into test.t1 values ("g", 2);
+end case|
+call g(-42)|
+call g(0)|
+call g(1)|
+select * from t1|
+id	data
+g	0
+g	1
+g	2
+delete from t1|
+drop procedure g|
+drop procedure if exists h|
+create procedure h(x int)
+case x
+when 0 then
+insert into test.t1 values ("h0", x);
+when 1 then
+insert into test.t1 values ("h1", x);
+else
+insert into test.t1 values ("h?", x);
+end case|
+call h(0)|
+call h(1)|
+call h(17)|
+select * from t1|
+id	data
+h0	0
+h1	1
+h?	17
+delete from t1|
+drop procedure h|
+drop procedure if exists i|
+create procedure i(x int)
+foo:
+begin
+if x = 0 then
+leave foo;
+end if;
+insert into test.t1 values ("i", x);
+end foo|
+call i(0)|
+call i(3)|
+select * from t1|
+id	data
+i	3
+delete from t1|
+drop procedure i|
+insert into t1 values ("foo", 3), ("bar", 19)|
+insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
+drop procedure if exists sel1|
+create procedure sel1()
+begin
+select * from t1;
+end|
+call sel1()|
+id	data
+foo	3
+bar	19
+drop procedure sel1|
+drop procedure if exists sel2|
+create procedure sel2()
+begin
+select * from t1;
+select * from t2;
+end|
+call sel2()|
+id	data
+foo	3
+bar	19
+s	i	d
+x	9	4.1
+y	-1	19.2
+z	3	2.2
+drop procedure sel2|
+delete from t1|
+delete from t2|
+drop procedure if exists into_test|
+create procedure into_test(x char(16), y int)
+begin
+insert into test.t1 values (x, y);
+select id,data into x,y from test.t1 limit 1;
+insert into test.t1 values (concat(x, "2"), y+2);
+end|
+call into_test("into", 100)|
+select * from t1|
+id	data
+into	100
+into2	102
+delete from t1|
+drop procedure into_test|
+drop procedure if exists into_tes2|
+create procedure into_test2(x char(16), y int)
+begin
+insert into test.t1 values (x, y);
+select id,data into x,@z from test.t1 limit 1;
+insert into test.t1 values (concat(x, "2"), y+2);
+end|
+call into_test2("into", 100)|
+select id,data,@z from t1|
+id	data	@z
+into	100	100
+into2	102	100
+delete from t1|
+drop procedure into_test2|
+drop procedure if exists into_test3|
+create procedure into_test3()
+begin
+declare x char(16);
+declare y int;
+select * into x,y from test.t1 limit 1;
+insert into test.t2 values (x, y, 0.0);
+end|
+insert into t1 values ("into3", 19)|
+call into_test3()|
+call into_test3()|
+select * from t2|
+s	i	d
+into3	19	0
+into3	19	0
+delete from t1|
+delete from t2|
+drop procedure into_test3|
+drop procedure if exists into_test4|
+create procedure into_test4()
+begin
+declare x int;
+select data into x from test.t1 limit 1;
+insert into test.t3 values ("into4", x);
+end|
+delete from t1|
+create table t3 ( s char(16), d int)|
+call into_test4()|
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+select * from t3|
+s	d
+into4	NULL
+insert into t1 values ("i4", 77)|
+call into_test4()|
+select * from t3|
+s	d
+into4	NULL
+into4	77
+delete from t1|
+drop table t3|
+drop procedure into_test4|
+drop procedure if exists into_outfile|
+create procedure into_outfile(x char(16), y int)
+begin
+insert into test.t1 values (x, y);
+select * into outfile "../tmp/spout" from test.t1;
+insert into test.t1 values (concat(x, "2"), y+2);
+end|
+call into_outfile("ofile", 1)|
+delete from t1|
+drop procedure into_outfile|
+drop procedure if exists into_dumpfile|
+create procedure into_dumpfile(x char(16), y int)
+begin
+insert into test.t1 values (x, y);
+select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
+insert into test.t1 values (concat(x, "2"), y+2);
+end|
+call into_dumpfile("dfile", 1)|
+delete from t1|
+drop procedure into_dumpfile|
+drop procedure if exists create_select|
+create procedure create_select(x char(16), y int)
+begin
+insert into test.t1 values (x, y);
+create temporary table test.t3 select * from test.t1;
+insert into test.t3 values (concat(x, "2"), y+2);
+end|
+call create_select("cs", 90)|
+select * from t1, t3|
+id	data	id	data
+cs	90	cs	90
+cs	90	cs2	92
+drop table t3|
+delete from t1|
+drop procedure create_select|
+drop function if exists e|
+create function e() returns double
+return 2.7182818284590452354|
+set @e = e()|
+select e(), @e|
+e()	@e
+2.718281828459	2.718281828459
+drop function if exists inc|
+create function inc(i int) returns int
+return i+1|
+select inc(1), inc(99), inc(-71)|
+inc(1)	inc(99)	inc(-71)
+2	100	-70
+drop function if exists mul|
+create function mul(x int, y int) returns int
+return x*y|
+select mul(1,1), mul(3,5), mul(4711, 666)|
+mul(1,1)	mul(3,5)	mul(4711, 666)
+1	15	3137526
+drop function if exists append|
+create function append(s1 char(8), s2 char(8)) returns char(16)
+return concat(s1, s2)|
+select append("foo", "bar")|
+append("foo", "bar")
+foobar
+drop function if exists fac|
+create function fac(n int unsigned) returns bigint unsigned
+begin
+declare f bigint unsigned default 1;
+while n > 1 do
+set f = f * n;
+set n = n - 1;
+end while;
+return f;
+end|
+select fac(1), fac(2), fac(5), fac(10)|
+fac(1)	fac(2)	fac(5)	fac(10)
+1	2	120	3628800
+drop function if exists fun|
+create function fun(d double, i int, u int unsigned) returns double
+return mul(inc(i), fac(u)) / e()|
+select fun(2.3, 3, 5)|
+fun(2.3, 3, 5)
+176.58213176229
+insert into t2 values (append("xxx", "yyy"), mul(4,3), e())|
+insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))|
+select * from t2 where s = append("a", "b")|
+s	i	d
+ab	24	1324.36598821719
+select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)|
+s	i	d
+xxxyyy	12	2.71828182845905
+ab	24	1324.36598821719
+select * from t2 where d = e()|
+s	i	d
+xxxyyy	12	2.71828182845905
+select * from t2|
+s	i	d
+xxxyyy	12	2.71828182845905
+ab	24	1324.36598821719
+delete from t2|
+drop function e|
+drop function inc|
+drop function mul|
+drop function append|
+drop function fun|
+drop procedure if exists hndlr1|
+create procedure hndlr1(val int)
+begin
+declare x int default 0;
+declare foo condition for 1136;
+declare bar condition for sqlstate '42S98';        # Just for testing syntax
+declare zip condition for sqlstate value '42S99';  # Just for testing syntax
+declare continue handler for foo set x = 1;
+insert into test.t1 values ("hndlr1", val, 2);  # Too many values
+if (x) then
+insert into test.t1 values ("hndlr1", val);   # This instead then
+end if;
+end|
+call hndlr1(42)|
+select * from t1|
+id	data
+hndlr1	42
+delete from t1|
+drop procedure hndlr1|
+drop procedure if exists hndlr2|
+create procedure hndlr2(val int)
+begin
+declare x int default 0;
+begin
+declare exit handler for sqlstate '21S01' set x = 1;
+insert into test.t1 values ("hndlr2", val, 2); # Too many values
+end;
+insert into test.t1 values ("hndlr2", x);
+end|
+call hndlr2(42)|
+select * from t1|
+id	data
+hndlr2	1
+delete from t1|
+drop procedure hndlr2|
+drop procedure if exists hndlr3|
+create procedure hndlr3(val int)
+begin
+declare x int default 0;
+declare continue handler for sqlexception        # Any error
+begin
+declare z int;
+set z = 2 * val;
+set x = 1;
+end;
+if val < 10 then
+begin
+declare y int;
+set y = val + 10;
+insert into test.t1 values ("hndlr3", y, 2);  # Too many values
+if x then
+insert into test.t1 values ("hndlr3", y);
+end if;
+end;
+end if;
+end|
+call hndlr3(3)|
+select * from t1|
+id	data
+hndlr3	13
+delete from t1|
+drop procedure hndlr3|
+create table t3 ( id   char(16), data int )|
+drop procedure if exists hndlr4|
+create procedure hndlr4()
+begin
+declare x int default 0;
+declare val int;	                           # No default
+declare continue handler for sqlstate '02000' set x=1;
+select data into val from test.t3 where id='z' limit 1;  # No hits
+insert into test.t3 values ('z', val);
+end|
+call hndlr4()|
+select * from t3|
+id	data
+z	NULL
+drop table t3|
+drop procedure hndlr4|
+drop procedure if exists cur1|
+create procedure cur1()
+begin
+declare a char(16);
+declare b int;
+declare c double;
+declare done int default 0;
+declare c cursor for select * from test.t2;
+declare continue handler for sqlstate '02000' set done = 1;
+open c;
+repeat
+fetch c into a, b, c;
+if not done then
+insert into test.t1 values (a, b+c);
+end if;
+until done end repeat;
+close c;
+end|
+insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)|
+call cur1()|
+select * from t1|
+id	data
+foo	40
+bar	15
+zap	663
+drop procedure cur1|
+create table t3 ( s char(16), i int )|
+drop procedure if exists cur2|
+create procedure cur2()
+begin
+declare done int default 0;
+declare c1 cursor for select id,data from test.t1;
+declare c2 cursor for select i from test.t2;
+declare continue handler for sqlstate '02000' set done = 1;
+open c1;
+open c2;
+repeat
+begin
+declare a char(16);
+declare b,c int;
+fetch from c1 into a, b;
+fetch next from c2 into c;
+if not done then
+if b < c then
+insert into test.t3 values (a, b);
+else
+insert into test.t3 values (a, c);
+end if;
+end if;
+end;
+until done end repeat;
+close c1;
+close c2;
+end|
+call cur2()|
+select * from t3|
+s	i
+foo	40
+bar	3
+zap	663
+delete from t1|
+delete from t2|
+drop table t3|
+drop procedure cur2|
+drop procedure if exists chistics|
+create procedure chistics()
+language sql
+modifies sql data
+not deterministic
+sql security definer
+comment 'Characteristics procedure test'
+  insert into t1 values ("chistics", 1)|
+show create procedure chistics|
+Procedure	sql_mode	Create Procedure
+chistics		CREATE PROCEDURE `chistics`()
+    MODIFIES SQL DATA
+    COMMENT 'Characteristics procedure test'
+insert into t1 values ("chistics", 1)
+call chistics()|
+select * from t1|
+id	data
+chistics	1
+delete from t1|
+alter procedure chistics sql security invoker|
+show create procedure chistics|
+Procedure	sql_mode	Create Procedure
+chistics		CREATE PROCEDURE `chistics`()
+    MODIFIES SQL DATA
+    SQL SECURITY INVOKER
+    COMMENT 'Characteristics procedure test'
+insert into t1 values ("chistics", 1)
+drop procedure chistics|
+drop function if exists chistics|
+create function chistics() returns int
+language sql
+deterministic
+sql security invoker
+comment 'Characteristics procedure test'
+  return 42|
+show create function chistics|
+Function	sql_mode	Create Function
+chistics		CREATE FUNCTION `chistics`() RETURNS int(11)
+    DETERMINISTIC
+    SQL SECURITY INVOKER
+    COMMENT 'Characteristics procedure test'
+return 42
+select chistics()|
+chistics()
+42
+alter function chistics
+no sql
+comment 'Characteristics function test'|
+show create function chistics|
+Function	sql_mode	Create Function
+chistics		CREATE FUNCTION `chistics`() RETURNS int(11)
+    NO SQL
+    DETERMINISTIC
+    SQL SECURITY INVOKER
+    COMMENT 'Characteristics function test'
+return 42
+drop function chistics|
+insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)|
+set @@sql_mode = 'ANSI'|
+drop procedure if exists modes$
+create procedure modes(out c1 int, out c2 int)
+begin
+declare done int default 0;
+declare x int;
+declare c cursor for select data from t1;
+declare continue handler for sqlstate '02000' set done = 1;
+select 1 || 2 into c1;
+set c2 = 0;
+open c;
+repeat
+fetch c into x;
+if not done then
+set c2 = c2 + 1;
+end if;
+until done end repeat;
+close c;
+end$
+set @@sql_mode = ''|
+set sql_select_limit = 1|
+call modes(@c1, @c2)|
+set sql_select_limit = default|
+select @c1, @c2|
+@c1	@c2
+12	3
+delete from t1|
+drop procedure modes|
+create database sp_db1|
+drop database sp_db1|
+create database sp_db2|
+use sp_db2|
+create table t3 ( s char(4), t int )|
+insert into t3 values ("abcd", 42), ("dcba", 666)|
+use test|
+drop database sp_db2|
+create database sp_db3|
+use sp_db3|
+drop procedure if exists dummy|
+create procedure dummy(out x int)
+set x = 42|
+use test|
+drop database sp_db3|
+select type,db,name from mysql.proc where db = 'sp_db3'|
+type	db	name
+drop procedure if exists rc|
+create procedure rc()
+begin
+delete from t1;
+insert into t1 values ("a", 1), ("b", 2), ("c", 3);
+end|
+call rc()|
+select row_count()|
+row_count()
+3
+update t1 set data=42 where id = "b";
+select row_count()|
+row_count()
+1
+delete from t1|
+select row_count()|
+row_count()
+3
+delete from t1|
+select row_count()|
+row_count()
+0
+select * from t1|
+id	data
+select row_count()|
+row_count()
+-1
+drop procedure rc|
+drop function if exists f0|
+drop function if exists f1|
+drop function if exists f2|
+drop function if exists f3|
+drop function if exists f4|
+drop function if exists f5|
+drop function if exists f6|
+drop function if exists f7|
+drop function if exists f8|
+drop function if exists f9|
+drop function if exists f10|
+drop function if exists f11|
+drop function if exists f12_1|
+drop function if exists f12_2|
+drop view if exists v0|
+drop view if exists v1|
+drop view if exists v2|
+delete from t1|
+delete from t2|
+insert into t1 values ("a", 1), ("b", 2) |
+insert into t2 values ("a", 1, 1.0), ("b", 2, 2.0), ("c", 3, 3.0) |
+create function f1() returns int
+return (select sum(data) from t1)|
+select f1()|
+f1()
+3
+select id, f1() from t1|
+id	f1()
+a	3
+b	3
+create function f2() returns int
+return (select data from t1 where data <= (select sum(data) from t1) limit 1)|
+select f2()|
+f2()
+1
+select id, f2() from t1|
+id	f2()
+a	1
+b	1
+create function f3() returns int
+begin
+declare n int;
+declare m int;
+set n:= (select min(data) from t1);
+set m:= (select max(data) from t1);
+return n < m;
+end|
+select f3()|
+f3()
+1
+select id, f3() from t1|
+id	f3()
+a	1
+b	1
+select f1(), f3()|
+f1()	f3()
+3	1
+select id, f1(), f3() from t1|
+id	f1()	f3()
+a	3	1
+b	3	1
+create function f4() returns double 
+return (select d from t1, t2 where t1.data = t2.i and t1.id= "b")|
+select f4()|
+f4()
+2
+select s, f4() from t2|
+s	f4()
+a	2
+b	2
+c	2
+create function f5(i int) returns int
+begin
+if i <= 0 then
+return 0;
+elseif i = 1  then
+return (select count(*) from t1 where data = i);
+else
+return (select count(*) + f5( i - 1) from t1 where data = i);
+end if;
+end|
+select f5(1)|
+f5(1)
+1
+select f5(2)|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+select f5(3)|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+create function f6() returns int
+begin
+declare n int;
+set n:= f1();
+return (select count(*) from t1 where data <= f7() and data <= n);
+end|
+create function f7() returns int
+return (select sum(data) from t1 where data <= f1())|
+select f6()|
+f6()
+2
+select id, f6() from t1|
+id	f6()
+a	2
+b	2
+create view v1 (a) as select f1()|
+select * from v1|
+a
+3
+select id, a from t1, v1|
+id	a
+a	3
+b	3
+select * from v1, v1 as v|
+a	a
+3	3
+create view v2 (a) as select a*10 from v1|
+select * from v2|
+a
+30
+select id, a from t1, v2|
+id	a
+a	30
+b	30
+select * from v1, v2|
+a	a
+3	30
+create function f8 () returns int
+return (select count(*) from v2)|
+select *, f8() from v1|
+a	f8()
+3	1
+drop function f1|
+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
+create function f1() returns int
+return (select sum(data) from t1) + (select sum(data) from v1)|
+select f1()|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+select * from v1|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+select * from v2|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+drop function f1|
+create function f1() returns int
+return (select sum(data) from t1)|
+create function f0() returns int
+return (select * from (select 100) as r)|
+select f0()|
+f0()
+100
+select *, f0() from (select 1) as t|
+1	f0()
+1	100
+create view v0 as select f0()|
+select * from v0|
+f0()
+100
+select *, f0() from v0|
+f0()	f0()
+100	100
+lock tables t1 read, t1 as t11 read|
+select f3()|
+f3()
+1
+select id, f3() from t1 as t11|
+id	f3()
+a	1
+b	1
+select f0()|
+f0()
+100
+select * from v0|
+f0()
+100
+select *, f0() from v0, (select 123) as d1|
+f0()	123	f0()
+100	123	100
+select id, f3() from t1|
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+select f4()|
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+unlock tables|
+lock tables v2 read, mysql.proc read|
+select * from v2|
+a
+30
+select * from v1|
+a
+3
+select * from v1, t1|
+ERROR HY000: Table 't1' was not locked with LOCK TABLES
+select f4()|
+ERROR HY000: Table 't2' was not locked with LOCK TABLES
+unlock tables|
+create function f9() returns int
+begin
+declare a, b int;
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+set a:= (select count(*) from t3);
+set b:= (select count(*) from t3 t3_alias);
+return a + b;
+end|
+select f9()|
+f9()
+6
+Warnings:
+Note	1051	Unknown table 't3'
+select f9() from t1 limit 1|
+f9()
+6
+create function f10() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 select id from t4;
+return (select count(*) from t3);
+end|
+select f10()|
+ERROR 42S02: Table 'test.t4' doesn't exist
+create table t4 as select 1 as id|
+select f10()|
+f10()
+1
+create function f11() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+return (select count(*) from t3 as a, t3 as b);
+end|
+select f11()|
+ERROR HY000: Can't reopen table: 'a'
+select f11() from t1|
+ERROR HY000: Can't reopen table: 'a'
+create function f12_1() returns int
+begin
+drop temporary table if exists t3;
+create temporary table t3 (id int);
+insert into t3 values (1), (2), (3);
+return f12_2();
+end|
+create function f12_2() returns int
+return (select count(*) from t3)|
+drop temporary table t3|
+select f12_1()|
+ERROR 42S02: Table 'test.t3' doesn't exist
+select f12_1() from t1 limit 1|
+ERROR 42S02: Table 'test.t3' doesn't exist
+drop function f0|
+drop function f1|
+drop function f2|
+drop function f3|
+drop function f4|
+drop function f5|
+drop function f6|
+drop function f7|
+drop function f8|
+drop function f9|
+drop function f10|
+drop function f11|
+drop function f12_1|
+drop function f12_2|
+drop view v0|
+drop view v1|
+drop view v2|
+delete from t1 |
+delete from t2 |
+drop table t4|
+drop table if exists t3|
+create table t3 (n int unsigned not null primary key, f bigint unsigned)|
+drop procedure if exists ifac|
+create procedure ifac(n int unsigned)
+begin
+declare i int unsigned default 1;
+if n > 20 then
+set n = 20;		# bigint overflow otherwise
+end if;
+while i <= n do
+begin
+insert into test.t3 values (i, fac(i));
+set i = i + 1;
+end;
+end while;
+end|
+call ifac(20)|
+select * from t3|
+n	f
+1	1
+2	2
+3	6
+4	24
+5	120
+6	720
+7	5040
+8	40320
+9	362880
+10	3628800
+11	39916800
+12	479001600
+13	6227020800
+14	87178291200
+15	1307674368000
+16	20922789888000
+17	355687428096000
+18	6402373705728000
+19	121645100408832000
+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	
+drop procedure ifac|
+drop function fac|
+show function status like '%f%'|
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+drop table if exists t3|
+create table t3 (
+i int unsigned not null primary key,
+p bigint unsigned not null
+)|
+insert into t3 values
+( 0,   3), ( 1,   5), ( 2,   7), ( 3,  11), ( 4,  13),
+( 5,  17), ( 6,  19), ( 7,  23), ( 8,  29), ( 9,  31),
+(10,  37), (11,  41), (12,  43), (13,  47), (14,  53),
+(15,  59), (16,  61), (17,  67), (18,  71), (19,  73),
+(20,  79), (21,  83), (22,  89), (23,  97), (24, 101),
+(25, 103), (26, 107), (27, 109), (28, 113), (29, 127),
+(30, 131), (31, 137), (32, 139), (33, 149), (34, 151),
+(35, 157), (36, 163), (37, 167), (38, 173), (39, 179),
+(40, 181), (41, 191), (42, 193), (43, 197), (44, 199)|
+drop procedure if exists opp|
+create procedure opp(n bigint unsigned, out pp bool)
+begin
+declare r double;
+declare b, s bigint unsigned default 0;
+set r = sqrt(n);
+again:
+loop
+if s = 45 then
+set b = b+200, s = 0;
+else
+begin
+declare p bigint unsigned;
+select t.p into p from test.t3 t where t.i = s;
+if b+p > r then
+set pp = 1;
+leave again;
+end if;
+if mod(n, b+p) = 0 then
+set pp = 0;
+leave again;
+end if;
+set s = s+1;
+end;
+end if;
+end loop;
+end|
+drop procedure if exists ip|
+create procedure ip(m int unsigned)
+begin
+declare p bigint unsigned;
+declare i int unsigned;
+set i=45, p=201;
+while i < m do
+begin
+declare pp bool default 0;
+call opp(p, pp);
+if pp then
+insert into test.t3 values (i, p);
+set i = i+1;
+end if;
+set p = p+2;
+end;
+end while;
+end|
+show create procedure opp|
+Procedure	sql_mode	Create Procedure
+opp		CREATE PROCEDURE `opp`(n bigint unsigned, out pp bool)
+begin
+declare r double;
+declare b, s bigint unsigned default 0;
+set r = sqrt(n);
+again:
+loop
+if s = 45 then
+set b = b+200, s = 0;
+else
+begin
+declare p bigint unsigned;
+select t.p into p from test.t3 t where t.i = s;
+if b+p > r then
+set pp = 1;
+leave again;
+end if;
+if mod(n, b+p) = 0 then
+set pp = 0;
+leave again;
+end if;
+set s = s+1;
+end;
+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	
+call ip(200)|
+select * from t3 where i=45 or i=100 or i=199|
+i	p
+45	211
+100	557
+199	1229
+drop table t3|
+drop procedure opp|
+drop procedure ip|
+show procedure status like '%p%'|
+Db	Name	Type	Definer	Modified	Created	Security_type	Comment
+drop table if exists t3|
+create table t3 ( f bigint unsigned not null )|
+drop procedure if exists fib|
+create procedure fib(n int unsigned)
+begin
+if n > 1 then
+begin
+declare x, y bigint unsigned;
+declare c cursor for select f from t3 order by f desc limit 2;
+open c;
+fetch c into y;
+fetch c into x;
+close c;
+insert into t3 values (x+y);
+call fib(n-1);
+end;
+end if;
+end|
+set @@max_sp_recursion_depth= 20|
+insert into t3 values (0), (1)|
+call fib(3)|
+select * from t3 order by f asc|
+f
+0
+1
+1
+2
+delete from t3|
+insert into t3 values (0), (1)|
+call fib(10)|
+select * from t3 order by f asc|
+f
+0
+1
+1
+2
+3
+5
+8
+13
+21
+34
+55
+drop table t3|
+drop procedure fib|
+set @@max_sp_recursion_depth= 0|
+drop procedure if exists bar|
+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
+alter procedure bar comment "2222222222" sql security definer|
+alter procedure bar comment "3333333333"|
+alter procedure bar|
+show create procedure bar|
+Procedure	sql_mode	Create Procedure
+bar		CREATE PROCEDURE `bar`(x char(16), y int)
+    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
+drop procedure bar|
+drop procedure if exists p1|
+create procedure p1 ()
+select (select s1 from t3) from t3|
+create table t3 (s1 int)|
+call p1()|
+(select s1 from t3)
+insert into t3 values (1)|
+call p1()|
+(select s1 from t3)
+1
+drop procedure p1|
+drop table t3|
+drop function if exists foo|
+create function `foo` () returns int
+return 5|
+select `foo` ()|
+`foo` ()
+5
+drop function `foo`|
+drop function if exists t1max|
+create function t1max() returns int
+begin
+declare x int;
+select max(data) into x from t1;
+return x;
+end|
+insert into t1 values ("foo", 3), ("bar", 2), ("zip", 5), ("zap", 1)|
+select t1max()|
+t1max()
+5
+drop function t1max|
+create table t3 (
+v char(16) not null primary key,
+c int unsigned not null
+)|
+create function getcount(s char(16)) returns int
+begin
+declare x int;
+select count(*) into x from t3 where v = s;
+if x = 0 then
+insert into t3 values (s, 1);
+else
+update t3 set c = c+1 where v = s;
+end if;
+return x;
+end|
+select * from t1 where data = getcount("bar")|
+id	data
+zap	1
+select * from t3|
+v	c
+bar	4
+select getcount("zip")|
+getcount("zip")
+0
+select getcount("zip")|
+getcount("zip")
+1
+select * from t3|
+v	c
+bar	4
+zip	2
+select getcount(id) from t1 where data = 3|
+getcount(id)
+0
+select getcount(id) from t1 where data = 5|
+getcount(id)
+1
+select * from t3|
+v	c
+bar	4
+zip	3
+foo	1
+drop table t3|
+drop function getcount|
+drop table if exists t3|
+drop procedure if exists h_ee|
+drop procedure if exists h_es|
+drop procedure if exists h_en|
+drop procedure if exists h_ew|
+drop procedure if exists h_ex|
+drop procedure if exists h_se|
+drop procedure if exists h_ss|
+drop procedure if exists h_sn|
+drop procedure if exists h_sw|
+drop procedure if exists h_sx|
+drop procedure if exists h_ne|
+drop procedure if exists h_ns|
+drop procedure if exists h_nn|
+drop procedure if exists h_we|
+drop procedure if exists h_ws|
+drop procedure if exists h_ww|
+drop procedure if exists h_xe|
+drop procedure if exists h_xs|
+drop procedure if exists h_xx|
+create table t3 (a smallint primary key)|
+insert into t3 (a) values (1)|
+create procedure h_ee()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (bad)' as 'h_ee';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_ee';
+insert into t3 values (1);
+end;
+end|
+create procedure h_es()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (good)' as 'h_es';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000'
+      select 'Inner (bad)' as 'h_es';
+insert into t3 values (1);
+end;
+end|
+create procedure h_en()
+deterministic
+begin
+declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+select 'Outer (good)' as 'h_en';
+begin
+declare x int;
+declare continue handler for sqlstate '02000' -- no data
+select 'Inner (bad)' as 'h_en';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_ew()
+deterministic
+begin
+declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+select 'Outer (good)' as 'h_ew';
+begin
+declare continue handler for sqlwarning
+select 'Inner (bad)' as 'h_ew';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ex()
+deterministic
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Outer (good)' as 'h_ex';
+begin
+declare continue handler for sqlexception
+select 'Inner (bad)' as 'h_ex';
+insert into t3 values (1);
+end;
+end|
+create procedure h_se()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (bad)' as 'h_se';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_se';
+insert into t3 values (1);
+end;
+end|
+create procedure h_ss()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (bad)' as 'h_ss';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Inner (good)' as 'h_ss';
+insert into t3 values (1);
+end;
+end|
+create procedure h_sn()
+deterministic
+begin
+-- Note: '02000' is more specific than NOT FOUND ;
+--       there might be other not found states 
+declare continue handler for sqlstate '02000' -- no data
+select 'Outer (good)' as 'h_sn';
+begin
+declare x int;
+declare continue handler for not found
+select 'Inner (bad)' as 'h_sn';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_sw()
+deterministic
+begin
+-- data exception - numeric value out of range
+declare continue handler for sqlstate '22003'
+    select 'Outer (good)' as 'h_sw';
+begin
+declare continue handler for sqlwarning
+select 'Inner (bad)' as 'h_sw';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_sx()
+deterministic
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000' 
+select 'Outer (good)' as 'h_sx';
+begin
+declare continue handler for sqlexception
+select 'Inner (bad)' as 'h_sx';
+insert into t3 values (1);
+end;
+end|
+create procedure h_ne()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_ne';
+begin
+declare x int;
+declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+select 'Inner (good)' as 'h_ne';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_ns()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_ns';
+begin
+declare x int;
+declare continue handler for sqlstate '02000' -- no data
+select 'Inner (good)' as 'h_ns';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_nn()
+deterministic
+begin
+declare continue handler for not found
+select 'Outer (bad)' as 'h_nn';
+begin
+declare x int;
+declare continue handler for not found
+select 'Inner (good)' as 'h_nn';
+select a into x from t3 where a = 42;
+end;
+end|
+create procedure h_we()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_we';
+begin
+declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+select 'Inner (good)' as 'h_we';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ws()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_ws';
+begin
+-- data exception - numeric value out of range
+declare continue handler for sqlstate '22003'
+      select 'Inner (good)' as 'h_ws';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_ww()
+deterministic
+begin
+declare continue handler for sqlwarning
+select 'Outer (bad)' as 'h_ww';
+begin
+declare continue handler for sqlwarning
+select 'Inner (good)' as 'h_ww';
+insert into t3 values (123456789012);
+end;
+delete from t3;
+insert into t3 values (1);
+end|
+create procedure h_xe()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xe';
+begin
+declare continue handler for 1062 -- ER_DUP_ENTRY
+select 'Inner (good)' as 'h_xe';
+insert into t3 values (1);
+end;
+end|
+create procedure h_xs()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xs';
+begin
+-- integrity constraint violation
+declare continue handler for sqlstate '23000'
+      select 'Inner (good)' as 'h_xs';
+insert into t3 values (1);
+end;
+end|
+create procedure h_xx()
+deterministic
+begin
+declare continue handler for sqlexception
+select 'Outer (bad)' as 'h_xx';
+begin
+declare continue handler for sqlexception
+select 'Inner (good)' as 'h_xx';
+insert into t3 values (1);
+end;
+end|
+call h_ee()|
+h_ee
+Inner (good)
+call h_es()|
+h_es
+Outer (good)
+call h_en()|
+h_en
+Outer (good)
+call h_ew()|
+h_ew
+Outer (good)
+call h_ex()|
+h_ex
+Outer (good)
+call h_se()|
+h_se
+Inner (good)
+call h_ss()|
+h_ss
+Inner (good)
+call h_sn()|
+h_sn
+Outer (good)
+call h_sw()|
+h_sw
+Outer (good)
+call h_sx()|
+h_sx
+Outer (good)
+call h_ne()|
+h_ne
+Inner (good)
+call h_ns()|
+h_ns
+Inner (good)
+call h_nn()|
+h_nn
+Inner (good)
+call h_we()|
+h_we
+Inner (good)
+call h_ws()|
+h_ws
+Inner (good)
+call h_ww()|
+h_ww
+Inner (good)
+call h_xe()|
+h_xe
+Inner (good)
+call h_xs()|
+h_xs
+Inner (good)
+call h_xx()|
+h_xx
+Inner (good)
+drop table t3|
+drop procedure h_ee|
+drop procedure h_es|
+drop procedure h_en|
+drop procedure h_ew|
+drop procedure h_ex|
+drop procedure h_se|
+drop procedure h_ss|
+drop procedure h_sn|
+drop procedure h_sw|
+drop procedure h_sx|
+drop procedure h_ne|
+drop procedure h_ns|
+drop procedure h_nn|
+drop procedure h_we|
+drop procedure h_ws|
+drop procedure h_ww|
+drop procedure h_xe|
+drop procedure h_xs|
+drop procedure h_xx|
+drop procedure if exists bug822|
+create procedure bug822(a_id char(16), a_data int)
+begin
+declare n int;
+select count(*) into n from t1 where id = a_id and data = a_data;
+if n = 0 then
+insert into t1 (id, data) values (a_id, a_data);
+end if;
+end|
+delete from t1|
+call bug822('foo', 42)|
+call bug822('foo', 42)|
+call bug822('bar', 666)|
+select * from t1|
+id	data
+foo	42
+bar	666
+delete from t1|
+drop procedure bug822|
+drop procedure if exists bug1495|
+create procedure bug1495()
+begin
+declare x int;
+select data into x from t1 order by id limit 1;
+if x > 10 then
+insert into t1 values ("less", x-10);
+else
+insert into t1 values ("more", x+10);
+end if;
+end|
+insert into t1 values ('foo', 12)|
+call bug1495()|
+delete from t1 where id='foo'|
+insert into t1 values ('bar', 7)|
+call bug1495()|
+delete from t1 where id='bar'|
+select * from t1|
+id	data
+less	2
+more	17
+delete from t1|
+drop procedure bug1495|
+drop procedure if exists bug1547|
+create procedure bug1547(s char(16))
+begin
+declare x int;
+select data into x from t1 where s = id limit 1;
+if x > 10 then
+insert into t1 values ("less", x-10);
+else
+insert into t1 values ("more", x+10);
+end if;
+end|
+insert into t1 values ("foo", 12), ("bar", 7)|
+call bug1547("foo")|
+call bug1547("bar")|
+select * from t1|
+id	data
+foo	12
+bar	7
+less	2
+more	17
+delete from t1|
+drop procedure bug1547|
+drop table if exists t70|
+create table t70 (s1 int,s2 int)|
+insert into t70 values (1,2)|
+drop procedure if exists bug1656|
+create procedure bug1656(out p1 int, out p2 int)
+select * into p1, p1 from t70|
+call bug1656(@1, @2)|
+select @1, @2|
+@1	@2
+2	NULL
+drop table t70|
+drop procedure bug1656|
+create table t3(a int)|
+drop procedure if exists bug1862|
+create procedure bug1862()
+begin
+insert into t3 values(2);    
+flush tables;
+end|
+call bug1862()|
+call bug1862()|
+select * from t3|
+a
+2
+2
+drop table t3|
+drop procedure bug1862|
+drop procedure if exists bug1874|
+create procedure bug1874()
+begin
+declare x int;
+declare y double;
+select max(data) into x from t1;
+insert into t2 values ("max", x, 0);
+select min(data) into x from t1;
+insert into t2 values ("min", x, 0);
+select sum(data) into x from t1;
+insert into t2 values ("sum", x, 0);
+select avg(data) into y from t1;
+insert into t2 values ("avg", 0, y);
+end|
+insert into t1 (data) values (3), (1), (5), (9), (4)|
+call bug1874()|
+select * from t2|
+s	i	d
+max	9	0
+min	1	0
+sum	22	0
+avg	0	4.4
+delete from t1|
+delete from t2|
+drop procedure bug1874|
+drop procedure if exists bug2260|
+create procedure bug2260()
+begin
+declare v1 int;
+declare c1 cursor for select data from t1;
+declare continue handler for not found set @x2 = 1;
+open c1;
+fetch c1 into v1;
+set @x2 = 2;
+close c1;
+end|
+call bug2260()|
+select @x2|
+@x2
+2
+drop procedure bug2260|
+drop procedure if exists bug2267_1|
+create procedure bug2267_1()
+begin
+show procedure status;
+end|
+drop procedure if exists bug2267_2|
+create procedure bug2267_2()
+begin
+show function status;
+end|
+drop procedure if exists bug2267_3|
+create procedure bug2267_3()
+begin
+show create procedure bug2267_1;
+end|
+drop procedure if exists bug2267_4|
+drop function if exists bug2267_4|
+create procedure bug2267_4()
+begin
+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	
+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	
+call bug2267_3()|
+Procedure	sql_mode	Create Procedure
+bug2267_1		CREATE PROCEDURE `bug2267_1`()
+begin
+show procedure status;
+end
+call bug2267_4()|
+Function	sql_mode	Create Function
+bug2267_4		CREATE FUNCTION `bug2267_4`() RETURNS int(11)
+return 100
+drop procedure bug2267_1|
+drop procedure bug2267_2|
+drop procedure bug2267_3|
+drop procedure bug2267_4|
+drop function bug2267_4|
+drop procedure if exists bug2227|
+create procedure bug2227(x int)
+begin
+declare y float default 2.6;
+declare z char(16) default "zzz";
+select 1.3, x, y, 42, z;
+end|
+call bug2227(9)|
+1.3	x	y	42	z
+1.3	9	2.6	42	zzz
+drop procedure bug2227|
+drop procedure if exists bug2614|
+create procedure bug2614()
+begin
+drop table if exists t3;
+create table t3 (id int default '0' not null);
+insert into t3 select 12;
+insert into t3 select * from t3;
+end|
+call bug2614()|
+call bug2614()|
+drop table t3|
+drop procedure bug2614|
+drop function if exists bug2674|
+create function bug2674() returns int
+return @@sort_buffer_size|
+set @osbs = @@sort_buffer_size|
+set @@sort_buffer_size = 262000|
+select bug2674()|
+bug2674()
+262000
+drop function bug2674|
+set @@sort_buffer_size = @osbs|
+drop procedure if exists bug3259_1 |
+create procedure bug3259_1 () begin end|
+drop procedure if exists BUG3259_2 |
+create procedure BUG3259_2 () begin end|
+drop procedure if exists Bug3259_3 |
+create procedure Bug3259_3 () begin end|
+call BUG3259_1()|
+call BUG3259_1()|
+call bug3259_2()|
+call Bug3259_2()|
+call bug3259_3()|
+call bUG3259_3()|
+drop procedure bUg3259_1|
+drop procedure BuG3259_2|
+drop procedure BUG3259_3|
+drop function if exists bug2772|
+create function bug2772() returns char(10) character set latin2
+return 'a'|
+select bug2772()|
+bug2772()
+a
+drop function bug2772|
+drop procedure if exists bug2776_1|
+create procedure bug2776_1(out x int)
+begin
+declare v int;
+set v = default;
+set x = v;
+end|
+drop procedure if exists bug2776_2|
+create procedure bug2776_2(out x int)
+begin
+declare v int default 42;
+set v = default;
+set x = v;
+end|
+set @x = 1|
+call bug2776_1(@x)|
+select @x|
+@x
+NULL
+call bug2776_2(@x)|
+select @x|
+@x
+42
+drop procedure bug2776_1|
+drop procedure bug2776_2|
+create table t3 (s1 smallint)|
+insert into t3 values (123456789012)|
+Warnings:
+Warning	1264	Out of range value adjusted for column 's1' at row 1
+drop procedure if exists bug2780|
+create procedure bug2780()
+begin
+declare exit handler for sqlwarning set @x = 1; 
+set @x = 0;
+insert into t3 values (123456789012);
+insert into t3 values (0);
+end|
+call bug2780()|
+select @x|
+@x
+1
+select * from t3|
+s1
+32767
+32767
+drop procedure bug2780|
+drop table t3|
+create table t3 (content varchar(10) )|
+insert into t3 values ("test1")|
+insert into t3 values ("test2")|
+create table t4 (f1 int, rc int, t3 int)|
+drop procedure if exists bug1863|
+create procedure bug1863(in1 int)
+begin 
+declare ind int default 0;
+declare t1 int;
+declare t2 int;
+declare t3 int;
+declare rc int default 0;
+declare continue handler for 1065 set rc = 1;
+drop temporary table if exists temp_t1;
+create temporary table temp_t1 (
+f1 int auto_increment, f2 varchar(20), primary key (f1)
+);
+insert into temp_t1 (f2) select content from t3;
+select f2 into t3 from temp_t1 where f1 = 10;
+if (rc) then
+insert into t4 values (1, rc, t3);
+end if;
+insert into t4 values (2, rc, t3);
+end|
+call bug1863(10)|
+Warnings:
+Note	1051	Unknown table 'temp_t1'
+Warning	1329	No data - zero rows fetched, selected, or processed
+call bug1863(10)|
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+select * from t4|
+f1	rc	t3
+2	0	NULL
+2	0	NULL
+drop procedure bug1863|
+drop temporary table temp_t1;
+drop table t3, t4|
+create table t3 ( 
+OrderID  int not null,
+MarketID int,
+primary key (OrderID)
+)|
+create table t4 ( 
+MarketID int not null,
+Market varchar(60),
+Status char(1),
+primary key (MarketID)
+)|
+insert t3 (OrderID,MarketID) values (1,1)|
+insert t3 (OrderID,MarketID) values (2,2)|
+insert t4 (MarketID,Market,Status) values (1,"MarketID One","A")|
+insert t4 (MarketID,Market,Status) values (2,"MarketID Two","A")|
+drop procedure if exists bug2656_1|
+create procedure bug2656_1()
+begin 
+select
+m.Market
+from  t4 m JOIN t3 o 
+ON o.MarketID != 1 and o.MarketID = m.MarketID;
+end |
+drop procedure if exists bug2656_2|
+create procedure bug2656_2()
+begin 
+select
+m.Market
+from  
+t4 m, t3 o
+where       
+m.MarketID != 1 and m.MarketID = o.MarketID;
+end |
+call bug2656_1()|
+Market
+MarketID Two
+call bug2656_1()|
+Market
+MarketID Two
+call bug2656_2()|
+Market
+MarketID Two
+call bug2656_2()|
+Market
+MarketID Two
+drop procedure bug2656_1|
+drop procedure bug2656_2|
+drop table t3, t4|
+drop procedure if exists bug3426|
+create procedure bug3426(in_time int unsigned, out x int)
+begin
+if in_time is null then
+set @stamped_time=10;
+set x=1;
+else
+set @stamped_time=in_time;
+set x=2;
+end if;
+end|
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+@i	time
+2	01-01-1970 03:16:40
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+@i	time
+1	01-01-1970 03:00:10
+alter procedure bug3426 sql security invoker|
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+@i	time
+1	01-01-1970 03:00:10
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+@i	time
+2	01-01-1970 03:16:40
+drop procedure bug3426|
+create table t3 (
+a int primary key, 
+ach char(1)
+) engine = innodb|
+create table t4 (
+b int  primary key , 
+bch char(1)
+) engine = innodb|
+insert into t3 values (1 , 'aCh1' ) , ('2' , 'aCh2')|
+Warnings:
+Warning	1265	Data truncated for column 'ach' at row 1
+Warning	1265	Data truncated for column 'ach' at row 2
+insert into t4 values (1 , 'bCh1' )|
+Warnings:
+Warning	1265	Data truncated for column 'bch' at row 1
+drop procedure if exists bug3448|
+create procedure bug3448()
+select * from t3 inner join t4 on t3.a = t4.b|
+select * from t3 inner join t4 on t3.a = t4.b|
+a	ach	b	bch
+1	a	1	b
+call bug3448()|
+a	ach	b	bch
+1	a	1	b
+call bug3448()|
+a	ach	b	bch
+1	a	1	b
+drop procedure bug3448|
+drop table t3, t4|
+create table t3 (
+id int unsigned auto_increment not null primary key,
+title VARCHAR(200),
+body text,
+fulltext (title,body)
+)|
+insert into t3 (title,body) values
+('MySQL Tutorial','DBMS stands for DataBase ...'),
+('How To Use MySQL Well','After you went through a ...'),
+('Optimizing MySQL','In this tutorial we will show ...'),
+('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+('MySQL vs. YourSQL','In the following database comparison ...'),
+('MySQL Security','When configured properly, MySQL ...')|
+drop procedure if exists bug3734 |
+create procedure bug3734 (param1 varchar(100))
+select * from t3 where match (title,body) against (param1)|
+call bug3734('database')|
+id	title	body
+5	MySQL vs. YourSQL	In the following database comparison ...
+1	MySQL Tutorial	DBMS stands for DataBase ...
+call bug3734('Security')|
+id	title	body
+6	MySQL Security	When configured properly, MySQL ...
+drop procedure bug3734|
+drop table t3|
+drop procedure if exists bug3863|
+create procedure bug3863()
+begin
+set @a = 0;
+while @a < 5 do
+set @a = @a + 1;
+end while;
+end|
+call bug3863()|
+select @a|
+@a
+5
+call bug3863()|
+select @a|
+@a
+5
+drop procedure bug3863|
+create table t3 (
+id int(10) unsigned not null default 0,
+rid int(10) unsigned not null default 0,
+msg text not null,
+primary key (id),
+unique key rid (rid, id)
+)|
+drop procedure if exists bug2460_1|
+create procedure bug2460_1(in v int)
+begin
+( select n0.id from t3 as n0 where n0.id = v )
+union
+( select n0.id from t3 as n0, t3 as n1
+where n0.id = n1.rid and n1.id = v )
+union
+( select n0.id from t3 as n0, t3 as n1, t3 as n2
+where n0.id = n1.rid and n1.id = n2.rid and n2.id = v );
+end|
+call bug2460_1(2)|
+id
+call bug2460_1(2)|
+id
+insert into t3 values (1, 1, 'foo'), (2, 1, 'bar'), (3, 1, 'zip zap')|
+call bug2460_1(2)|
+id
+2
+1
+call bug2460_1(2)|
+id
+2
+1
+drop procedure if exists bug2460_2|
+create procedure bug2460_2()
+begin
+drop table if exists t3;
+create temporary table t3 (s1 int);
+insert into t3 select 1 union select 1;
+end|
+call bug2460_2()|
+call bug2460_2()|
+select * from t3|
+s1
+1
+drop procedure bug2460_1|
+drop procedure bug2460_2|
+drop table t3|
+set @@sql_mode = ''|
+drop procedure if exists bug2564_1|
+create procedure bug2564_1()
+comment 'Joe''s procedure'
+  insert into `t1` values ("foo", 1)|
+set @@sql_mode = 'ANSI_QUOTES'|
+drop procedure if exists bug2564_2|
+create procedure bug2564_2()
+insert into "t1" values ('foo', 1)|
+set @@sql_mode = ''$
+drop function if exists bug2564_3$
+create function bug2564_3(x int, y int) returns int
+return x || y$
+set @@sql_mode = 'ANSI'$
+drop function if exists bug2564_4$
+create function bug2564_4(x int, y int) returns int
+return x || y$
+set @@sql_mode = ''|
+show create procedure bug2564_1|
+Procedure	sql_mode	Create Procedure
+bug2564_1		CREATE PROCEDURE `bug2564_1`()
+    COMMENT 'Joe''s procedure'
+insert into `t1` values ("foo", 1)
+show create procedure bug2564_2|
+Procedure	sql_mode	Create Procedure
+bug2564_2	ANSI_QUOTES	CREATE PROCEDURE "bug2564_2"()
+insert into "t1" values ('foo', 1)
+show create function bug2564_3|
+Function	sql_mode	Create Function
+bug2564_3		CREATE FUNCTION `bug2564_3`(x int, y int) RETURNS int(11)
+return x || y
+show create function bug2564_4|
+Function	sql_mode	Create Function
+bug2564_4	REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI	CREATE FUNCTION "bug2564_4"(x int, y int) RETURNS int(11)
+return x || y
+drop procedure bug2564_1|
+drop procedure bug2564_2|
+drop function bug2564_3|
+drop function bug2564_4|
+drop function if exists bug3132|
+create function bug3132(s char(20)) returns char(50)
+return concat('Hello, ', s, '!')|
+select bug3132('Bob') union all select bug3132('Judy')|
+bug3132('Bob')
+Hello, Bob!
+Hello, Judy!
+drop function bug3132|
+drop procedure if exists bug3843|
+create procedure bug3843()
+analyze table t1|
+call bug3843()|
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	OK
+call bug3843()|
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+select 1+2|
+1+2
+3
+drop procedure bug3843|
+create table t3 ( s1 char(10) )|
+insert into t3 values ('a'), ('b')|
+drop procedure if exists bug3368|
+create procedure bug3368(v char(10))
+begin
+select group_concat(v) from t3;
+end|
+call bug3368('x')|
+group_concat(v)
+x,x
+call bug3368('yz')|
+group_concat(v)
+yz,yz
+drop procedure bug3368|
+drop table t3|
+create table t3 (f1 int, f2 int)|
+insert into t3 values (1,1)|
+drop procedure if exists bug4579_1|
+create procedure bug4579_1 ()
+begin
+declare sf1 int;
+select f1 into sf1 from t3 where f1=1 and f2=1;
+update t3 set f2 = f2 + 1 where f1=1 and f2=1;
+call bug4579_2();
+end|
+drop procedure if exists bug4579_2|
+create procedure bug4579_2 ()
+begin
+end|
+call bug4579_1()|
+call bug4579_1()|
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+call bug4579_1()|
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+drop procedure bug4579_1|
+drop procedure bug4579_2|
+drop table t3|
+drop procedure if exists bug2773|
+create function bug2773() returns int return null|
+create table t3 as select bug2773()|
+show create table t3|
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `bug2773()` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t3|
+drop function bug2773|
+drop procedure if exists bug3788|
+create function bug3788() returns date return cast("2005-03-04" as date)|
+select bug3788()|
+bug3788()
+2005-03-04
+drop function bug3788|
+create function bug3788() returns binary(1) return 5|
+select bug3788()|
+bug3788()
+5
+drop function bug3788|
+create table t3 (f1 int, f2 int, f3 int)|
+insert into t3 values (1,1,1)|
+drop procedure if exists bug4726|
+create procedure bug4726()
+begin
+declare tmp_o_id INT;
+declare tmp_d_id INT default 1;
+while tmp_d_id <= 2 do
+begin
+select f1 into tmp_o_id from t3 where f2=1 and f3=1;
+set tmp_d_id = tmp_d_id + 1;
+end;
+end while;
+end|
+call bug4726()|
+call bug4726()|
+call bug4726()|
+drop procedure bug4726|
+drop table t3|
+drop procedure if exists bug4902|
+create procedure bug4902()
+begin
+show charset like 'foo';
+show collation like 'foo';
+show column types;
+show create table t1;
+show create database test;
+show databases like 'foo';
+show errors;
+show columns from t1;
+show grants for 'root'@'localhost';
+show keys from t1;
+show open tables like 'foo';
+show privileges;
+show status like 'foo';
+show tables like 'foo';
+show variables like 'foo';
+show warnings;
+end|
+call bug4902()|
+Charset	Description	Default collation	Maxlen
+Collation	Charset	Id	Default	Compiled	Sortlen
+Type	Size	Min_Value	Max_Value	Prec	Scale	Nullable	Auto_Increment	Unsigned	Zerofill	Searchable	Case_Sensitive	Default	Comment
+tinyint	1	-128	127	0	0	YES	YES	NO	YES	YES	NO	NULL,0	A very small integer
+tinyint unsigned	1	0	255	0	0	YES	YES	YES	YES	YES	NO	NULL,0	A very small integer
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` char(16) NOT NULL default '',
+  `data` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Database	Create Database
+test	CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
+Database (foo)
+Level	Code	Message
+Field	Type	Null	Key	Default	Extra
+id	char(16)	NO			
+data	int(11)	NO			
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
+Database	Table	In_use	Name_locked
+Privilege	Context	Comment
+Alter	Tables	To alter the table
+Alter routine	Functions,Procedures	To alter or drop stored functions/procedures
+Create	Databases,Tables,Indexes	To create new databases and tables
+Create routine	Functions,Procedures	To use CREATE FUNCTION/PROCEDURE
+Create temporary tables	Databases	To use CREATE TEMPORARY TABLE
+Create view	Tables	To create new views
+Create user	Server Admin	To create new users
+Delete	Tables	To delete existing rows
+Drop	Databases,Tables	To drop databases, tables, and views
+Execute	Functions,Procedures	To execute stored routines
+File	File access on server	To read and write files on the server
+Grant option	Databases,Tables,Functions,Procedures	To give to other users those privileges you possess
+Index	Tables	To create or drop indexes
+Insert	Tables	To insert data into tables
+Lock tables	Databases	To use LOCK TABLES (together with SELECT privilege)
+Process	Server Admin	To view the plain text of currently executing queries
+References	Databases,Tables	To have references on tables
+Reload	Server Admin	To reload or refresh tables, logs and privileges
+Replication client	Server Admin	To ask where the slave or master servers are
+Replication slave	Server Admin	To read binary log events from the master
+Select	Tables	To retrieve rows from table
+Show databases	Server Admin	To see all databases with SHOW DATABASES
+Show view	Tables	To see views with SHOW CREATE VIEW
+Shutdown	Server Admin	To shut down the server
+Super	Server Admin	To use KILL thread, SET GLOBAL, CHANGE MASTER, etc.
+Update	Tables	To update existing rows
+Usage	Server Admin	No privileges - allow connect only
+Variable_name	Value
+Tables_in_test (foo)
+Variable_name	Value
+Level	Code	Message
+call bug4902()|
+Charset	Description	Default collation	Maxlen
+Collation	Charset	Id	Default	Compiled	Sortlen
+Type	Size	Min_Value	Max_Value	Prec	Scale	Nullable	Auto_Increment	Unsigned	Zerofill	Searchable	Case_Sensitive	Default	Comment
+tinyint	1	-128	127	0	0	YES	YES	NO	YES	YES	NO	NULL,0	A very small integer
+tinyint unsigned	1	0	255	0	0	YES	YES	YES	YES	YES	NO	NULL,0	A very small integer
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `id` char(16) NOT NULL default '',
+  `data` int(11) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Database	Create Database
+test	CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET latin1 */
+Database (foo)
+Level	Code	Message
+Field	Type	Null	Key	Default	Extra
+id	char(16)	NO			
+data	int(11)	NO			
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+Table	Non_unique	Key_name	Seq_in_index	Column_name	Collation	Cardinality	Sub_part	Packed	Null	Index_type	Comment
+Database	Table	In_use	Name_locked
+Privilege	Context	Comment
+Alter	Tables	To alter the table
+Alter routine	Functions,Procedures	To alter or drop stored functions/procedures
+Create	Databases,Tables,Indexes	To create new databases and tables
+Create routine	Functions,Procedures	To use CREATE FUNCTION/PROCEDURE
+Create temporary tables	Databases	To use CREATE TEMPORARY TABLE
+Create view	Tables	To create new views
+Create user	Server Admin	To create new users
+Delete	Tables	To delete existing rows
+Drop	Databases,Tables	To drop databases, tables, and views
+Execute	Functions,Procedures	To execute stored routines
+File	File access on server	To read and write files on the server
+Grant option	Databases,Tables,Functions,Procedures	To give to other users those privileges you possess
+Index	Tables	To create or drop indexes
+Insert	Tables	To insert data into tables
+Lock tables	Databases	To use LOCK TABLES (together with SELECT privilege)
+Process	Server Admin	To view the plain text of currently executing queries
+References	Databases,Tables	To have references on tables
+Reload	Server Admin	To reload or refresh tables, logs and privileges
+Replication client	Server Admin	To ask where the slave or master servers are
+Replication slave	Server Admin	To read binary log events from the master
+Select	Tables	To retrieve rows from table
+Show databases	Server Admin	To see all databases with SHOW DATABASES
+Show view	Tables	To see views with SHOW CREATE VIEW
+Shutdown	Server Admin	To shut down the server
+Super	Server Admin	To use KILL thread, SET GLOBAL, CHANGE MASTER, etc.
+Update	Tables	To update existing rows
+Usage	Server Admin	No privileges - allow connect only
+Variable_name	Value
+Tables_in_test (foo)
+Variable_name	Value
+Level	Code	Message
+drop procedure bug4902|
+drop procedure if exists bug4902_2|
+create procedure bug4902_2()
+begin
+show processlist;
+end|
+call bug4902_2()|
+Id	User	Host	db	Command	Time	State	Info
+#	root	localhost	test	Query	#	NULL	show processlist
+call bug4902_2()|
+Id	User	Host	db	Command	Time	State	Info
+#	root	localhost	test	Query	#	NULL	show processlist
+drop procedure bug4902_2|
+drop procedure if exists bug4904|
+create procedure bug4904()
+begin
+declare continue handler for sqlstate 'HY000' begin end;
+create table t2 as select * from t3;
+end|
+call bug4904()|
+ERROR 42S02: Table 'test.t3' doesn't exist
+drop procedure bug4904|
+create table t3 (s1 char character set latin1, s2 char character set latin2)|
+drop procedure if exists bug4904|
+create procedure bug4904 ()
+begin
+declare continue handler for sqlstate 'HY000' begin end;
+select s1 from t3 union select s2 from t3; 
+end|
+call bug4904()|
+drop procedure bug4904|
+drop table t3|
+drop procedure if exists bug336|
+create procedure bug336(out y int)
+begin
+declare x int;
+set x = (select sum(t.data) from test.t1 t);
+set y = x;
+end|
+insert into t1 values ("a", 2), ("b", 3)|
+call bug336(@y)|
+select @y|
+@y
+5
+delete from t1|
+drop procedure bug336|
+drop procedure if exists bug3157|
+create procedure bug3157()
+begin
+if exists(select * from t1) then
+set @n= @n + 1;
+end if;
+if (select count(*) from t1) then
+set @n= @n + 1;
+end if;
+end|
+set @n = 0|
+insert into t1 values ("a", 1)|
+call bug3157()|
+select @n|
+@n
+2
+delete from t1|
+drop procedure bug3157|
+drop procedure if exists bug5251|
+create procedure bug5251()
+begin
+end|
+select created into @c1 from mysql.proc
+where db='test' and name='bug5251'|
+alter procedure bug5251 comment 'foobar'|
+select count(*) from mysql.proc
+where  db='test' and name='bug5251' and created = @c1|
+count(*)
+1
+drop procedure bug5251|
+drop procedure if exists bug5251|
+create procedure bug5251()
+checksum table t1|
+call bug5251()|
+Table	Checksum
+test.t1	0
+call bug5251()|
+Table	Checksum
+test.t1	0
+drop procedure bug5251|
+drop procedure if exists bug5287|
+create procedure bug5287(param1 int)
+label1:
+begin
+declare c cursor for select 5;
+loop
+if param1 >= 0 then
+leave label1;
+end if;
+end loop;
+end|
+call bug5287(1)|
+drop procedure bug5287|
+drop procedure if exists bug5307|
+create procedure bug5307()
+begin
+end; set @x = 3|
+call bug5307()|
+select @x|
+@x
+3
+drop procedure bug5307|
+drop procedure if exists bug5258|
+create procedure bug5258()
+begin
+end|
+drop procedure if exists bug5258_aux|
+create procedure bug5258_aux()
+begin
+declare c, m char(19);
+select created,modified into c,m from mysql.proc where name = 'bug5258';
+if c = m then
+select 'Ok';
+else
+select c, m;
+end if;
+end|
+call bug5258_aux()|
+Ok
+Ok
+drop procedure bug5258|
+drop procedure bug5258_aux|
+drop function if exists bug4487|
+create function bug4487() returns char
+begin
+declare v char;
+return v;
+end|
+select bug4487()|
+bug4487()
+NULL
+drop function bug4487|
+drop procedure if exists bug4941|
+drop procedure if exists bug4941|
+create procedure bug4941(out x int)
+begin
+declare c cursor for select i from t2 limit 1;
+open c;
+fetch c into x;
+close c;
+end|
+insert into t2 values (null, null, null)|
+set @x = 42|
+call bug4941(@x)|
+select @x|
+@x
+NULL
+delete from t1|
+drop procedure bug4941|
+drop procedure if exists bug3583|
+drop procedure if exists bug3583|
+create procedure bug3583()
+begin
+declare c int;
+select * from t1;
+select count(*) into c from t1;
+select c;
+end|
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	0
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	0
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	2
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+drop procedure if exists bug4905|
+create table t3 (s1 int,primary key (s1))|
+drop procedure if exists bug4905|
+create procedure bug4905()
+begin
+declare v int;
+declare continue handler for sqlstate '23000' set v = 5;
+insert into t3 values (1);
+end|
+call bug4905()|
+select row_count()|
+row_count()
+1
+call bug4905()|
+select row_count()|
+row_count()
+0
+call bug4905()|
+select row_count()|
+row_count()
+0
+select * from t3|
+s1
+1
+drop procedure bug4905|
+drop table t3|
+drop procedure if exists bug6029|
+drop procedure if exists bug6029|
+create procedure bug6029()
+begin
+declare exit handler for 1136  select '1136';
+declare exit handler for sqlstate '23000'  select 'sqlstate 23000';
+declare continue handler for sqlexception  select 'sqlexception';
+insert into t3 values (1);
+insert into t3 values (1,2);
+end|
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (1)|
+call bug6029()|
+sqlstate 23000
+sqlstate 23000
+delete from t3|
+call bug6029()|
+1136
+1136
+drop procedure bug6029|
+drop table t3|
+drop procedure if exists bug8540|
+create procedure bug8540()
+begin
+declare x int default 1;
+select x as y, x+0 as z;
+end|
+call bug8540()|
+y	z
+1	1
+drop procedure bug8540|
+create table t3 (s1 int)|
+drop procedure if exists bug6642|
+create procedure bug6642()
+select abs(count(s1)) from t3|
+call bug6642()|
+abs(count(s1))
+0
+call bug6642()|
+abs(count(s1))
+0
+drop procedure bug6642|
+insert into t3 values (0),(1)|
+drop procedure if exists bug7013|
+create procedure bug7013()
+select s1,count(s1) from t3 group by s1 with rollup|
+call bug7013()|
+s1	count(s1)
+0	1
+1	1
+NULL	2
+call bug7013()|
+s1	count(s1)
+0	1
+1	1
+NULL	2
+drop procedure bug7013|
+drop table if exists t4|
+create table t4 (
+a mediumint(8) unsigned not null auto_increment,
+b smallint(5) unsigned not null,
+c char(32) not null,
+primary key  (a)
+) engine=myisam default charset=latin1|
+insert into t4 values (1, 2, 'oneword')|
+insert into t4 values (2, 2, 'anotherword')|
+drop procedure if exists bug7743|
+create procedure bug7743 ( searchstring char(28) )
+begin
+declare var mediumint(8) unsigned;
+select a into var from t4 where b = 2 and c = binary searchstring limit 1;
+select var;
+end|
+call bug7743("oneword")|
+var
+1
+call bug7743("OneWord")|
+var
+NULL
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+call bug7743("anotherword")|
+var
+2
+call bug7743("AnotherWord")|
+var
+NULL
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+drop procedure bug7743|
+drop table t4|
+delete from t3|
+insert into t3 values(1)|
+drop procedure if exists bug7992_1|
+Warnings:
+Note	1305	PROCEDURE bug7992_1 does not exist
+drop procedure if exists bug7992_2|
+Warnings:
+Note	1305	PROCEDURE bug7992_2 does not exist
+create procedure bug7992_1()
+begin
+declare i int;
+select max(s1)+1 into i from t3;
+end|
+create procedure bug7992_2()
+insert into t3 (s1) select max(t4.s1)+1 from t3 as t4|
+call bug7992_1()|
+call bug7992_1()|
+call bug7992_2()|
+call bug7992_2()|
+drop procedure bug7992_1|
+drop procedure bug7992_2|
+drop table t3|
+create table t3 (  userid bigint(20) not null default 0 )|
+drop procedure if exists bug8116|
+create procedure bug8116(in _userid int)
+select * from t3 where userid = _userid|
+call bug8116(42)|
+userid
+call bug8116(42)|
+userid
+drop procedure bug8116|
+drop table t3|
+drop procedure if exists bug6857|
+create procedure bug6857(counter int)
+begin
+declare t0, t1 int;
+declare plus bool default 0;
+set t0 = current_time();
+while counter > 0 do
+set counter = counter - 1;
+end while;
+set t1 = current_time();
+if t1 > t0 then
+set plus = 1;
+end if;
+select plus;
+end|
+drop procedure bug6857|
+drop procedure if exists bug8757|
+create procedure bug8757()
+begin
+declare x int;
+declare c1 cursor for select data from t1 limit 1;
+begin
+declare y int;
+declare c2 cursor for select i from t2 limit 1;
+open c2;
+fetch c2 into y;
+close c2;
+select 2,y;
+end;
+open c1;
+fetch c1 into x;
+close c1;
+select 1,x;
+end|
+delete from t1|
+delete from t2|
+insert into t1 values ("x", 1)|
+insert into t2 values ("y", 2, 0.0)|
+call bug8757()|
+2	y
+2	2
+1	x
+1	1
+delete from t1|
+delete from t2|
+drop procedure bug8757|
+drop procedure if exists bug8762|
+drop procedure if exists bug8762; create procedure bug8762() begin end|
+drop procedure if exists bug8762; create procedure bug8762() begin end|
+drop procedure bug8762|
+drop function if exists bug5240|
+create function bug5240 () returns int
+begin
+declare x int;
+declare c cursor for select data from t1 limit 1;
+open c;
+fetch c into x;
+close c;
+return x;
+end|
+delete from t1|
+insert into t1 values ("answer", 42)|
+select id, bug5240() from t1|
+id	bug5240()
+answer	42
+drop function bug5240|
+drop function if exists bug5278|
+create function bug5278 () returns char
+begin
+SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
+return 'okay';
+end|
+select bug5278()|
+ERROR 42000: Can't find any matching row in the user table
+select bug5278()|
+ERROR 42000: Can't find any matching row in the user table
+drop function bug5278|
+drop procedure if exists p1|
+create table t3(id int)|
+insert into t3 values(1)|
+create procedure bug7992()
+begin
+declare i int;
+select max(id)+1 into i from t3;
+end|
+call bug7992()|
+call bug7992()|
+drop procedure bug7992|
+drop table t3|
+create table t3 (
+lpitnumber int(11) default null,
+lrecordtype int(11) default null
+)|
+create table t4 (
+lbsiid int(11) not null default '0',
+ltradingmodeid int(11) not null default '0',
+ltradingareaid int(11) not null default '0',
+csellingprice decimal(19,4) default null,
+primary key  (lbsiid,ltradingmodeid,ltradingareaid)
+)|
+create table t5 (
+lbsiid int(11) not null default '0',
+ltradingareaid int(11) not null default '0',
+primary key  (lbsiid,ltradingareaid)
+)|
+drop procedure if exists bug8849|
+create procedure bug8849()
+begin
+insert into t5
+(
+t5.lbsiid,
+t5.ltradingareaid
+)
+select distinct t3.lpitnumber, t4.ltradingareaid
+from
+t4 join t3 on
+t3.lpitnumber = t4.lbsiid
+and t3.lrecordtype = 1
+left join t4 as price01 on
+price01.lbsiid = t4.lbsiid and
+price01.ltradingmodeid = 1 and
+t4.ltradingareaid = price01.ltradingareaid;
+end|
+call bug8849()|
+call bug8849()|
+call bug8849()|
+drop procedure bug8849|
+drop tables t3,t4,t5|
+drop procedure if exists bug8937|
+create procedure bug8937()
+begin
+declare s,x,y,z int;
+declare a float;
+select sum(data),avg(data),min(data),max(data) into s,x,y,z from t1;
+select s,x,y,z;
+select avg(data) into a from t1;
+select a;
+end|
+delete from t1|
+insert into t1 (data) values (1), (2), (3), (4), (6)|
+call bug8937()|
+s	x	y	z
+16	3	1	6
+a
+3.2
+drop procedure bug8937|
+delete from t1|
+drop procedure if exists bug6900|
+drop procedure if exists bug9074|
+drop procedure if exists bug6900_9074|
+create table t3 (w char unique, x char)|
+insert into t3 values ('a', 'b')|
+create procedure bug6900()
+begin
+declare exit handler for sqlexception select '1';
+begin
+declare exit handler for sqlexception select '2';
+insert into t3 values ('x', 'y', 'z');
+end;
+end|
+create procedure bug9074()
+begin
+declare x1, x2, x3, x4, x5, x6 int default 0;
+begin    
+declare continue handler for sqlstate '23000' set x5 = 1;      
+insert into t3 values ('a', 'b');      
+set x6 = 1;      
+end;
+begin1_label:
+begin
+declare continue handler for sqlstate '23000' set x1 = 1;      
+insert into t3 values ('a', 'b');      
+set x2 = 1;      
+begin2_label:
+begin  
+declare exit handler for sqlstate '23000' set x3 = 1;         
+set x4= 1;         
+insert into t3 values ('a','b');
+set x4= 0;
+end begin2_label;
+end begin1_label;
+select x1, x2, x3, x4, x5, x6;
+end|
+create procedure bug6900_9074(z int)
+begin
+declare exit handler for sqlstate '23000' select '23000';
+begin
+declare exit handler for sqlexception select 'sqlexception';
+if z = 1 then
+insert into t3 values ('a', 'b');
+else
+insert into t3 values ('x', 'y', 'z');
+end if;
+end;
+end|
+call bug6900()|
+2
+2
+call bug9074()|
+x1	x2	x3	x4	x5	x6
+1	1	1	1	1	1
+call bug6900_9074(0)|
+sqlexception
+sqlexception
+call bug6900_9074(1)|
+23000
+23000
+drop procedure bug6900|
+drop procedure bug9074|
+drop procedure bug6900_9074|
+drop table t3|
+drop procedure if exists avg|
+create procedure avg ()
+begin
+end|
+call avg ()|
+drop procedure avg|
+drop procedure if exists bug6129|
+set @old_mode= @@sql_mode;
+set @@sql_mode= "ERROR_FOR_DIVISION_BY_ZERO";
+create procedure bug6129()
+select @@sql_mode|
+call bug6129()|
+@@sql_mode
+ERROR_FOR_DIVISION_BY_ZERO
+set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"|
+call bug6129()|
+@@sql_mode
+ERROR_FOR_DIVISION_BY_ZERO
+set @@sql_mode= "NO_ZERO_IN_DATE"|
+call bug6129()|
+@@sql_mode
+ERROR_FOR_DIVISION_BY_ZERO
+set @@sql_mode=@old_mode;
+drop procedure bug6129|
+drop procedure if exists bug9856|
+create procedure bug9856()
+begin
+declare v int;
+declare c cursor for select data from t1;
+declare exit handler for sqlexception, not found select '16';
+open c;
+fetch c into v;
+select v;
+end|
+delete from t1|
+call bug9856()|
+16
+16
+call bug9856()|
+16
+16
+drop procedure bug9856|
+drop procedure if exists bug9674_1|
+drop procedure if exists bug9674_2|
+create procedure bug9674_1(out arg int)
+begin
+declare temp_in1 int default 0;
+declare temp_fl1 int default 0;
+set temp_in1 = 100;
+set temp_fl1 = temp_in1/10;
+set arg = temp_fl1;
+end|
+create procedure bug9674_2()
+begin
+declare v int default 100;
+select v/10;
+end|
+call bug9674_1(@sptmp)|
+call bug9674_1(@sptmp)|
+select @sptmp|
+@sptmp
+10
+call bug9674_2()|
+v/10
+10.0000
+call bug9674_2()|
+v/10
+10.0000
+drop procedure bug9674_1|
+drop procedure bug9674_2|
+drop procedure if exists bug9598_1|
+drop procedure if exists bug9598_2|
+create procedure bug9598_1(in var_1 char(16),
+out var_2 integer, out var_3 integer)
+begin
+set var_2 = 50;
+set var_3 = 60;
+end|
+create procedure bug9598_2(in v1 char(16),
+in v2 integer,
+in v3 integer,
+in v4 integer,
+in v5 integer)
+begin
+select v1,v2,v3,v4,v5;
+call bug9598_1(v1,@tmp1,@tmp2);
+select v1,v2,v3,v4,v5;
+end|
+call bug9598_2('Test',2,3,4,5)|
+v1	v2	v3	v4	v5
+Test	2	3	4	5
+v1	v2	v3	v4	v5
+Test	2	3	4	5
+select @tmp1, @tmp2|
+@tmp1	@tmp2
+50	60
+drop procedure bug9598_1|
+drop procedure bug9598_2|
+drop procedure if exists bug9902|
+create function bug9902() returns int(11)
+begin
+set @x = @x + 1;
+return @x;
+end|
+set @qcs1 = @@query_cache_size|
+set global query_cache_size = 100000|
+set @x = 1|
+insert into t1 values ("qc", 42)|
+select bug9902() from t1|
+bug9902()
+2
+select bug9902() from t1|
+bug9902()
+3
+select @x|
+@x
+3
+set global query_cache_size = @qcs1|
+delete from t1|
+drop function bug9902|
+drop function if exists bug9102|
+create function bug9102() returns blob return 'a'|
+select bug9102()|
+bug9102()
+a
+drop function bug9102|
+drop function if exists bug7648|
+create function bug7648() returns bit(8) return 'a'|
+select bug7648()|
+bug7648()
+a
+drop function bug7648|
+drop function if exists bug9775|
+create function bug9775(v1 char(1)) returns enum('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('c')|
+bug9775('a')	bug9775('b')	bug9775('c')
+a	b	
+Warnings:
+Warning	1265	Data truncated for column 'bug9775('c')' at row 1
+drop function bug9775|
+create function bug9775(v1 int) returns enum('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3)|
+bug9775(1)	bug9775(2)	bug9775(3)
+a	b	
+Warnings:
+Warning	1265	Data truncated for column 'bug9775(3)' at row 1
+drop function bug9775|
+create function bug9775(v1 char(1)) returns set('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
+bug9775('a')	bug9775('b')	bug9775('a,b')	bug9775('c')
+a	b	a	
+Warnings:
+Warning	1265	Data truncated for column 'v1' at row 1
+Warning	1265	Data truncated for column 'bug9775('c')' at row 1
+drop function bug9775|
+create function bug9775(v1 int) returns set('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
+bug9775(1)	bug9775(2)	bug9775(3)	bug9775(4)
+a	b	a,b	
+Warnings:
+Warning	1265	Data truncated for column 'bug9775(4)' at row 1
+drop function bug9775|
+drop function if exists bug8861|
+create function bug8861(v1 int) returns year return v1|
+select bug8861(05)|
+bug8861(05)
+2005
+set @x = bug8861(05)|
+select @x|
+@x
+2005
+drop function bug8861|
+drop procedure if exists bug9004_1|
+drop procedure if exists bug9004_2|
+create procedure bug9004_1(x char(16))
+begin
+insert into t1 values (x, 42);
+insert into t1 values (x, 17);
+end|
+create procedure bug9004_2(x char(16))
+call bug9004_1(x)|
+call bug9004_1('12345678901234567')|
+Warnings:
+Warning	1265	Data truncated for column 'x' at row 1
+call bug9004_2('12345678901234567890')|
+Warnings:
+Warning	1265	Data truncated for column 'x' at row 1
+delete from t1|
+drop procedure bug9004_1|
+drop procedure bug9004_2|
+drop procedure if exists bug7293|
+insert into t1 values ('secret', 0)|
+create procedure bug7293(p1 varchar(100))
+begin
+if exists (select id from t1 where soundex(p1)=soundex(id)) then
+select 'yes';
+end if;
+end;|
+call bug7293('secret')|
+yes
+yes
+call bug7293 ('secrete')|
+yes
+yes
+drop procedure bug7293|
+delete from t1|
+drop procedure if exists bug9841|
+drop view if exists v1|
+create view v1 as select * from t1, t2 where id = s|
+create procedure bug9841 ()
+update v1 set data = 10|
+call bug9841()|
+drop view v1|
+drop procedure bug9841|
+drop procedure if exists bug5963|
+create procedure bug5963_1 () begin declare v int; set v = (select s1 from t3); select v; end;|
+create table t3 (s1 int)|
+insert into t3 values (5)|
+call bug5963_1()|
+v
+5
+call bug5963_1()|
+v
+5
+drop procedure bug5963_1|
+drop table t3|
+create procedure bug5963_2 (cfk_value int) 
+begin 
+if cfk_value in (select cpk from t3) then 
+set @x = 5; 
+end if; 
+end; 
+|
+create table t3 (cpk int)|
+insert into t3 values (1)|
+call bug5963_2(1)|
+call bug5963_2(1)|
+drop procedure bug5963_2|
+drop table t3|
+drop function if exists bug9559|
+create function bug9559()
+returns int
+begin
+set @y = -6/2;
+return @y;
+end|
+select bug9559()|
+bug9559()
+-3
+drop function bug9559|
+drop procedure if exists bug10961|
+create procedure bug10961()
+begin
+declare v char;
+declare x int;
+declare c cursor for select * from dual;
+declare continue handler for sqlexception select x;
+set x = 1;
+open c;
+set x = 2;
+fetch c into v;
+set x = 3;
+close c;
+end|
+call bug10961()|
+x
+1
+x
+2
+x
+3
+call bug10961()|
+x
+1
+x
+2
+x
+3
+drop procedure bug10961|
+DROP PROCEDURE IF EXISTS bug6866|
+DROP VIEW IF EXISTS tv|
+Warnings:
+Note	1051	Unknown table 'test.tv'
+DROP TABLE IF EXISTS tt1,tt2,tt3|
+Warnings:
+Note	1051	Unknown table 'tt1'
+Note	1051	Unknown table 'tt2'
+Note	1051	Unknown table 'tt3'
+CREATE TABLE tt1 (a1 int, a2 int, a3 int, data varchar(10))|
+CREATE TABLE tt2 (a2 int, data2 varchar(10))|
+CREATE TABLE tt3 (a3 int, data3 varchar(10))|
+INSERT INTO tt1 VALUES (1, 1, 4, 'xx')|
+INSERT INTO tt2 VALUES (1, 'a')|
+INSERT INTO tt2 VALUES (2, 'b')|
+INSERT INTO tt2 VALUES (3, 'c')|
+INSERT INTO tt3 VALUES (4, 'd')|
+INSERT INTO tt3 VALUES (5, 'e')|
+INSERT INTO tt3 VALUES (6, 'f')|
+CREATE VIEW tv AS
+SELECT tt1.*, tt2.data2, tt3.data3
+FROM tt1 INNER JOIN tt2 ON tt1.a2 = tt2.a2
+LEFT JOIN tt3 ON tt1.a3 = tt3.a3
+ORDER BY tt1.a1, tt2.a2, tt3.a3|
+CREATE PROCEDURE bug6866 (_a1 int)
+BEGIN
+SELECT * FROM tv WHERE a1 = _a1;
+END|
+CALL bug6866(1)|
+a1	a2	a3	data	data2	data3
+1	1	4	xx	a	d
+CALL bug6866(1)|
+a1	a2	a3	data	data2	data3
+1	1	4	xx	a	d
+CALL bug6866(1)|
+a1	a2	a3	data	data2	data3
+1	1	4	xx	a	d
+DROP PROCEDURE bug6866;
+DROP VIEW tv|
+DROP TABLE tt1, tt2, tt3|
+DROP PROCEDURE IF EXISTS bug10136|
+create table t3 ( name char(5) not null primary key, val float not null)|
+insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)|
+create procedure bug10136()
+begin
+declare done int default 3;
+repeat
+select * from t3;
+set done = done - 1;
+until done <= 0 end repeat;
+end|
+call bug10136()|
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+call bug10136()|
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+call bug10136()|
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+name	val
+aaaaa	1
+bbbbb	2
+ccccc	3
+drop procedure bug10136|
+drop table t3|
+drop procedure if exists bug11529|
+create procedure bug11529()
+begin
+declare c cursor for select id, data from t1 where data in (10,13);
+open c;
+begin
+declare vid char(16);
+declare vdata int;
+declare exit handler for not found begin end;
+while true do
+fetch c into vid, vdata;
+end while;
+end;
+close c;
+end|
+insert into t1 values
+('Name1', 10),
+('Name2', 11),
+('Name3', 12),
+('Name4', 13),
+('Name5', 14)|
+call bug11529()|
+call bug11529()|
+delete from t1|
+drop procedure bug11529|
+drop procedure if exists bug6063|
+drop procedure if exists bug7088_1|
+drop procedure if exists bug7088_2|
+drop procedure if exists bug9565_sub|
+drop procedure if exists bug9565|
+create procedure bug9565_sub()
+begin
+select * from t1;
+end|
+create procedure bug9565()
+begin
+insert into t1 values ("one", 1);
+call bug9565_sub();
+end|
+call bug9565()|
+id	data
+one	1
+delete from t1|
+drop procedure bug9565_sub|
+drop procedure bug9565|
+drop procedure if exists bug9538|
+create procedure bug9538()
+set @@sort_buffer_size = 1000000|
+set @x = @@sort_buffer_size|
+set @@sort_buffer_size = 2000000|
+select @@sort_buffer_size|
+@@sort_buffer_size
+2000000
+call bug9538()|
+select @@sort_buffer_size|
+@@sort_buffer_size
+1000000
+set @@sort_buffer_size = @x|
+drop procedure bug9538|
+drop procedure if exists bug8692|
+create table t3 (c1 varchar(5), c2 char(5), c3 enum('one','two'), c4 text, c5 blob, c6 char(5), c7 varchar(5))|
+insert into t3 values ('', '', '', '', '', '', NULL)|
+Warnings:
+Warning	1265	Data truncated for column 'c3' at row 1
+create procedure bug8692()
+begin 
+declare v1 VARCHAR(10); 
+declare v2 VARCHAR(10); 
+declare v3 VARCHAR(10); 
+declare v4 VARCHAR(10); 
+declare v5 VARCHAR(10); 
+declare v6 VARCHAR(10); 
+declare v7 VARCHAR(10); 
+declare c8692 cursor for select c1,c2,c3,c4,c5,c6,c7 from t3; 
+open c8692; 
+fetch c8692 into v1,v2,v3,v4,v5,v6,v7;
+select v1, v2, v3, v4, v5, v6, v7;
+end|
+call bug8692()|
+v1	v2	v3	v4	v5	v6	v7
+						NULL
+drop procedure bug8692|
+drop table t3|
+drop function if exists bug10055|
+create function bug10055(v char(255)) returns char(255) return lower(v)|
+select t.column_name, bug10055(t.column_name)
+from information_schema.columns as t
+where t.table_schema = 'test' and t.table_name = 't1'|
+column_name	bug10055(t.column_name)
+id	id
+data	data
+drop function bug10055|
+drop procedure if exists bug12297|
+create procedure bug12297(lim int)
+begin
+set @x = 0;
+repeat
+insert into t1(id,data)
+values('aa', @x);
+set @x = @x + 1;
+until @x >= lim
+end repeat;
+end|
+call bug12297(10)|
+drop procedure bug12297|
+drop function if exists f_bug11247|
+drop procedure if exists p_bug11247|
+create function f_bug11247(param int)
+returns int
+return param + 1|
+create procedure p_bug11247(lim int)
+begin
+declare v int default 0;
+while v < lim do
+set v= f_bug11247(v);
+end while;
+end|
+call p_bug11247(10)|
+drop function f_bug11247|
+drop procedure p_bug11247|
+drop procedure if exists bug12168|
+drop table if exists t3, t4|
+create table t3 (a int)|
+insert into t3 values (1),(2),(3),(4)|
+create table t4 (a int)|
+create procedure bug12168(arg1 char(1))
+begin
+declare b, c integer;
+if arg1 = 'a' then
+begin
+declare c1 cursor for select a from t3 where a % 2;
+declare continue handler for not found set b = 1;
+set b = 0;
+open c1;
+c1_repeat: repeat
+fetch c1 into c;
+if (b = 1) then
+leave c1_repeat;
+end if;
+insert into t4 values (c);
+until b = 1
+end repeat;
+end;
+end if;
+if arg1 = 'b' then
+begin
+declare c2 cursor for select a from t3 where not a % 2;
+declare continue handler for not found set b = 1;
+set b = 0;
+open c2;
+c2_repeat: repeat
+fetch c2 into c;
+if (b = 1) then
+leave c2_repeat;
+end if;
+insert into t4 values (c);
+until b = 1
+end repeat;
+end;
+end if;
+end|
+call bug12168('a')|
+select * from t4|
+a
+1
+3
+truncate t4|
+call bug12168('b')|
+select * from t4|
+a
+2
+4
+truncate t4|
+call bug12168('a')|
+select * from t4|
+a
+1
+3
+truncate t4|
+call bug12168('b')|
+select * from t4|
+a
+2
+4
+truncate t4|
+drop table t3, t4|
+drop procedure if exists bug12168|
+drop table if exists t3|
+drop procedure if exists bug11333|
+create table t3 (c1 char(128))|
+insert into t3 values 
+('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')|
+create procedure bug11333(i int)
+begin
+declare tmp varchar(128);
+set @x = 0;
+repeat
+select c1 into tmp from t3
+where c1 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
+set @x = @x + 1;
+until @x >= i
+end repeat;
+end|
+call bug11333(10)|
+drop procedure bug11333|
+drop table t3|
+drop function if exists bug9048|
+create function bug9048(f1 char binary) returns char binary
+begin
+set f1= concat( 'hello', f1 );
+return f1;
+end|
+drop function bug9048|
+drop procedure if exists bug12849_1|
+create procedure bug12849_1(inout x char) select x into x|
+set @var='a'|
+call bug12849_1(@var)|
+select @var|
+@var
+a
+drop procedure bug12849_1|
+drop procedure if exists bug12849_2|
+create procedure bug12849_2(inout foo varchar(15))
+begin
+select concat(foo, foo) INTO foo;
+end|
+set @var='abcd'|
+call bug12849_2(@var)|
+select @var|
+@var
+abcdabcd
+drop procedure bug12849_2|
+drop procedure if exists bug131333|
+drop function if exists bug131333|
+create procedure bug131333()
+begin
+begin
+declare a int;
+select a;
+set a = 1;
+select a;
+end;
+begin
+declare b int;
+select b;
+end;
+end|
+create function bug131333()
+returns int
+begin
+begin
+declare a int;
+set a = 1;
+end;
+begin
+declare b int;
+return b;
+end;
+end|
+call bug131333()|
+a
+NULL
+a
+1
+b
+NULL
+select bug131333()|
+bug131333()
+NULL
+drop procedure bug131333|
+drop function bug131333|
+drop function if exists bug12379|
+drop procedure if exists bug12379_1|
+drop procedure if exists bug12379_2|
+drop procedure if exists bug12379_3|
+drop table if exists t3|
+create table t3 (c1 char(1) primary key not null)|
+create function bug12379()
+returns integer
+begin
+insert into t3 values('X');
+insert into t3 values('X');
+return 0;
+end|
+create procedure bug12379_1()
+begin
+declare exit handler for sqlexception select 42;
+select bug12379();
+END|
+create procedure bug12379_2()
+begin
+declare exit handler for sqlexception begin end;
+select bug12379();
+end|
+create procedure bug12379_3()
+begin
+select bug12379();
+end|
+select bug12379()|
+ERROR 23000: Duplicate entry 'X' for key 1
+select 1|
+1
+1
+call bug12379_1()|
+bug12379()
+42
+42
+select 2|
+2
+2
+call bug12379_2()|
+bug12379()
+select 3|
+3
+3
+call bug12379_3()|
+ERROR 23000: Duplicate entry 'X' for key 1
+select 4|
+4
+4
+drop function bug12379|
+drop procedure bug12379_1|
+drop procedure bug12379_2|
+drop procedure bug12379_3|
+drop table t3|
+drop procedure if exists bug13124|
+create procedure bug13124()
+begin
+declare y integer;
+set @x=y;
+end|
+call bug13124()|
+drop procedure  bug13124|
+drop procedure if exists bug12979_1|
+create procedure bug12979_1(inout d decimal(5)) set d = d / 2|
+set @bug12979_user_var = NULL|
+call bug12979_1(@bug12979_user_var)|
+drop procedure bug12979_1|
+drop procedure if exists bug12979_2|
+create procedure bug12979_2()
+begin
+declare internal_var decimal(5);
+set internal_var= internal_var / 2;
+select internal_var;
+end|
+call bug12979_2()|
+internal_var
+NULL
+drop procedure bug12979_2|
+drop table if exists t3|
+drop procedure if exists bug6127|
+create table t3 (s1 int unique)|
+set @sm=@@sql_mode|
+set sql_mode='traditional'|
+create procedure bug6127()
+begin
+declare continue handler for sqlstate '23000'
+    begin
+declare continue handler for sqlstate '22003'
+        insert into t3 values (0);
+insert into t3 values (1000000000000000);
+end;
+insert into t3 values (1);
+insert into t3 values (1);
+end|
+call bug6127()|
+select * from t3|
+s1
+0
+1
+call bug6127()|
+ERROR 23000: Duplicate entry '0' for key 1
+select * from t3|
+s1
+0
+1
+set sql_mode=@sm|
+drop table t3|
+drop procedure bug6127|
+drop procedure if exists bug12589_1|
+drop procedure if exists bug12589_2|
+drop procedure if exists bug12589_3|
+create procedure bug12589_1()
+begin
+declare spv1 decimal(3,3);
+set spv1= 123.456;
+set spv1 = 'test';
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+create procedure bug12589_2()
+begin
+declare spv1 decimal(6,3);
+set spv1= 123.456;
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+create procedure bug12589_3()
+begin
+declare spv1 decimal(6,3);
+set spv1= -123.456;
+create temporary table tm1 as select spv1;
+show create table tm1;
+drop temporary table tm1;
+end|
+call bug12589_1()|
+Table	Create Table
+tm1	CREATE TEMPORARY TABLE `tm1` (
+  `spv1` decimal(3,3) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+Warnings:
+Warning	1264	Out of range value adjusted for column 'spv1' at row 1
+Warning	1366	Incorrect decimal value: 'test' for column 'spv1' at row 1
+call bug12589_2()|
+Table	Create Table
+tm1	CREATE TEMPORARY TABLE `tm1` (
+  `spv1` decimal(6,3) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+call bug12589_3()|
+Table	Create Table
+tm1	CREATE TEMPORARY TABLE `tm1` (
+  `spv1` decimal(6,3) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop procedure bug12589_1|
+drop procedure bug12589_2|
+drop procedure bug12589_3|
+drop table if exists t3|
+drop procedure if exists bug7049_1|
+drop procedure if exists bug7049_2|
+drop procedure if exists bug7049_3|
+drop procedure if exists bug7049_4|
+drop function if exists bug7049_1|
+drop function if exists bug7049_2|
+create table t3 ( x int unique )|
+create procedure bug7049_1()
+begin
+insert into t3 values (42);
+insert into t3 values (42);
+end|
+create procedure bug7049_2()
+begin
+declare exit handler for sqlexception
+select 'Caught it' as 'Result';
+call bug7049_1();
+select 'Missed it' as 'Result';
+end|
+create procedure bug7049_3()
+call bug7049_1()|
+create procedure bug7049_4()
+begin
+declare exit handler for sqlexception
+select 'Caught it' as 'Result';
+call bug7049_3();
+select 'Missed it' as 'Result';
+end|
+create function bug7049_1()
+returns int
+begin
+insert into t3 values (42);
+insert into t3 values (42);
+return 42;
+end|
+create function bug7049_2()
+returns int
+begin
+declare x int default 0;
+declare continue handler for sqlexception
+set x = 1;
+set x = bug7049_1();
+return x;
+end|
+call bug7049_2()|
+Result
+Caught it
+select * from t3|
+x
+42
+delete from t3|
+call bug7049_4()|
+Result
+Caught it
+select * from t3|
+x
+42
+select bug7049_2()|
+bug7049_2()
+1
+drop table t3|
+drop procedure bug7049_1|
+drop procedure bug7049_2|
+drop procedure bug7049_3|
+drop procedure bug7049_4|
+drop function bug7049_1|
+drop function bug7049_2|
+drop function if exists bug13941|
+drop procedure if exists bug13941|
+create function bug13941(p_input_str text)
+returns text
+begin
+declare p_output_str text;
+set p_output_str = p_input_str;
+set p_output_str = replace(p_output_str, 'xyzzy', 'plugh');
+set p_output_str = replace(p_output_str, 'test', 'prova');
+set p_output_str = replace(p_output_str, 'this', 'questo');
+set p_output_str = replace(p_output_str, ' a ', 'una ');
+set p_output_str = replace(p_output_str, 'is', '');
+return p_output_str;
+end|
+create procedure bug13941(out sout varchar(128))
+begin
+set sout = 'Local';
+set sout = ifnull(sout, 'DEF');
+end|
+select bug13941('this is a test')|
+bug13941('this is a test')
+questo una prova
+call bug13941(@a)|
+select @a|
+@a
+Local
+drop function bug13941|
+drop procedure bug13941|
+DROP PROCEDURE IF EXISTS bug13095;
+DROP TABLE IF EXISTS bug13095_t1;
+DROP VIEW IF EXISTS bug13095_v1;
+CREATE PROCEDURE bug13095(tbl_name varchar(32))
+BEGIN
+SET @str =
+CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))");
+SELECT @str;
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+SET @str =
+CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" );
+SELECT @str;
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+SET @str =
+CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name);
+SELECT @str;
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+SELECT * FROM bug13095_v1;
+SET @str =
+"DROP VIEW bug13095_v1";
+SELECT @str;
+PREPARE stmt FROM @str;
+EXECUTE stmt;
+END|
+CALL bug13095('bug13095_t1');
+@str
+CREATE TABLE bug13095_t1(stuff char(15))
+@str
+INSERT INTO bug13095_t1 VALUES('row1'),('row2'),('row3')
+@str
+CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM bug13095_t1
+c1
+row1
+row2
+row3
+@str
+DROP VIEW bug13095_v1
+DROP PROCEDURE IF EXISTS bug13095;
+DROP VIEW IF EXISTS bug13095_v1;
+DROP TABLE IF EXISTS bug13095_t1;
+drop procedure if exists bug14210|
+set @@session.max_heap_table_size=16384|
+select @@session.max_heap_table_size|
+@@session.max_heap_table_size
+16384
+create table t3 (a char(255)) engine=InnoDB|
+create procedure bug14210_fill_table()
+begin
+declare table_size, max_table_size int default 0;
+select @@session.max_heap_table_size into max_table_size;
+delete from t3;
+insert into t3 (a) values (repeat('a', 255));
+repeat
+insert into t3 select a from t3;
+select count(*)*255 from t3 into table_size;
+until table_size > max_table_size*2 end repeat;
+end|
+call bug14210_fill_table()|
+drop procedure bug14210_fill_table|
+create table t4 like t3|
+create procedure bug14210()
+begin
+declare a char(255);
+declare done int default 0;
+declare c cursor for select * from t3;
+declare continue handler for sqlstate '02000' set done = 1;
+open c;
+repeat
+fetch c into a;
+if not done then
+insert into t4 values (upper(a));
+end if;
+until done end repeat;
+close c;
+end|
+call bug14210()|
+select count(*) from t4|
+count(*)
+256
+drop table t3, t4|
+drop procedure bug14210|
+set @@session.max_heap_table_size=default|
+drop function if exists bug14723|
+drop procedure if exists bug14723|
+/*!50003 create function bug14723()
+returns bigint(20)
+main_loop: begin
+return 42;
+end */;;
+show create function bug14723;;
+Function	sql_mode	Create Function
+bug14723		CREATE FUNCTION `bug14723`() RETURNS bigint(20)
+main_loop: begin
+return 42;
+end
+select bug14723();;
+bug14723()
+42
+/*!50003 create procedure bug14723()
+main_loop: begin
+select 42;
+end */;;
+show create procedure bug14723;;
+Procedure	sql_mode	Create Procedure
+bug14723		CREATE PROCEDURE `bug14723`()
+main_loop: begin
+select 42;
+end
+call bug14723();;
+42
+42
+drop function bug14723|
+drop procedure bug14723|
+create procedure bug14845()
+begin
+declare a char(255);
+declare done int default 0;
+declare c cursor for select count(*) from t1 where 1 = 0;
+declare continue handler for sqlstate '02000' set done = 1;
+open c;
+repeat
+fetch c into a;
+if not done then
+select a;
+end if;
+until done end repeat;
+close c;
+end|
+call bug14845()|
+a
+0
+drop procedure bug14845|
+drop procedure if exists bug13549_1|
+drop procedure if exists bug13549_2|
+CREATE PROCEDURE `bug13549_2`()
+begin
+call bug13549_1();
+end|
+CREATE PROCEDURE `bug13549_1`()
+begin
+declare done int default 0;
+set done= not done;
+end|
+CALL bug13549_2()|
+drop procedure bug13549_2|
+drop procedure bug13549_1|
+drop function if exists bug10100f|
+drop procedure if exists bug10100p|
+drop procedure if exists bug10100t|
+drop procedure if exists bug10100pt|
+drop procedure if exists bug10100pv|
+drop procedure if exists bug10100pd|
+drop procedure if exists bug10100pc|
+create function bug10100f(prm int) returns int
+begin
+if prm > 1 then
+return prm * bug10100f(prm - 1);
+end if;
+return 1;
+end|
+create procedure bug10100p(prm int, inout res int)
+begin
+set res = res * prm;
+if prm > 1 then
+call bug10100p(prm - 1, res);  
+end if;
+end|
+create procedure bug10100t(prm int)
+begin
+declare res int;
+set res = 1;
+call bug10100p(prm, res);
+select res;
+end|
+create table t3 (a int)|
+insert into t3 values (0)|
+create view v1 as select a from t3;
+create procedure bug10100pt(level int, lim int)
+begin
+if level < lim then
+update t3 set a=level;
+FLUSH TABLES;
+call bug10100pt(level+1, lim);
+else
+select * from t3;
+end if;
+end|
+create procedure bug10100pv(level int, lim int)
+begin
+if level < lim then
+update v1 set a=level;
+FLUSH TABLES;
+call bug10100pv(level+1, lim);
+else
+select * from v1;
+end if;
+end|
+prepare stmt2 from "select * from t3;";
+create procedure bug10100pd(level int, lim int)
+begin
+if level < lim then
+select level;
+prepare stmt1 from "update t3 set a=a+2";
+execute stmt1;
+FLUSH TABLES;
+execute stmt1;
+FLUSH TABLES;
+execute stmt1;
+FLUSH TABLES;
+deallocate prepare stmt1;
+execute stmt2;
+select * from t3;
+call bug10100pd(level+1, lim);
+else
+execute stmt2;
+end if;
+end|
+create procedure bug10100pc(level int, lim int)
+begin
+declare lv int;
+declare c cursor for select a from t3;
+open c;
+if level < lim then
+select level;
+fetch c into lv;
+select lv;
+update t3 set a=level+lv;
+FLUSH TABLES;
+call bug10100pc(level+1, lim);
+else
+select * from t3;
+end if;
+close c;
+end|
+set @@max_sp_recursion_depth=4|
+select @@max_sp_recursion_depth|
+@@max_sp_recursion_depth
+4
+select bug10100f(3)|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+select bug10100f(6)|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+call bug10100t(5)|
+res
+120
+call bug10100pt(1,5)|
+a
+4
+call bug10100pv(1,5)|
+a
+4
+update t3 set a=1|
+call bug10100pd(1,5)|
+level
+1
+a
+7
+a
+7
+level
+2
+a
+13
+a
+13
+level
+3
+a
+19
+a
+19
+level
+4
+a
+25
+a
+25
+a
+25
+select * from t3|
+a
+25
+update t3 set a=1|
+call bug10100pc(1,5)|
+level
+1
+lv
+1
+level
+2
+lv
+2
+level
+3
+lv
+4
+level
+4
+lv
+7
+a
+11
+select * from t3|
+a
+11
+set @@max_sp_recursion_depth=0|
+select @@max_sp_recursion_depth|
+@@max_sp_recursion_depth
+0
+select bug10100f(5)|
+ERROR HY000: Recursive stored functions and triggers are not allowed.
+call bug10100t(5)|
+ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug10100p
+set @@max_sp_recursion_depth=255|
+set @var=1|
+call bug10100p(255, @var)|
+call bug10100pt(1,255)|
+call bug10100pv(1,255)|
+call bug10100pd(1,255)|
+call bug10100pc(1,255)|
+set @@max_sp_recursion_depth=0|
+deallocate prepare stmt2|
+drop function bug10100f|
+drop procedure bug10100p|
+drop procedure bug10100t|
+drop procedure bug10100pt|
+drop procedure bug10100pv|
+drop procedure bug10100pd|
+drop procedure bug10100pc|
+drop view v1|
+drop procedure if exists bug13729|
+drop table if exists t3|
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (1),(2)|
+create procedure bug13729()
+begin
+declare continue handler for sqlexception select 55;
+update t3 set s1 = 1;
+end|
+call bug13729()|
+55
+55
+select * from t3|
+s1
+1
+2
+drop procedure bug13729|
+drop table t3|
+drop procedure if exists bug14643_1|
+drop procedure if exists bug14643_2|
+create procedure bug14643_1()
+begin
+declare continue handler for sqlexception select 'boo' as 'Handler';
+begin
+declare v int default undefined_var;
+if v = 1 then
+select 1;
+else
+select v, isnull(v);
+end if;
+end;
+end|
+create procedure bug14643_2()
+begin
+declare continue handler for sqlexception select 'boo' as 'Handler';
+case undefined_var
+when 1 then
+select 1;
+else
+select 2;
+end case;
+select undefined_var;
+end|
+call bug14643_1()|
+Handler
+boo
+v	isnull(v)
+NULL	1
+call bug14643_2()|
+Handler
+boo
+Handler
+boo
+drop procedure bug14643_1|
+drop procedure bug14643_2|
+drop procedure if exists bug14304|
+drop table if exists t3, t4|
+create table t3(a int primary key auto_increment)|
+create table t4(a int primary key auto_increment)|
+create procedure bug14304()
+begin
+insert into t3 set a=null;
+insert into t4 set a=null;
+insert into t4 set a=null;
+insert into t4 set a=null;
+insert into t4 set a=null;
+insert into t4 set a=null;
+insert into t4 select null as a;
+insert into t3 set a=null;
+insert into t3 set a=null;
+select * from t3;
+end|
+call bug14304()|
+a
+1
+2
+3
+drop procedure bug14304|
+drop table t3, t4|
+drop procedure if exists bug14376|
+create procedure bug14376()
+begin
+declare x int default x;
+end|
+call bug14376()|
+ERROR 42S22: Unknown column 'x' in 'field list'
+drop procedure bug14376|
+create procedure bug14376()
+begin
+declare x int default 42;
+begin
+declare x int default x;
+select x;
+end;
+end|
+call bug14376()|
+x
+42
+drop procedure bug14376|
+create procedure bug14376(x int)
+begin
+declare x int default x;
+select x;
+end|
+call bug14376(4711)|
+x
+4711
+drop procedure bug14376|
+drop procedure if exists bug5967|
+drop table if exists t3|
+create table t3 (a varchar(255))|
+insert into t3 (a) values ("a - table column")|
+create procedure bug5967(a varchar(255))
+begin
+declare i varchar(255);
+declare c cursor for select a from t3;
+select a;
+select a from t3 into i;
+select i as 'Parameter takes precedence over table column';                     open c;
+fetch c into i;
+close c;
+select i as 'Parameter takes precedence over table column in cursors';
+begin
+declare a varchar(255) default 'a - local variable';
+declare c1 cursor for select a from t3;
+select a as 'A local variable takes precedence over parameter';
+open c1;
+fetch c1 into i;
+close c1;
+select i as 'A local variable takes precedence over parameter in cursors';
+begin
+declare a varchar(255) default 'a - local variable in a nested compound statement';
+declare c2 cursor for select a from t3;
+select a as 'A local variable in a nested compound statement takes precedence over a local variable in the outer statement';
+select a from t3 into i;
+select i as  'A local variable in a nested compound statement takes precedence over table column';
+open c2;
+fetch c2 into i;
+close c2;
+select i as  'A local variable in a nested compound statement takes precedence over table column in cursors';
+end;
+end;
+end|
+call bug5967("a - stored procedure parameter")|
+a
+a - stored procedure parameter
+Parameter takes precedence over table column
+a - stored procedure parameter
+Parameter takes precedence over table column in cursors
+a - stored procedure parameter
+A local variable takes precedence over parameter
+a - local variable
+A local variable takes precedence over parameter in cursors
+a - local variable
+A local variable in a nested compound statement takes precedence over a local variable in the outer statement
+a - local variable in a nested compound statement
+A local variable in a nested compound statement takes precedence over table column
+a - local variable in a nested compound statement
+A local variable in a nested compound statement takes precedence over table column in cursors
+a - local variable in a nested compound statement
+drop procedure bug5967|
+drop procedure if exists bug13012|
+create procedure bug13012()
+BEGIN
+REPAIR TABLE t1;
+BACKUP TABLE t1 to '../tmp';
+DROP TABLE t1;
+RESTORE TABLE t1 FROM '../tmp';
+END|
+call bug13012()|
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+Table	Op	Msg_type	Msg_text
+test.t1	backup	status	OK
+Table	Op	Msg_type	Msg_text
+test.t1	restore	status	OK
+drop procedure bug13012|
+create view v1 as select * from t1|
+create procedure bug13012()
+BEGIN
+REPAIR TABLE t1,t2,t3,v1;
+OPTIMIZE TABLE t1,t2,t3,v1;
+ANALYZE TABLE t1,t2,t3,v1;
+END|
+call bug13012()|
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t2	repair	status	OK
+test.t3	repair	status	OK
+test.v1	repair	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+test.t2	optimize	status	OK
+test.t3	optimize	status	OK
+test.v1	optimize	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+test.t2	analyze	status	Table is already up to date
+test.t3	analyze	status	Table is already up to date
+test.v1	analyze	error	'test.v1' is not BASE TABLE
+Warnings:
+Error	1347	'test.v1' is not BASE TABLE
+call bug13012()|
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t2	repair	status	OK
+test.t3	repair	status	OK
+test.v1	repair	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+test.t2	optimize	status	OK
+test.t3	optimize	status	OK
+test.v1	optimize	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+test.t2	analyze	status	Table is already up to date
+test.t3	analyze	status	Table is already up to date
+test.v1	analyze	error	'test.v1' is not BASE TABLE
+Warnings:
+Error	1347	'test.v1' is not BASE TABLE
+call bug13012()|
+Table	Op	Msg_type	Msg_text
+test.t1	repair	status	OK
+test.t2	repair	status	OK
+test.t3	repair	status	OK
+test.v1	repair	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	optimize	status	OK
+test.t2	optimize	status	OK
+test.t3	optimize	status	OK
+test.v1	optimize	error	'test.v1' is not BASE TABLE
+Table	Op	Msg_type	Msg_text
+test.t1	analyze	status	Table is already up to date
+test.t2	analyze	status	Table is already up to date
+test.t3	analyze	status	Table is already up to date
+test.v1	analyze	error	'test.v1' is not BASE TABLE
+Warnings:
+Error	1347	'test.v1' is not BASE TABLE
+drop procedure bug13012|
+drop view v1;
+select * from t1|
+id	data
+aa	0
+aa	1
+aa	2
+aa	3
+aa	4
+aa	5
+aa	6
+aa	7
+aa	8
+aa	9
+drop schema if exists mysqltest1|
+Warnings:
+Note	1008	Can't drop database 'mysqltest1'; database doesn't exist
+drop schema if exists mysqltest2|
+Warnings:
+Note	1008	Can't drop database 'mysqltest2'; database doesn't exist
+drop schema if exists mysqltest3|
+Warnings:
+Note	1008	Can't drop database 'mysqltest3'; database doesn't exist
+create schema mysqltest1|
+create schema mysqltest2|
+create schema mysqltest3|
+use mysqltest3|
+create procedure mysqltest1.p1 (out prequestid varchar(100))
+begin
+call mysqltest2.p2('call mysqltest3.p3(1, 2)');
+end|
+create procedure mysqltest2.p2(in psql text)
+begin
+declare lsql text;
+set @lsql= psql;
+prepare lstatement from @lsql;
+execute lstatement;
+deallocate prepare lstatement;
+end|
+create procedure mysqltest3.p3(in p1 int)
+begin
+select p1;
+end|
+call mysqltest1.p1(@rs)|
+ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
+call mysqltest1.p1(@rs)|
+ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
+call mysqltest1.p1(@rs)|
+ERROR 42000: Incorrect number of arguments for PROCEDURE mysqltest3.p3; expected 1, got 2
+drop schema if exists mysqltest1|
+drop schema if exists mysqltest2|
+drop schema if exists mysqltest3|
+use test|
+drop table if exists t3|
+drop procedure if exists bug15441|
+create table t3 (id int not null primary key, county varchar(25))|
+insert into t3 (id, county) values (1, 'York')|
+create procedure bug15441(c varchar(25))
+begin
+update t3 set id=2, county=values(c);
+end|
+call bug15441('county')|
+ERROR 42S22: Unknown column 'c' in 'field list'
+drop procedure bug15441|
+create procedure bug15441(county varchar(25))
+begin
+declare c varchar(25) default "hello";
+insert into t3 (id, county) values (1, county)
+on duplicate key update county= values(county);
+select * from t3;
+update t3 set id=2, county=values(id);
+select * from t3;
+end|
+call bug15441('Yale')|
+id	county
+1	Yale
+id	county
+2	NULL
+drop table t3|
+drop procedure bug15441|
+drop procedure if exists bug14498_1|
+drop procedure if exists bug14498_2|
+drop procedure if exists bug14498_3|
+drop procedure if exists bug14498_4|
+drop procedure if exists bug14498_5|
+create procedure bug14498_1()
+begin
+declare continue handler for sqlexception select 'error' as 'Handler';
+if v then
+select 'yes' as 'v';
+else
+select 'no' as 'v';
+end if;
+select 'done' as 'End';
+end|
+create procedure bug14498_2()
+begin
+declare continue handler for sqlexception select 'error' as 'Handler';
+while v do
+select 'yes' as 'v';
+end while;
+select 'done' as 'End';
+end|
+create procedure bug14498_3()
+begin
+declare continue handler for sqlexception select 'error' as 'Handler';
+repeat
+select 'maybe' as 'v';
+until v end repeat;
+select 'done' as 'End';
+end|
+create procedure bug14498_4()
+begin
+declare continue handler for sqlexception select 'error' as 'Handler';
+case v
+when 1 then
+select '1' as 'v';
+when 2 then
+select '2' as 'v';
+else
+select '?' as 'v';
+end case;
+select 'done' as 'End';
+end|
+create procedure bug14498_5()
+begin
+declare continue handler for sqlexception select 'error' as 'Handler';
+case
+when v = 1 then
+select '1' as 'v';
+when v = 2 then
+select '2' as 'v';
+else
+select '?' as 'v';
+end case;
+select 'done' as 'End';
+end|
+call bug14498_1()|
+Handler
+error
+End
+done
+call bug14498_2()|
+Handler
+error
+End
+done
+call bug14498_3()|
+v
+maybe
+Handler
+error
+End
+done
+call bug14498_4()|
+Handler
+error
+End
+done
+call bug14498_5()|
+Handler
+error
+End
+done
+drop procedure bug14498_1|
+drop procedure bug14498_2|
+drop procedure bug14498_3|
+drop procedure bug14498_4|
+drop procedure bug14498_5|
+drop table if exists t3|
+drop procedure if exists bug15231_1|
+drop procedure if exists bug15231_2|
+drop procedure if exists bug15231_3|
+drop procedure if exists bug15231_4|
+create table t3 (id int not null)|
+create procedure bug15231_1()
+begin
+declare xid integer;
+declare xdone integer default 0;
+declare continue handler for not found set xdone = 1;
+set xid=null;
+call bug15231_2(xid);
+select xid, xdone;
+end|
+create procedure bug15231_2(inout ioid integer)
+begin
+select "Before NOT FOUND condition is triggered" as '1';
+select id into ioid from t3 where id=ioid;
+select "After NOT FOUND condtition is triggered" as '2';
+if ioid is null then
+set ioid=1;
+end if;
+end|
+create procedure bug15231_3()
+begin
+declare exit handler for sqlwarning
+select 'Caught it (wrong)' as 'Result';
+call bug15231_4();
+end|
+create procedure bug15231_4()
+begin
+declare x decimal(2,1);
+set x = 'zap';
+select 'Missed it (correct)' as 'Result';
+end|
+call bug15231_1()|
+1
+Before NOT FOUND condition is triggered
+2
+After NOT FOUND condtition is triggered
+xid	xdone
+1	0
+Warnings:
+Warning	1329	No data - zero rows fetched, selected, or processed
+call bug15231_3()|
+Result
+Missed it (correct)
+Warnings:
+Warning	1366	Incorrect decimal value: 'zap' for column 'x' at row 1
+drop table if exists t3|
+drop procedure if exists bug15231_1|
+drop procedure if exists bug15231_2|
+drop procedure if exists bug15231_3|
+drop procedure if exists bug15231_4|
+drop procedure if exists bug15011|
+create table t3 (c1 int primary key)|
+insert into t3 values (1)|
+create procedure bug15011()
+deterministic
+begin
+declare continue handler for 1062
+select 'Outer' as 'Handler';
+begin
+declare continue handler for 1062
+select 'Inner' as 'Handler';
+insert into t3 values (1);
+end;
+end|
+call bug15011()|
+Handler
+Inner
+drop procedure bug15011|
+drop table t3|
+drop table t1,t2;
diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result
new file mode 100644
index 00000000000..d434f5c32ce
--- /dev/null
+++ b/mysql-test/r/sp_notembedded.result
@@ -0,0 +1,206 @@
+drop procedure if exists bug4902|
+create procedure bug4902()
+begin
+show grants for 'root'@'localhost';
+end|
+call bug4902()|
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+call bug4902()|
+Grants for root@localhost
+GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION
+drop procedure bug4902|
+drop procedure if exists bug4902_2|
+create procedure bug4902_2()
+begin
+show processlist;
+end|
+call bug4902_2()|
+Id	User	Host	db	Command	Time	State	Info
+#	root	localhost	test	Query	#	NULL	show processlist
+call bug4902_2()|
+Id	User	Host	db	Command	Time	State	Info
+#	root	localhost	test	Query	#	NULL	show processlist
+drop procedure bug4902_2|
+drop function if exists bug5278|
+create function bug5278 () returns char
+begin
+SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
+return 'okay';
+end|
+select bug5278()|
+ERROR 42000: Can't find any matching row in the user table
+select bug5278()|
+ERROR 42000: Can't find any matching row in the user table
+drop function bug5278|
+drop table if exists t1|
+create table t1 (
+id   char(16) not null default '',
+data int not null
+)|
+drop procedure if exists bug3583|
+drop procedure if exists bug3583|
+create procedure bug3583()
+begin
+declare c int;
+select * from t1;
+select count(*) into c from t1;
+select c;
+end|
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	0
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	0
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+call bug3583()|
+id	data
+x	3
+y	5
+c
+2
+show status like 'Qcache_hits'|
+Variable_name	Value
+Qcache_hits	2
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+drop table t1;
+#|
+drop procedure if exists bug6807|
+create procedure bug6807()
+begin
+declare id int;
+set id = connection_id();
+kill query id;
+select 'Not reached';
+end|
+call bug6807()|
+ERROR 70100: Query execution was interrupted
+call bug6807()|
+ERROR 70100: Query execution was interrupted
+drop procedure bug6807|
+drop function if exists bug10100f|
+drop procedure if exists bug10100p|
+drop procedure if exists bug10100t|
+drop procedure if exists bug10100pt|
+drop procedure if exists bug10100pv|
+drop procedure if exists bug10100pd|
+drop procedure if exists bug10100pc|
+create function bug10100f(prm int) returns int
+begin
+if prm > 1 then
+return prm * bug10100f(prm - 1);
+end if;
+return 1;
+end|
+create procedure bug10100p(prm int, inout res int)
+begin
+set res = res * prm;
+if prm > 1 then
+call bug10100p(prm - 1, res);
+end if;
+end|
+create procedure bug10100t(prm int)
+begin
+declare res int;
+set res = 1;
+call bug10100p(prm, res);
+select res;
+end|
+create table t3 (a int)|
+insert into t3 values (0)|
+create view v1 as select a from t3;
+create procedure bug10100pt(level int, lim int)
+begin
+if level < lim then
+update t3 set a=level;
+FLUSH TABLES;
+call bug10100pt(level+1, lim);
+else
+select * from t3;
+end if;
+end|
+create procedure bug10100pv(level int, lim int)
+begin
+if level < lim then
+update v1 set a=level;
+FLUSH TABLES;
+call bug10100pv(level+1, lim);
+else
+select * from v1;
+end if;
+end|
+prepare stmt2 from "select * from t3;";
+create procedure bug10100pd(level int, lim int)
+begin
+if level < lim then
+select level;
+prepare stmt1 from "update t3 set a=a+2";
+execute stmt1;
+FLUSH TABLES;
+execute stmt1;
+FLUSH TABLES;
+execute stmt1;
+FLUSH TABLES;
+deallocate prepare stmt1;
+execute stmt2;
+select * from t3;
+call bug10100pd(level+1, lim);
+else
+execute stmt2;
+end if;
+end|
+create procedure bug10100pc(level int, lim int)
+begin
+declare lv int;
+declare c cursor for select a from t3;
+open c;
+if level < lim then
+select level;
+fetch c into lv;
+select lv;
+update t3 set a=level+lv;
+FLUSH TABLES;
+call bug10100pc(level+1, lim);
+else
+select * from t3;
+end if;
+close c;
+end|
+set @@max_sp_recursion_depth=255|
+set @var=1|
+call bug10100p(255, @var)|
+call bug10100pt(1,255)|
+call bug10100pv(1,255)|
+call bug10100pd(1,255)|
+call bug10100pc(1,255)|
+set @@max_sp_recursion_depth=0|
+deallocate prepare stmt2|
+drop function bug10100f|
+drop procedure bug10100p|
+drop procedure bug10100t|
+drop procedure bug10100pt|
+drop procedure bug10100pv|
+drop procedure bug10100pd|
+drop procedure bug10100pc|
+drop view v1|
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 33b12c05f98..48b8625d839 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2987,7 +2987,6 @@ select * from (select max(fld) from t1) as foo;
 max(fld)
 1
 drop table t1;
-purge master logs before (select adddate(current_timestamp(), interval -4 day));
 CREATE TABLE t1 (a int, b int);
 CREATE TABLE t2 (c int, d int);
 CREATE TABLE t3 (e int);
diff --git a/mysql-test/r/subselect_notembedded.result b/mysql-test/r/subselect_notembedded.result
new file mode 100644
index 00000000000..dd4b0701c32
--- /dev/null
+++ b/mysql-test/r/subselect_notembedded.result
@@ -0,0 +1 @@
+purge master logs before (select adddate(current_timestamp(), interval -4 day));
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index e209e393d00..adf92909709 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -2213,15 +2213,6 @@ r_object_id	users_names
 120001a080000542	guser02
 drop view v1, v2;
 drop table t1, t2;
-create definer=some_user@`` sql security invoker view v1 as select 1;
-ERROR HY000: Definer is not fully qualified
-create definer=some_user@localhost sql security invoker view v1 as select 1;
-Warnings:
-Note	1449	There is no 'some_user'@'localhost' registered
-show create view v1;
-View	Create View
-v1	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
-drop view v1;
 create table t1 (s1 int);
 create view abc as select * from t1 as abc;
 drop table t1;
diff --git a/mysql-test/r/view_grant.result b/mysql-test/r/view_grant.result
index b20990e95a4..46fb4698838 100644
--- a/mysql-test/r/view_grant.result
+++ b/mysql-test/r/view_grant.result
@@ -519,3 +519,12 @@ use test;
 use test;
 drop user mysqltest_1@localhost;
 drop database mysqltest;
+create definer=some_user@`` sql security invoker view v1 as select 1;
+ERROR HY000: Definer is not fully qualified
+create definer=some_user@localhost sql security invoker view v1 as select 1;
+Warnings:
+Note	1449	There is no 'some_user'@'localhost' registered
+show create view v1;
+View	Create View
+v1	CREATE ALGORITHM=UNDEFINED DEFINER=`some_user`@`localhost` SQL SECURITY INVOKER VIEW `v1` AS select 1 AS `1`
+drop view v1;
diff --git a/mysql-test/t/backup.test b/mysql-test/t/backup.test
index a3339ecce69..053e83528e0 100644
--- a/mysql-test/t/backup.test
+++ b/mysql-test/t/backup.test
@@ -1,3 +1,6 @@
+# This test should work in embedded server after we fix mysqltest
+-- source include/not_embedded.inc
+
 #
 # This test is a bit tricky as we can't use backup table to overwrite an old
 # table
diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test
index 2310e800df7..42dd4ee6299 100644
--- a/mysql-test/t/binlog.test
+++ b/mysql-test/t/binlog.test
@@ -1,6 +1,7 @@
 #
 # misc binlogging tests that do not require a slave running
 #
+-- source include/not_embedded.inc
 -- source include/have_bdb.inc
 -- source include/have_innodb.inc
 
@@ -18,7 +19,7 @@ begin;
 insert t2 values (5);
 commit;
 # first COMMIT must be Query_log_event, second - Xid_log_event
---replace_result "xid=18" "xid=11"
+--replace_result "xid=19" "xid=12"
 --replace_column 2 # 5 #
 show binlog events from 98;
 drop table t1,t2;
@@ -40,7 +41,7 @@ while ($1)
 --enable_query_log
 commit;
 drop table t1;
---replace_result "xid=29" "xid=18"
+--replace_result "xid=30" "xid=19"
 --replace_column 2 # 5 #
 show binlog events in 'master-bin.000001' from 98;
 --replace_column 2 # 5 #
diff --git a/mysql-test/t/blackhole.test b/mysql-test/t/blackhole.test
index ce26d2447eb..e40b84eb5cd 100644
--- a/mysql-test/t/blackhole.test
+++ b/mysql-test/t/blackhole.test
@@ -2,6 +2,7 @@
 # Simple test for blackhole example
 # Taken from the select test
 #
+-- source include/not_embedded.inc
 -- source include/have_blackhole.inc
 
 --disable_warnings
diff --git a/mysql-test/t/compress.test b/mysql-test/t/compress.test
index 46244edd2a8..3f1892b5dec 100644
--- a/mysql-test/t/compress.test
+++ b/mysql-test/t/compress.test
@@ -1,6 +1,9 @@
 # Turn on compression between the client and server
 # and run a number of tests
 
+# Can't test with embedded server
+-- source include/not_embedded.inc
+
 -- source include/have_compress.inc
 
 connect (comp_con,localhost,root,,,,,COMPRESS);
diff --git a/mysql-test/t/ctype_cp932.test b/mysql-test/t/ctype_cp932.test
index 0c70e264891..688d06c4dde 100644
--- a/mysql-test/t/ctype_cp932.test
+++ b/mysql-test/t/ctype_cp932.test
@@ -398,28 +398,6 @@ DROP TABLE t2;
 DROP TABLE t3;
 DROP TABLE t4;
 
-# Test prepared statement with 0x8300 sequence in parameter while
-# running with cp932 client character set.
-RESET MASTER;
-CREATE TABLE t1(f1 blob);
-PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
-SET @var1= x'8300';
-# TODO: Note that this doesn't actually test the code which was added for
-# bug#11338 because this syntax for prepared statements causes the PS to
-# be replicated differently than if we executed the PS from C or Java.
-# Using this syntax, variable names are inserted into the binlog instead
-# of values. The real goal of this test is to check the code that was
-# added to Item_param::query_val_str() in order to do hex encoding of
-# PS parameters when the client character set is cp932;
-# Bug#11338 has an example java program which can be used to verify this 
-# code (and I have used it to test the fix) until there is some way to
-# exercise this code from mysql-test-run.
-EXECUTE stmt1 USING @var1;
-SHOW BINLOG EVENTS FROM 98;
-SELECT HEX(f1) FROM t1;
-DROP table t1;
-# end test for bug#11338
-
 SET collation_connection='cp932_japanese_ci';
 -- source include/ctype_filesort.inc
 SET collation_connection='cp932_bin';
diff --git a/mysql-test/t/ctype_cp932_notembedded.test b/mysql-test/t/ctype_cp932_notembedded.test
new file mode 100644
index 00000000000..52e7acc3f01
--- /dev/null
+++ b/mysql-test/t/ctype_cp932_notembedded.test
@@ -0,0 +1,32 @@
+-- source include/not_embedded.inc
+-- source include/have_cp932.inc
+
+--character_set cp932
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+set names cp932;
+set character_set_database = cp932;
+
+# Test prepared statement with 0x8300 sequence in parameter while
+# running with cp932 client character set.
+RESET MASTER;
+CREATE TABLE t1(f1 blob);
+PREPARE stmt1 FROM 'INSERT INTO t1 VALUES(?)';
+SET @var1= x'8300';
+# TODO: Note that this doesn't actually test the code which was added for
+# bug#11338 because this syntax for prepared statements causes the PS to
+# be replicated differently than if we executed the PS from C or Java.
+# Using this syntax, variable names are inserted into the binlog instead
+# of values. The real goal of this test is to check the code that was
+# added to Item_param::query_val_str() in order to do hex encoding of
+# PS parameters when the client character set is cp932;
+# Bug#11338 has an example java program which can be used to verify this 
+# code (and I have used it to test the fix) until there is some way to
+# exercise this code from mysql-test-run.
+EXECUTE stmt1 USING @var1;
+SHOW BINLOG EVENTS FROM 98;
+SELECT HEX(f1) FROM t1;
+DROP table t1;
+# end test for bug#11338
diff --git a/mysql-test/t/delayed.test b/mysql-test/t/delayed.test
index ca34cc020f3..5ae757b1fde 100644
--- a/mysql-test/t/delayed.test
+++ b/mysql-test/t/delayed.test
@@ -3,6 +3,9 @@
 # (Can't be tested with purify :( )
 #
 
+# This tests not performed with embedded server
+-- source include/not_embedded.inc
+
 --disable_warnings
 drop table if exists t1;
 --enable_warnings
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
index 3fb09df5f2f..a7f1eeaa2cc 100644
--- a/mysql-test/t/handler.test
+++ b/mysql-test/t/handler.test
@@ -2,6 +2,9 @@
 # test of HANDLER ...
 #
 
+# should work in embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
+
 --disable_warnings
 drop table if exists t1,t3,t4,t5;
 --enable_warnings
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index a47e635cf74..64d7d55294d 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -1619,33 +1619,7 @@ connection a;
 checksum table t1;
 drop table t1;
 
-#
-# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
-# non-blocking SELECT
-#
-create table t1 (col1 integer primary key, col2 integer) engine=innodb;
-insert t1 values (1,100);
-delimiter |;
-create function f1 () returns integer begin
-declare var1 int;
-select col2 into var1 from t1 where col1=1 for update;
-return var1;
-end|
-delimiter ;|
-start transaction;
-select f1();
-connection b;
-send update t1 set col2=0 where col1=1;
 connection default;
-select * from t1;
-connection a;
-rollback;
-connection b;
-reap;
-rollback;
-connection default;
-drop table t1;
-drop function f1;
 disconnect a;
 disconnect b;
 
@@ -1788,6 +1762,7 @@ commit;
 
 set foreign_key_checks=0;
 create table t2 (a int primary key, b int, foreign key (b) references t1(a)) engine = innodb;
+--replace_result $MYSQLTEST_VARDIR . master-data/ ''
 -- error 1005
 create table t1(a char(10) primary key, b varchar(20)) engine = innodb;
 set foreign_key_checks=1;
@@ -1798,6 +1773,7 @@ drop table t2;
 
 set foreign_key_checks=0;
 create table t1(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=latin1;
+--replace_result $MYSQLTEST_VARDIR . master-data/ ''
 -- error 1005
 create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=utf8;
 set foreign_key_checks=1;
@@ -1827,6 +1803,7 @@ drop table t2,t1;
 set foreign_key_checks=0;
 create table t2 (a varchar(10), foreign key (a) references t1(a)) engine = innodb DEFAULT CHARSET=latin1;
 create table t3(a varchar(10) primary key) engine = innodb DEFAULT CHARSET=utf8;
+--replace_result $MYSQLTEST_VARDIR . master-data/ ''
 -- error 1025
 rename table t3 to t1;
 set foreign_key_checks=1;
diff --git a/mysql-test/t/innodb_notembedded.test b/mysql-test/t/innodb_notembedded.test
new file mode 100644
index 00000000000..53332d9fda4
--- /dev/null
+++ b/mysql-test/t/innodb_notembedded.test
@@ -0,0 +1,40 @@
+-- source include/not_embedded.inc
+-- source include/have_innodb.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+connect (a,localhost,root,,);
+connect (b,localhost,root,,);
+
+
+#
+# BUG#11238 - in prelocking mode SELECT .. FOR UPDATE is changed to
+# non-blocking SELECT
+#
+create table t1 (col1 integer primary key, col2 integer) engine=innodb;
+insert t1 values (1,100);
+delimiter |;
+create function f1 () returns integer begin
+declare var1 int;
+select col2 into var1 from t1 where col1=1 for update;
+return var1;
+end|
+delimiter ;|
+start transaction;
+select f1();
+connection b;
+send update t1 set col2=0 where col1=1;
+connection default;
+select * from t1;
+connection a;
+rollback;
+connection b;
+reap;
+rollback;
+connection default;
+drop table t1;
+drop function f1;
+disconnect a;
+disconnect b;
diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test
index 7a9a1ee3f60..4712e7e8266 100644
--- a/mysql-test/t/mysql.test
+++ b/mysql-test/t/mysql.test
@@ -1,3 +1,5 @@
+# This test should work in embedded server after we fix mysqltest
+-- source include/not_embedded.inc
 #
 # Testing the MySQL command line client(mysql)
 #
diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test
index 4899ef9cecc..b61deeac001 100644
--- a/mysql-test/t/mysql_client_test.test
+++ b/mysql-test/t/mysql_client_test.test
@@ -1,3 +1,6 @@
+# This test should work in embedded server after we fix mysqltest
+-- source include/not_embedded.inc
+
 # We run with different binaries for normal and --embedded-server
 #
 # If this test fails with "command "$MYSQL_CLIENT_TEST" failed",
diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 1bb1cd48f0d..858c704c10e 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -1,3 +1,5 @@
+# This test should work in embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
 
 # ============================================================================
 #
diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test
index 2dca45470cc..d416f34ce45 100644
--- a/mysql-test/t/query_cache.test
+++ b/mysql-test/t/query_cache.test
@@ -819,29 +819,14 @@ select sql_cache * from t1 where s1=1;
 end;//
 delimiter ;//
 call f1();
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
 call f1();
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
 call f1();
 select sql_cache * from t1;
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
 insert into t1 values (1);
 select sql_cache * from t1;
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
 call f1();
 call f1();
 select sql_cache * from t1;
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
 flush query cache;
 reset query cache;
 flush status;
diff --git a/mysql-test/t/query_cache_notembedded.test b/mysql-test/t/query_cache_notembedded.test
index fd4785ffe95..5e1ab7051e5 100644
--- a/mysql-test/t/query_cache_notembedded.test
+++ b/mysql-test/t/query_cache_notembedded.test
@@ -97,4 +97,88 @@ connection root;
 SELECT * FROM t1;
 drop table t1;
 
+#
+# query in QC from normal execution and SP (BUG#6897)
+# improved to also test BUG#3583 and BUG#12990
+#
+flush query cache;
+reset query cache;
+flush status;
+delimiter //;
+create table t1 (s1 int)//
+create procedure f1 () begin
+select sql_cache * from t1;
+select sql_cache * from t1;
+select sql_cache * from t1;
+end;//
+create procedure f2 () begin
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1;
+end;//
+create procedure f3 () begin
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+end;//
+create procedure f4 () begin
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1 where s1=1;
+end;//
+delimiter ;//
+call f1();
+--replace_result 1 3
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+call f1();
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+call f1();
+select sql_cache * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+insert into t1 values (1);
+select sql_cache * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+call f1();
+call f1();
+select sql_cache * from t1;
+show status like "Qcache_queries_in_cache";
+show status like "Qcache_inserts";
+show status like "Qcache_hits";
+flush query cache;
+reset query cache;
+flush status;
+select sql_cache * from t1;
+select sql_cache * from t1 where s1=1;
+call f1();
+call f2();
+call f3();
+call f4();
+call f4();
+call f3();
+call f2();
+select sql_cache * from t1 where s1=1;
+insert into t1 values (2);
+call f1();
+select sql_cache * from t1 where s1=1;
+select sql_cache * from t1;
+call f1();
+call f3();
+call f3();
+call f1();
+
+drop procedure f1;
+drop procedure f2;
+drop procedure f3;
+drop procedure f4;
+drop table t1;
+
+
 set GLOBAL query_cache_size=0;
diff --git a/mysql-test/t/read_only.test b/mysql-test/t/read_only.test
index b9008ac34a3..175a5bba6fa 100644
--- a/mysql-test/t/read_only.test
+++ b/mysql-test/t/read_only.test
@@ -1,6 +1,9 @@
 # Test of the READ_ONLY global variable:
 # check that it blocks updates unless they are only on temporary tables.
 
+# should work with embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
+
 --disable_warnings
 DROP TABLE IF EXISTS t1,t2,t3;
 --enable_warnings
diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test
index 16b0fbc4d25..a0164cb0759 100644
--- a/mysql-test/t/skip_grants.test
+++ b/mysql-test/t/skip_grants.test
@@ -1,3 +1,6 @@
+# This tests not performed with embedded server
+-- source include/not_embedded.inc
+
 --disable_warnings
 drop table if exists t1,v1;
 drop view if exists t1,v1;
diff --git a/mysql-test/t/sp-destruct.test b/mysql-test/t/sp-destruct.test
index fb368a1e621..4f5f1cdcb9b 100644
--- a/mysql-test/t/sp-destruct.test
+++ b/mysql-test/t/sp-destruct.test
@@ -46,10 +46,13 @@ flush table mysql.proc;
 
 # Thrashing the .frm file
 --system echo 'saljdlfa' > $MYSQLTEST_VARDIR/master-data/mysql/proc.frm
+--replace_result $MYSQLTEST_VARDIR . master-data// ''
 --error ER_NOT_FORM_FILE
 call bug14233();
+--replace_result $MYSQLTEST_VARDIR . master-data// ''
 --error ER_NOT_FORM_FILE
 create view v1 as select bug14233_f();
+--replace_result $MYSQLTEST_VARDIR . master-data// ''
 --error ER_NOT_FORM_FILE
 insert into t1 values (0);
 
diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test
index c4745537de3..4b307de2ad0 100644
--- a/mysql-test/t/sp-error.test
+++ b/mysql-test/t/sp-error.test
@@ -647,28 +647,6 @@ create table t5 (x int)|
 call bug3294()|
 drop procedure bug3294|
 
-#
-# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
-#
---disable_warnings
-drop procedure if exists bug6807|
---enable_warnings
-create procedure bug6807()
-begin
-  declare id int;
-
-  set id = connection_id();
-  kill query id;
-  select 'Not reached';
-end|
-
---error 1317
-call bug6807()|
---error 1317
-call bug6807()|
-
-drop procedure bug6807|
-
 #
 # BUG#876: Stored Procedures: Invalid SQLSTATE is allowed in 
 #          a DECLARE ? HANDLER FOR stmt.
diff --git a/mysql-test/t/sp-threads.test b/mysql-test/t/sp-threads.test
index 70c1efb1f0b..d8a8ce5dae7 100644
--- a/mysql-test/t/sp-threads.test
+++ b/mysql-test/t/sp-threads.test
@@ -1,3 +1,5 @@
+# This test should work in embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
 #
 # Testing stored procedures with multiple connections,
 # except security/privilege tests, they go to sp-security.test
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index a4b99620344..243c1b413b7 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -699,10 +699,11 @@ drop procedure into_test4|
 --disable_warnings
 drop procedure if exists into_outfile|
 --enable_warnings
-create procedure into_outfile(x char(16), y int)
+--replace_result $MYSQLTEST_VARDIR ..
+eval create procedure into_outfile(x char(16), y int)
 begin
   insert into test.t1 values (x, y);
-  select * into outfile "../tmp/spout" from test.t1;
+  select * into outfile "$MYSQLTEST_VARDIR/tmp/spout" from test.t1;
   insert into test.t1 values (concat(x, "2"), y+2);
 end|
 
@@ -715,10 +716,11 @@ drop procedure into_outfile|
 --disable_warnings
 drop procedure if exists into_dumpfile|
 --enable_warnings
-create procedure into_dumpfile(x char(16), y int)
+--replace_result $MYSQLTEST_VARDIR ..
+eval create procedure into_dumpfile(x char(16), y int)
 begin
   insert into test.t1 values (x, y);
-  select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
+  select * into dumpfile "$MYSQLTEST_VARDIR/tmp/spdump" from test.t1 limit 1;
   insert into test.t1 values (concat(x, "2"), y+2);
 end|
 
@@ -1531,7 +1533,7 @@ begin
   end while;
 end|
 show create procedure opp|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like '%p%'|
 
 # This isn't the fastest way in the world to compute prime numbers, so
@@ -1549,7 +1551,7 @@ select * from t3 where i=45 or i=100 or i=199|
 drop table t3|
 drop procedure opp|
 drop procedure ip|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like '%p%'|
 
 
@@ -1618,13 +1620,13 @@ drop procedure if exists bar|
 create procedure bar(x char(16), y int)
  comment "111111111111" sql security invoker
  insert into test.t1 values (x, y)|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like 'bar'|
 alter procedure bar comment "2222222222" sql security definer|
 alter procedure bar comment "3333333333"|
 alter procedure bar|
 show create procedure bar|
---replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+--replace_column 4 'root@localhost' 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
 show procedure status like 'bar'|
 drop procedure bar|
 
@@ -2965,7 +2967,6 @@ begin
   show databases like 'foo';
   show errors;
   show columns from t1;
-  show grants for 'root'@'localhost';
   show keys from t1;
   show open tables like 'foo';
   show privileges;
@@ -2987,20 +2988,6 @@ call bug4902()|
 
 drop procedure bug4902|
 
-# We need separate SP for SHOW PROCESSLIST  since we want use replace_column
---disable_warnings
-drop procedure if exists bug4902_2|
---enable_warnings
-create procedure bug4902_2()
-begin
-  show processlist;
-end|
---replace_column 1 # 6 # 3 localhost
-call bug4902_2()|
---replace_column 1 # 6 # 3 localhost
-call bug4902_2()|
-drop procedure bug4902_2|
-
 #
 # BUG#4904
 #
@@ -3215,44 +3202,6 @@ select @x|
 delete from t1|
 drop procedure bug4941|
 
-
-#
-# BUG#3583: query cache doesn't work for stored procedures
-#
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
---disable_warnings
-drop procedure if exists bug3583|
---enable_warnings
-create procedure bug3583()
-begin
-  declare c int;
-
-  select * from t1;
-  select count(*) into c from t1;
-  select c;
-end|
-
-insert into t1 values ("x", 3), ("y", 5)|
-set @x = @@query_cache_size|
-set global query_cache_size = 10*1024*1024|
-
-flush status|
-flush query cache|
-show status like 'Qcache_hits'|
-call bug3583()|
-show status like 'Qcache_hits'|
-call bug3583()|
-call bug3583()|
-show status like 'Qcache_hits'|
-
-set global query_cache_size = @x|
-flush status|
-flush query cache|
-delete from t1|
-drop procedure bug3583|
-
 #
 # BUG#4905: Stored procedure doesn't clear for "Rows affected"
 #
@@ -3561,24 +3510,6 @@ insert into t1 values ("answer", 42)|
 select id, bug5240() from t1|
 drop function bug5240|
 
-#
-# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
-#
---disable_warnings
-drop function if exists bug5278|
---enable_warnings
-create function bug5278 () returns char
-begin
-  SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
-  return 'okay';
-end|
-
---error 1133
-select bug5278()|
---error 1133
-select bug5278()|
-drop function bug5278|
-
 #
 # BUG#7992: rolling back temporary Item tree changes in SP
 #
@@ -5176,24 +5107,6 @@ select bug10100f(5)|
 call bug10100t(5)|
 
 #end of the stack checking
-set @@max_sp_recursion_depth=255|
-set @var=1|
-#disable log because error about stack overrun contains numbers which
-#depend on a system
--- disable_result_log
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100p(255, @var)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pt(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pv(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pd(1,255)|
--- error ER_STACK_OVERRUN_NEED_MORE
-call bug10100pc(1,255)|
--- enable_result_log
-set @@max_sp_recursion_depth=0|
-
 deallocate prepare stmt2|
 
 drop function bug10100f|
diff --git a/mysql-test/t/sp.test.orig b/mysql-test/t/sp.test.orig
new file mode 100644
index 00000000000..a4b99620344
--- /dev/null
+++ b/mysql-test/t/sp.test.orig
@@ -0,0 +1,5716 @@
+#
+# Basic stored PROCEDURE tests
+#
+# Please keep this file free of --error cases and other
+# things that will not run in a single debugged mysqld
+# process (e.g. master-slave things).
+#
+# Test cases for bugs are added at the end. See template there.
+#
+# Tests that require --error go into sp-error.test
+# Tests that require inndb go into sp_trans.test
+# Tests that check privilege and security issues go to sp-security.test.
+# Tests that require multiple connections, except security/privilege tests,
+#   go to sp-thread.
+# Tests that uses 'goto' to into sp-goto.test (currently disabled)
+# Tests that destroys system tables (e.g. mysql.proc) for error testing
+#   go to sp-destruct.
+
+use test;
+
+# Test tables
+#
+# t1 and t2 are reused throughout the file, and dropped at the end.
+# t3 and up are created and dropped when needed.
+#
+--disable_warnings
+drop table if exists t1,t2,t3,t4;
+--enable_warnings
+create table t1 (
+	id   char(16) not null default '',
+        data int not null
+);
+create table t2 (
+	s   char(16),
+        i   int,
+	d   double
+);
+
+
+# Single statement, no params.
+--disable_warnings
+drop procedure if exists foo42;
+--enable_warnings
+create procedure foo42()
+  insert into test.t1 values ("foo", 42);
+
+call foo42();
+select * from t1;
+delete from t1;
+drop procedure foo42;
+
+
+# Single statement, two IN params.
+--disable_warnings
+drop procedure if exists bar;
+--enable_warnings
+create procedure bar(x char(16), y int)
+  insert into test.t1 values (x, y);
+
+call bar("bar", 666);
+select * from t1;
+delete from t1;
+# Don't drop procedure yet...
+
+
+# Now for multiple statements...
+delimiter |;
+
+# Empty statement
+--disable_warnings
+drop procedure if exists empty|
+--enable_warnings
+create procedure empty()
+begin
+end|
+
+call empty()|
+drop procedure empty|
+
+# Scope test. This is legal (warnings might be possible in the future,
+# but for the time being, we just accept it).
+--disable_warnings
+drop procedure if exists scope|
+--enable_warnings
+create procedure scope(a int, b float)
+begin
+  declare b int;
+  declare c float;
+
+  begin
+    declare c int;
+  end;
+end|
+
+drop procedure scope|
+
+# Two statements.
+--disable_warnings
+drop procedure if exists two|
+--enable_warnings
+create procedure two(x1 char(16), x2 char(16), y int)
+begin
+  insert into test.t1 values (x1, y);
+  insert into test.t1 values (x2, y);
+end|
+
+call two("one", "two", 3)|
+select * from t1|
+delete from t1|
+drop procedure two|
+
+
+# Simple test of local variables and SET.
+--disable_warnings
+drop procedure if exists locset|
+--enable_warnings
+create procedure locset(x char(16), y int)
+begin
+  declare z1, z2 int;
+  set z1 = y;
+  set z2 = z1+2;
+  insert into test.t1 values (x, z2);
+end|
+
+call locset("locset", 19)|
+select * from t1|
+delete from t1|
+drop procedure locset|
+
+
+# In some contexts local variables are not recognized
+# (and in some, you have to qualify the identifier).
+--disable_warnings
+drop procedure if exists setcontext|
+--enable_warnings
+create procedure setcontext()
+begin
+  declare data int default 2;
+
+  insert into t1 (id, data) values ("foo", 1);
+  replace t1 set data = data, id = "bar";
+  update t1 set id = "kaka", data = 3 where t1.data = data;
+end|
+
+call setcontext()|
+select * from t1|
+delete from t1|
+drop procedure setcontext|
+
+
+# Set things to null
+create table t3 ( d date, i int, f double, s varchar(32) )|
+
+--disable_warnings
+drop procedure if exists nullset|
+--enable_warnings
+create procedure nullset()
+begin
+  declare ld date;
+  declare li int;
+  declare lf double;
+  declare ls varchar(32);
+
+  set ld = null, li = null, lf = null, ls = null;
+  insert into t3 values (ld, li, lf, ls);
+
+  insert into t3 (i, f, s) values ((ld is null), 1,    "ld is null"),
+                                  ((li is null), 1,    "li is null"),
+				  ((li = 0),     null, "li = 0"),
+				  ((lf is null), 1,    "lf is null"),
+				  ((lf = 0),     null, "lf = 0"),
+				  ((ls is null), 1,    "ls is null");
+end|
+
+call nullset()|
+select * from t3|
+drop table t3|
+drop procedure nullset|
+
+
+# The peculiar (non-standard) mixture of variables types in SET.
+--disable_warnings
+drop procedure if exists mixset|
+--enable_warnings
+create procedure mixset(x char(16), y int)
+begin
+  declare z int;
+
+  set @z = y, z = 666, max_join_size = 100;
+  insert into test.t1 values (x, z);
+end|
+
+call mixset("mixset", 19)|
+show variables like 'max_join_size'|
+select id,data,@z from t1|
+delete from t1|
+drop procedure mixset|
+
+
+# Multiple CALL statements, one with OUT parameter.
+--disable_warnings
+drop procedure if exists zip|
+--enable_warnings
+create procedure zip(x char(16), y int)
+begin
+  declare z int;
+  call zap(y, z);
+  call bar(x, z);
+end|
+
+# SET local variables and OUT parameter.
+--disable_warnings
+drop procedure if exists zap|
+--enable_warnings
+create procedure zap(x int, out y int)
+begin
+  declare z int;
+  set z = x+1, y = z;
+end|
+
+call zip("zip", 99)|
+select * from t1|
+delete from t1|
+drop procedure zip|
+drop procedure bar|
+
+# Top-level OUT parameter
+call zap(7, @zap)|
+select @zap|
+
+drop procedure zap|
+
+
+# "Deep" calls...
+--disable_warnings
+drop procedure if exists c1|
+--enable_warnings
+create procedure c1(x int)
+  call c2("c", x)|
+--disable_warnings
+drop procedure if exists c2|
+--enable_warnings
+create procedure c2(s char(16), x int)
+  call c3(x, s)|
+--disable_warnings
+drop procedure if exists c3|
+--enable_warnings
+create procedure c3(x int, s char(16))
+  call c4("level", x, s)|
+--disable_warnings
+drop procedure if exists c4|
+--enable_warnings
+create procedure c4(l char(8), x int, s char(16))
+  insert into t1 values (concat(l,s), x)|
+
+call c1(42)|
+select * from t1|
+delete from t1|
+drop procedure c1|
+drop procedure c2|
+drop procedure c3|
+drop procedure c4|
+
+# INOUT test
+--disable_warnings
+drop procedure if exists iotest|
+--enable_warnings
+create procedure iotest(x1 char(16), x2 char(16), y int)
+begin
+  call inc2(x2, y);
+  insert into test.t1 values (x1, y);
+end|
+
+--disable_warnings
+drop procedure if exists inc2|
+--enable_warnings
+create procedure inc2(x char(16), y int)
+begin
+  call inc(y);
+  insert into test.t1 values (x, y);
+end|
+
+--disable_warnings
+drop procedure if exists inc|
+--enable_warnings
+create procedure inc(inout io int)
+  set io = io + 1|
+
+call iotest("io1", "io2", 1)|
+select * from t1|
+delete from t1|
+drop procedure iotest|
+drop procedure inc2|
+
+# Propagating top-level @-vars
+--disable_warnings
+drop procedure if exists incr|
+--enable_warnings
+create procedure incr(inout x int)
+  call inc(x)|
+
+# Before
+select @zap|
+call incr(@zap)|
+# After
+select @zap|
+
+drop procedure inc|
+drop procedure incr|
+
+# Call-by-value test
+#  The expected result is:
+#    ("cbv2", 4)
+#    ("cbv1", 4711)
+--disable_warnings
+drop procedure if exists cbv1|
+--enable_warnings
+create procedure cbv1()
+begin
+  declare y int default 3;
+
+  call cbv2(y+1, y);
+  insert into test.t1 values ("cbv1", y);
+end|
+
+--disable_warnings
+drop procedure if exists cbv2|
+--enable_warnings
+create procedure cbv2(y1 int, inout y2 int)
+begin
+  set y2 = 4711;
+  insert into test.t1 values ("cbv2", y1);
+end|
+
+call cbv1()|
+select * from t1|
+delete from t1|
+drop procedure cbv1|
+drop procedure cbv2|
+
+
+# Subselect arguments
+
+insert into t2 values ("a", 1, 1.1), ("b", 2, 1.2), ("c", 3, 1.3)|
+
+--disable_warnings
+drop procedure if exists sub1|
+--enable_warnings
+create procedure sub1(id char(16), x int)
+  insert into test.t1 values (id, x)|
+
+--disable_warnings
+drop procedure if exists sub2|
+--enable_warnings
+create procedure sub2(id char(16))
+begin
+  declare x int;
+  set x = (select sum(t.i) from test.t2 t);
+  insert into test.t1 values (id, x);
+end|
+
+--disable_warnings
+drop procedure if exists sub3|
+--enable_warnings
+create function sub3(i int) returns int
+  return i+1|
+
+call sub1("sub1a", (select 7))|
+call sub1("sub1b", (select max(i) from t2))|
+--error ER_OPERAND_COLUMNS
+call sub1("sub1c", (select i,d from t2 limit 1))|
+call sub1("sub1d", (select 1 from (select 1) a))|
+call sub2("sub2")|
+select * from t1|
+select sub3((select max(i) from t2))|
+drop procedure sub1|
+drop procedure sub2|
+drop function sub3|
+delete from t1|
+delete from t2|
+
+# Basic tests of the flow control constructs
+
+# Just test on 'x'...
+--disable_warnings
+drop procedure if exists a0|
+--enable_warnings
+create procedure a0(x int)
+while x do
+  set x = x-1;
+  insert into test.t1 values ("a0", x);
+end while|
+
+call a0(3)|
+select * from t1|
+delete from t1|
+drop procedure a0|
+
+
+# The same, but with a more traditional test.
+--disable_warnings
+drop procedure if exists a|
+--enable_warnings
+create procedure a(x int)
+while x > 0 do
+  set x = x-1;
+  insert into test.t1 values ("a", x);
+end while|
+
+call a(3)|
+select * from t1|
+delete from t1|
+drop procedure a|
+
+
+# REPEAT
+--disable_warnings
+drop procedure if exists b|
+--enable_warnings
+create procedure b(x int)
+repeat
+  insert into test.t1 values (repeat("b",3), x);
+  set x = x-1;
+until x = 0 end repeat|
+
+call b(3)|
+select * from t1|
+delete from t1|
+drop procedure b|
+
+
+# Check that repeat isn't parsed the wrong way
+--disable_warnings
+drop procedure if exists b2|
+--enable_warnings
+create procedure b2(x int)
+repeat(select 1 into outfile 'b2');
+  insert into test.t1 values (repeat("b2",3), x);
+  set x = x-1;
+until x = 0 end repeat|
+
+# We don't actually want to call it.
+drop procedure b2|
+
+
+# Labelled WHILE with ITERATE (pointless really)
+--disable_warnings
+drop procedure if exists c|
+--enable_warnings
+create procedure c(x int)
+hmm: while x > 0 do
+  insert into test.t1 values ("c", x);
+  set x = x-1;
+  iterate hmm;
+  insert into test.t1 values ("x", x);
+end while hmm|
+
+call c(3)|
+select * from t1|
+delete from t1|
+drop procedure c|
+
+
+# Labelled WHILE with LEAVE
+--disable_warnings
+drop procedure if exists d|
+--enable_warnings
+create procedure d(x int)
+hmm: while x > 0 do
+  insert into test.t1 values ("d", x);
+  set x = x-1;
+  leave hmm;
+  insert into test.t1 values ("x", x);
+end while|
+
+call d(3)|
+select * from t1|
+delete from t1|
+drop procedure d|
+
+
+# LOOP, with simple IF statement
+--disable_warnings
+drop procedure if exists e|
+--enable_warnings
+create procedure e(x int)
+foo: loop
+  if x = 0 then
+    leave foo;
+  end if;
+  insert into test.t1 values ("e", x);
+  set x = x-1;
+end loop foo|
+
+call e(3)|
+select * from t1|
+delete from t1|
+drop procedure e|
+
+
+# A full IF statement
+--disable_warnings
+drop procedure if exists f|
+--enable_warnings
+create procedure f(x int)
+if x < 0 then
+  insert into test.t1 values ("f", 0);
+elseif x = 0 then
+  insert into test.t1 values ("f", 1);
+else
+  insert into test.t1 values ("f", 2);
+end if|
+
+call f(-2)|
+call f(0)|
+call f(4)|
+select * from t1|
+delete from t1|
+drop procedure f|
+
+
+# This form of CASE is really just syntactic sugar for IF-ELSEIF-...
+--disable_warnings
+drop procedure if exists g|
+--enable_warnings
+create procedure g(x int)
+case
+when x < 0 then
+  insert into test.t1 values ("g", 0);
+when x = 0 then
+  insert into test.t1 values ("g", 1);
+else
+  insert into test.t1 values ("g", 2);
+end case|
+
+call g(-42)|
+call g(0)|
+call g(1)|
+select * from t1|
+delete from t1|
+drop procedure g|
+
+
+# The "simple CASE"
+--disable_warnings
+drop procedure if exists h|
+--enable_warnings
+create procedure h(x int)
+case x
+when 0 then
+  insert into test.t1 values ("h0", x);
+when 1 then
+  insert into test.t1 values ("h1", x);
+else
+  insert into test.t1 values ("h?", x);
+end case|
+
+call h(0)|
+call h(1)|
+call h(17)|
+select * from t1|
+delete from t1|
+drop procedure h|
+
+
+# It's actually possible to LEAVE a BEGIN-END block
+--disable_warnings
+drop procedure if exists i|
+--enable_warnings
+create procedure i(x int)
+foo:
+begin
+  if x = 0 then
+    leave foo;
+  end if;
+  insert into test.t1 values ("i", x);
+end foo|
+
+call i(0)|
+call i(3)|
+select * from t1|
+delete from t1|
+drop procedure i|
+
+
+# SELECT with one of more result set sent back to the clinet
+insert into t1 values ("foo", 3), ("bar", 19)|
+insert into t2 values ("x", 9, 4.1), ("y", -1, 19.2), ("z", 3, 2.2)|
+
+--disable_warnings
+drop procedure if exists sel1|
+--enable_warnings
+create procedure sel1()
+begin
+  select * from t1;
+end|
+
+call sel1()|
+drop procedure sel1|
+
+--disable_warnings
+drop procedure if exists sel2|
+--enable_warnings
+create procedure sel2()
+begin
+  select * from t1;
+  select * from t2;
+end|
+
+call sel2()|
+drop procedure sel2|
+delete from t1|
+delete from t2|
+
+# SELECT INTO local variables
+--disable_warnings
+drop procedure if exists into_test|
+--enable_warnings
+create procedure into_test(x char(16), y int)
+begin
+  insert into test.t1 values (x, y);
+  select id,data into x,y from test.t1 limit 1;
+  insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test("into", 100)|
+select * from t1|
+delete from t1|
+drop procedure into_test|
+
+
+# SELECT INTO with a mix of local and global variables
+--disable_warnings
+drop procedure if exists into_tes2|
+--enable_warnings
+create procedure into_test2(x char(16), y int)
+begin
+  insert into test.t1 values (x, y);
+  select id,data into x,@z from test.t1 limit 1;
+  insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+call into_test2("into", 100)|
+select id,data,@z from t1|
+delete from t1|
+drop procedure into_test2|
+
+
+# SELECT * INTO ... (bug test)
+--disable_warnings
+drop procedure if exists into_test3|
+--enable_warnings
+create procedure into_test3()
+begin
+  declare x char(16);
+  declare y int;
+
+  select * into x,y from test.t1 limit 1;
+  insert into test.t2 values (x, y, 0.0);
+end|
+
+insert into t1 values ("into3", 19)|
+# Two call needed for bug test
+call into_test3()|
+call into_test3()|
+select * from t2|
+delete from t1|
+delete from t2|
+drop procedure into_test3|
+
+
+# SELECT INTO with no data is a warning ("no data", which we will
+# not see normally). When not caught, execution proceeds.
+--disable_warnings
+drop procedure if exists into_test4|
+--enable_warnings
+create procedure into_test4()
+begin
+  declare x int;
+
+  select data into x from test.t1 limit 1;
+  insert into test.t3 values ("into4", x);
+end|
+
+delete from t1|
+create table t3 ( s char(16), d int)|
+call into_test4()|
+select * from t3|
+insert into t1 values ("i4", 77)|
+call into_test4()|
+select * from t3|
+delete from t1|
+drop table t3|
+drop procedure into_test4|
+
+
+# These two (and the two procedures above) caused an assert() to fail in
+# sql_base.cc:lock_tables() at some point.
+--disable_warnings
+drop procedure if exists into_outfile|
+--enable_warnings
+create procedure into_outfile(x char(16), y int)
+begin
+  insert into test.t1 values (x, y);
+  select * into outfile "../tmp/spout" from test.t1;
+  insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+--system rm -f $MYSQLTEST_VARDIR/tmp/spout
+call into_outfile("ofile", 1)|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spout
+delete from t1|
+drop procedure into_outfile|
+
+--disable_warnings
+drop procedure if exists into_dumpfile|
+--enable_warnings
+create procedure into_dumpfile(x char(16), y int)
+begin
+  insert into test.t1 values (x, y);
+  select * into dumpfile "../tmp/spdump" from test.t1 limit 1;
+  insert into test.t1 values (concat(x, "2"), y+2);
+end|
+
+--system rm -f $MYSQLTEST_VARDIR/tmp/spdump
+call into_dumpfile("dfile", 1)|
+--system rm -f $MYSQLTEST_VARDIR/tmp/spdump
+delete from t1|
+drop procedure into_dumpfile|
+
+--disable_warnings
+drop procedure if exists create_select|
+--enable_warnings
+create procedure create_select(x char(16), y int)
+begin
+  insert into test.t1 values (x, y);
+  create temporary table test.t3 select * from test.t1;
+  insert into test.t3 values (concat(x, "2"), y+2);
+end|
+
+call create_select("cs", 90)|
+select * from t1, t3|
+drop table t3|
+delete from t1|
+drop procedure create_select|
+
+
+# A minimal, constant FUNCTION.
+--disable_warnings
+drop function if exists e|
+--enable_warnings
+create function e() returns double
+  return 2.7182818284590452354|
+
+set @e = e()|
+select e(), @e|
+
+# A minimal function with one argument
+--disable_warnings
+drop function if exists inc|
+--enable_warnings
+create function inc(i int) returns int
+  return i+1|
+
+select inc(1), inc(99), inc(-71)|
+
+# A minimal function with two arguments
+--disable_warnings
+drop function if exists mul|
+--enable_warnings
+create function mul(x int, y int) returns int
+  return x*y|
+
+select mul(1,1), mul(3,5), mul(4711, 666)|
+
+# A minimal string function
+--disable_warnings
+drop function if exists append|
+--enable_warnings
+create function append(s1 char(8), s2 char(8)) returns char(16)
+  return concat(s1, s2)|
+
+select append("foo", "bar")|
+
+# A function with flow control
+--disable_warnings
+drop function if exists fac|
+--enable_warnings
+create function fac(n int unsigned) returns bigint unsigned
+begin
+  declare f bigint unsigned default 1;
+
+  while n > 1 do
+    set f = f * n;
+    set n = n - 1;
+  end while;
+  return f;
+end|
+
+select fac(1), fac(2), fac(5), fac(10)|
+
+# Nested calls
+--disable_warnings
+drop function if exists fun|
+--enable_warnings
+create function fun(d double, i int, u int unsigned) returns double
+  return mul(inc(i), fac(u)) / e()|
+
+select fun(2.3, 3, 5)|
+
+
+# Various function calls in differen statements
+
+insert into t2 values (append("xxx", "yyy"), mul(4,3), e())|
+insert into t2 values (append("a", "b"), mul(2,mul(3,4)), fun(1.7, 4, 6))|
+
+# Disable PS because double's give a bit different values
+--disable_ps_protocol
+select * from t2 where s = append("a", "b")|
+select * from t2 where i = mul(4,3) or i = mul(mul(3,4),2)|
+select * from t2 where d = e()|
+select * from t2|
+--enable_ps_protocol
+delete from t2|
+
+drop function e|
+drop function inc|
+drop function mul|
+drop function append|
+drop function fun|
+
+
+#
+# CONDITIONs and HANDLERs
+#
+
+--disable_warnings
+drop procedure if exists hndlr1|
+--enable_warnings
+create procedure hndlr1(val int)
+begin
+  declare x int default 0;
+  declare foo condition for 1136;
+  declare bar condition for sqlstate '42S98';        # Just for testing syntax
+  declare zip condition for sqlstate value '42S99';  # Just for testing syntax
+  declare continue handler for foo set x = 1;
+
+  insert into test.t1 values ("hndlr1", val, 2);  # Too many values
+  if (x) then
+    insert into test.t1 values ("hndlr1", val);   # This instead then
+  end if;
+end|
+
+call hndlr1(42)|
+select * from t1|
+delete from t1|
+drop procedure hndlr1|
+
+--disable_warnings
+drop procedure if exists hndlr2|
+--enable_warnings
+create procedure hndlr2(val int)
+begin
+  declare x int default 0;
+
+  begin
+    declare exit handler for sqlstate '21S01' set x = 1;
+
+    insert into test.t1 values ("hndlr2", val, 2); # Too many values
+  end;
+
+  insert into test.t1 values ("hndlr2", x);
+end|
+
+call hndlr2(42)|
+select * from t1|
+delete from t1|
+drop procedure hndlr2|
+
+
+--disable_warnings
+drop procedure if exists hndlr3|
+--enable_warnings
+create procedure hndlr3(val int)
+begin
+  declare x int default 0;
+  declare continue handler for sqlexception        # Any error
+  begin
+    declare z int;
+
+    set z = 2 * val;
+    set x = 1;
+  end;
+
+  if val < 10 then
+    begin
+      declare y int;
+
+      set y = val + 10;
+      insert into test.t1 values ("hndlr3", y, 2);  # Too many values
+      if x then
+        insert into test.t1 values ("hndlr3", y);
+      end if;
+    end;
+  end if;
+end|
+
+call hndlr3(3)|
+select * from t1|
+delete from t1|
+drop procedure hndlr3|
+
+
+# Variables might be uninitialized when using handlers
+# (Otherwise the compiler can detect if a variable is not set, but
+#  not in this case.)
+create table t3 ( id   char(16), data int )|
+
+--disable_warnings
+drop procedure if exists hndlr4|
+--enable_warnings
+create procedure hndlr4()
+begin
+  declare x int default 0;
+  declare val int;	                           # No default
+  declare continue handler for sqlstate '02000' set x=1;
+
+  select data into val from test.t3 where id='z' limit 1;  # No hits
+
+  insert into test.t3 values ('z', val);
+end|
+
+call hndlr4()|
+select * from t3|
+drop table t3|
+drop procedure hndlr4|
+
+
+#
+# Cursors
+#
+--disable_warnings
+drop procedure if exists cur1|
+--enable_warnings
+create procedure cur1()
+begin
+  declare a char(16);
+  declare b int;
+  declare c double;
+  declare done int default 0;
+  declare c cursor for select * from test.t2;
+  declare continue handler for sqlstate '02000' set done = 1;
+
+  open c;
+  repeat
+    fetch c into a, b, c;
+    if not done then
+       insert into test.t1 values (a, b+c);
+    end if;
+  until done end repeat;
+  close c;
+end|
+
+insert into t2 values ("foo", 42, -1.9), ("bar", 3, 12.1), ("zap", 666, -3.14)|
+call cur1()|
+select * from t1|
+drop procedure cur1|
+
+create table t3 ( s char(16), i int )|
+
+--disable_warnings
+drop procedure if exists cur2|
+--enable_warnings
+create procedure cur2()
+begin
+  declare done int default 0;
+  declare c1 cursor for select id,data from test.t1;
+  declare c2 cursor for select i from test.t2;
+  declare continue handler for sqlstate '02000' set done = 1;
+
+  open c1;
+  open c2;
+  repeat
+  begin
+    declare a char(16);
+    declare b,c int;
+
+    fetch from c1 into a, b;
+    fetch next from c2 into c;
+    if not done then
+      if b < c then
+        insert into test.t3 values (a, b);
+      else
+        insert into test.t3 values (a, c);
+      end if;
+    end if;
+  end;
+  until done end repeat;
+  close c1;
+  close c2;
+end|
+
+call cur2()|
+select * from t3|
+delete from t1|
+delete from t2|
+drop table t3|
+drop procedure cur2|
+
+
+# The few characteristics we parse
+--disable_warnings
+drop procedure if exists chistics|
+--enable_warnings
+create procedure chistics()
+    language sql
+    modifies sql data
+    not deterministic
+    sql security definer
+    comment 'Characteristics procedure test'
+  insert into t1 values ("chistics", 1)|
+
+show create procedure chistics|
+# Call it, just to make sure.
+call chistics()|
+select * from t1|
+delete from t1|
+alter procedure chistics sql security invoker|
+show create procedure chistics|
+drop procedure chistics|
+
+--disable_warnings
+drop function if exists chistics|
+--enable_warnings
+create function chistics() returns int
+    language sql
+    deterministic
+    sql security invoker
+    comment 'Characteristics procedure test'
+  return 42|
+
+show create function chistics|
+# Call it, just to make sure.
+select chistics()|
+alter function chistics
+   no sql
+   comment 'Characteristics function test'|
+show create function chistics|
+drop function chistics|
+
+
+# Check mode settings
+insert into t1 values ("foo", 1), ("bar", 2), ("zip", 3)|
+
+set @@sql_mode = 'ANSI'|
+delimiter $|
+--disable_warnings
+drop procedure if exists modes$
+--enable_warnings
+create procedure modes(out c1 int, out c2 int)
+begin
+  declare done int default 0;
+  declare x int;
+  declare c cursor for select data from t1;
+  declare continue handler for sqlstate '02000' set done = 1;
+
+  select 1 || 2 into c1;
+  set c2 = 0;
+  open c;
+  repeat
+    fetch c into x;
+    if not done then
+      set c2 = c2 + 1;
+    end if;
+  until done end repeat;
+  close c;
+end$
+delimiter |$
+set @@sql_mode = ''|
+
+set sql_select_limit = 1|
+call modes(@c1, @c2)|
+set sql_select_limit = default|
+
+select @c1, @c2|
+delete from t1|
+drop procedure modes|
+
+
+# Check that dropping a database without routines works.
+# (Dropping with routines is tested in sp-security.test)
+# First an empty db.
+create database sp_db1|
+drop database sp_db1|
+
+# Again, with a table.
+create database sp_db2|
+use sp_db2|
+# Just put something in here...
+create table t3 ( s char(4), t int )|
+insert into t3 values ("abcd", 42), ("dcba", 666)|
+use test|
+drop database sp_db2|
+
+# And yet again, with just a procedure.
+create database sp_db3|
+use sp_db3|
+--disable_warnings
+drop procedure if exists dummy|
+--enable_warnings
+create procedure dummy(out x int)
+  set x = 42|
+use test|
+drop database sp_db3|
+# Check that it's gone
+select type,db,name from mysql.proc where db = 'sp_db3'|
+
+
+# ROW_COUNT() function after a CALL
+# We test the other cases here too, although it's not strictly SP specific
+--disable_warnings
+drop procedure if exists rc|
+--enable_warnings
+create procedure rc()
+begin
+  delete from t1;
+  insert into t1 values ("a", 1), ("b", 2), ("c", 3);
+end|
+
+call rc()|
+select row_count()|
+--disable_ps_protocol
+update t1 set data=42 where id = "b";
+select row_count()|
+--enable_ps_protocol
+delete from t1|
+select row_count()|
+delete from t1|
+select row_count()|
+select * from t1|
+select row_count()|
+drop procedure rc|
+
+
+#
+# Let us test how well new locking scheme works.
+#
+
+# Let us prepare playground
+--disable_warnings
+drop function if exists f0|
+drop function if exists f1|
+drop function if exists f2|
+drop function if exists f3|
+drop function if exists f4|
+drop function if exists f5|
+drop function if exists f6|
+drop function if exists f7|
+drop function if exists f8|
+drop function if exists f9|
+drop function if exists f10|
+drop function if exists f11|
+drop function if exists f12_1|
+drop function if exists f12_2|
+drop view if exists v0|
+drop view if exists v1|
+drop view if exists v2|
+--enable_warnings
+delete from t1|
+delete from t2|
+insert into t1 values ("a", 1), ("b", 2) |
+insert into t2 values ("a", 1, 1.0), ("b", 2, 2.0), ("c", 3, 3.0) |
+
+# Test the simplest function using tables
+create function f1() returns int
+  return (select sum(data) from t1)|
+select f1()|
+# This should work too (and give 2 rows as result)
+select id, f1() from t1|
+
+# Function which uses two instances of table simultaneously
+create function f2() returns int
+  return (select data from t1 where data <= (select sum(data) from t1) limit 1)|
+select f2()|
+select id, f2() from t1|
+
+# Function which uses the same table twice in different queries
+create function f3() returns int
+begin
+  declare n int;
+  declare m int;
+  set n:= (select min(data) from t1);
+  set m:= (select max(data) from t1);
+  return n < m;
+end|
+select f3()|
+select id, f3() from t1|
+
+# Calling two functions using same table
+select f1(), f3()|
+select id, f1(), f3() from t1|
+
+# Function which uses two different tables
+create function f4() returns double 
+  return (select d from t1, t2 where t1.data = t2.i and t1.id= "b")|
+select f4()|
+select s, f4() from t2|
+
+# Recursive functions which due to this recursion require simultaneous
+# access to several instance of the same table won't work
+create function f5(i int) returns int
+begin
+  if i <= 0 then
+    return 0;
+  elseif i = 1  then
+    return (select count(*) from t1 where data = i);
+  else
+    return (select count(*) + f5( i - 1) from t1 where data = i);
+  end if;
+end|
+select f5(1)|
+# Since currently recursive functions are disallowed ER_SP_NO_RECURSION
+# error will be returned, once we will allow them error about
+# insufficient number of locked tables will be returned instead.
+--error ER_SP_NO_RECURSION
+select f5(2)|
+--error ER_SP_NO_RECURSION
+select f5(3)|
+
+# OTOH this should work 
+create function f6() returns int
+begin
+  declare n int;
+  set n:= f1();
+  return (select count(*) from t1 where data <= f7() and data <= n);
+end|
+create function f7() returns int
+  return (select sum(data) from t1 where data <= f1())|
+select f6()|
+select id, f6() from t1|
+
+#
+# Let us test how new locking work with views
+#
+# The most trivial view
+create view v1 (a) as select f1()|
+select * from v1|
+select id, a from t1, v1|
+select * from v1, v1 as v|
+# A bit more complex construction
+create view v2 (a) as select a*10 from v1|
+select * from v2|
+select id, a from t1, v2|
+select * from v1, v2|
+
+# Nice example where the same view is used on
+# on different expression levels
+create function f8 () returns int
+  return (select count(*) from v2)|
+
+select *, f8() from v1|
+
+# Let us test what will happen if function is missing
+drop function f1|
+--error 1356
+select * from v1|
+
+# And what will happen if we have recursion which involves
+# views and functions ?
+create function f1() returns int
+  return (select sum(data) from t1) + (select sum(data) from v1)|
+--error ER_SP_NO_RECURSION
+select f1()|
+--error ER_SP_NO_RECURSION
+select * from v1|
+--error ER_SP_NO_RECURSION
+select * from v2|
+# Back to the normal cases
+drop function f1|
+create function f1() returns int
+  return (select sum(data) from t1)|
+
+# Let us also test some weird cases where no real tables is used
+create function f0() returns int
+  return (select * from (select 100) as r)|
+select f0()|
+select *, f0() from (select 1) as t|
+create view v0 as select f0()|
+select * from v0|
+select *, f0() from v0|
+
+#
+# Let us test how well prelocking works with explicit LOCK TABLES.
+#
+lock tables t1 read, t1 as t11 read|
+# These should work well
+select f3()|
+select id, f3() from t1 as t11|
+# Degenerate cases work too :)
+select f0()|
+select * from v0|
+select *, f0() from v0, (select 123) as d1|
+# But these should not !
+--error 1100
+select id, f3() from t1|
+--error 1100
+select f4()|
+unlock tables|
+
+# Let us test how LOCK TABLES which implicitly depends on functions
+# works
+lock tables v2 read, mysql.proc read|
+select * from v2|
+select * from v1|
+# These should not work as we have too little instances of tables locked
+--error 1100
+select * from v1, t1|
+--error 1100
+select f4()|
+unlock tables|
+
+# Tests for handling of temporary tables in functions.
+#
+# Unlike for permanent tables we should be able to create, use
+# and drop such tables in functions.
+# 
+# Simplest function using temporary table. It is also test case for bug 
+# #12198 "Temporary table aliasing does not work inside stored functions"
+create function f9() returns int
+begin
+  declare a, b int;
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  set a:= (select count(*) from t3);
+  set b:= (select count(*) from t3 t3_alias);
+  return a + b;
+end|
+# This will emit warning as t3 was not existing before.
+select f9()|
+select f9() from t1 limit 1|
+
+# Function which uses both temporary and permanent tables.
+create function f10() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 select id from t4;
+  return (select count(*) from t3);
+end|
+# Check that we don't ignore completely tables used in function
+--error ER_NO_SUCH_TABLE
+select f10()|
+create table t4 as select 1 as id|
+select f10()|
+
+# Practical cases which we don't handle well (yet)
+#
+# Function which does not work because of well-known and documented
+# limitation of MySQL. We can't use the several instances of the
+# same temporary table in statement.
+create function f11() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  return (select count(*) from t3 as a, t3 as b);
+end|
+--error ER_CANT_REOPEN_TABLE
+select f11()|
+--error ER_CANT_REOPEN_TABLE
+select f11() from t1|
+# We don't handle temporary tables used by nested functions well
+create function f12_1() returns int
+begin
+  drop temporary table if exists t3;
+  create temporary table t3 (id int);
+  insert into t3 values (1), (2), (3);
+  return f12_2();
+end|
+create function f12_2() returns int
+  return (select count(*) from t3)|
+# We need clean start to get error
+drop temporary table t3|
+--error ER_NO_SUCH_TABLE
+select f12_1()|
+--error ER_NO_SUCH_TABLE
+select f12_1() from t1 limit 1|
+
+# Cleanup
+drop function f0|
+drop function f1|
+drop function f2|
+drop function f3|
+drop function f4|
+drop function f5|
+drop function f6|
+drop function f7|
+drop function f8|
+drop function f9|
+drop function f10|
+drop function f11|
+drop function f12_1|
+drop function f12_2|
+drop view v0|
+drop view v1|
+drop view v2|
+delete from t1 |
+delete from t2 |
+drop table t4|
+
+# End of non-bug tests
+
+
+#
+# Some "real" examples
+#
+
+# fac
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 (n int unsigned not null primary key, f bigint unsigned)|
+
+--disable_warnings
+drop procedure if exists ifac|
+--enable_warnings
+create procedure ifac(n int unsigned)
+begin
+  declare i int unsigned default 1;
+
+  if n > 20 then
+    set n = 20;		# bigint overflow otherwise
+  end if;
+  while i <= n do
+    begin
+      insert into test.t3 values (i, fac(i));
+      set i = i + 1;
+    end;
+  end while;
+end|
+
+call ifac(20)|
+select * from t3|
+drop table t3|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like '%f%'|
+drop procedure ifac|
+drop function fac|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show function status like '%f%'|
+
+
+# primes
+
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+
+create table t3 (
+  i int unsigned not null primary key,
+  p bigint unsigned not null
+)|
+
+insert into t3 values
+ ( 0,   3), ( 1,   5), ( 2,   7), ( 3,  11), ( 4,  13),
+ ( 5,  17), ( 6,  19), ( 7,  23), ( 8,  29), ( 9,  31),
+ (10,  37), (11,  41), (12,  43), (13,  47), (14,  53),
+ (15,  59), (16,  61), (17,  67), (18,  71), (19,  73),
+ (20,  79), (21,  83), (22,  89), (23,  97), (24, 101),
+ (25, 103), (26, 107), (27, 109), (28, 113), (29, 127),
+ (30, 131), (31, 137), (32, 139), (33, 149), (34, 151),
+ (35, 157), (36, 163), (37, 167), (38, 173), (39, 179),
+ (40, 181), (41, 191), (42, 193), (43, 197), (44, 199)|
+
+--disable_warnings
+drop procedure if exists opp|
+--enable_warnings
+create procedure opp(n bigint unsigned, out pp bool)
+begin
+  declare r double;
+  declare b, s bigint unsigned default 0;
+
+  set r = sqrt(n);
+
+ again:
+  loop
+    if s = 45 then
+      set b = b+200, s = 0;
+    else
+      begin
+        declare p bigint unsigned;
+
+        select t.p into p from test.t3 t where t.i = s;
+        if b+p > r then
+          set pp = 1;
+          leave again;
+        end if;
+        if mod(n, b+p) = 0 then
+          set pp = 0;
+          leave again;
+        end if;
+        set s = s+1;
+      end;
+    end if;
+  end loop;
+end|
+
+--disable_warnings
+drop procedure if exists ip|
+--enable_warnings
+create procedure ip(m int unsigned)
+begin
+  declare p bigint unsigned;
+  declare i int unsigned;
+
+  set i=45, p=201;
+
+  while i < m do
+    begin
+      declare pp bool default 0;
+
+      call opp(p, pp);
+      if pp then
+        insert into test.t3 values (i, p);
+        set i = i+1;
+      end if;
+      set p = p+2;
+    end;
+  end while;
+end|
+show create procedure opp|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like '%p%'|
+
+# This isn't the fastest way in the world to compute prime numbers, so
+# don't be too ambitious. ;-)
+call ip(200)|
+# We don't want to select the entire table here, just pick a few
+# examples.
+# The expected result is:
+#    i      p
+#   ---   ----
+#    45    211
+#   100    557
+#   199   1229
+select * from t3 where i=45 or i=100 or i=199|
+drop table t3|
+drop procedure opp|
+drop procedure ip|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like '%p%'|
+
+
+# Fibonacci, for recursion test. (Yet Another Numerical series :)
+#
+--disable_warnings
+drop table if exists t3|
+--enable_warnings
+create table t3 ( f bigint unsigned not null )|
+
+# We deliberately do it the awkward way, fetching the last two
+# values from the table, in order to exercise various statements
+# and table accesses at each turn.
+--disable_warnings
+drop procedure if exists fib|
+--enable_warnings
+create procedure fib(n int unsigned)
+begin
+  if n > 1 then
+    begin
+      declare x, y bigint unsigned;
+      declare c cursor for select f from t3 order by f desc limit 2;
+
+      open c;
+      fetch c into y;
+      fetch c into x;
+      close c;
+      insert into t3 values (x+y);
+      call fib(n-1);
+    end;
+  end if;
+end|
+
+# Enable recursion
+set @@max_sp_recursion_depth= 20|
+
+# Minimum test: recursion of 3 levels
+
+insert into t3 values (0), (1)|
+
+call fib(3)|
+
+select * from t3 order by f asc|
+
+delete from t3|
+
+# The original test, 20 levels, ran into memory limits on some machines
+# and builds. Try 10 instead...
+
+insert into t3 values (0), (1)|
+
+call fib(10)|
+
+select * from t3 order by f asc|
+drop table t3|
+drop procedure fib|
+set @@max_sp_recursion_depth= 0|
+
+#
+# Comment & suid
+#
+
+--disable_warnings
+drop procedure if exists bar|
+--enable_warnings
+create procedure bar(x char(16), y int)
+ comment "111111111111" sql security invoker
+ insert into test.t1 values (x, y)|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'bar'|
+alter procedure bar comment "2222222222" sql security definer|
+alter procedure bar comment "3333333333"|
+alter procedure bar|
+show create procedure bar|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+show procedure status like 'bar'|
+drop procedure bar|
+
+#
+# rexecution
+#
+--disable_warnings
+drop procedure if exists p1|
+--enable_warnings
+create procedure p1 ()
+  select (select s1 from t3) from t3|
+
+create table t3 (s1 int)|
+
+call p1()|
+insert into t3 values (1)|
+call p1()|
+drop procedure p1|
+drop table t3|
+
+#
+# backticks
+#
+--disable_warnings
+drop function if exists foo|
+--enable_warnings
+create function `foo` () returns int
+  return 5|
+select `foo` ()|
+drop function `foo`|
+
+#
+# Implicit LOCK/UNLOCK TABLES for table access in functions
+#
+
+--disable_warnings
+drop function if exists t1max|
+--enable_warnings
+create function t1max() returns int
+begin
+  declare x int;
+  select max(data) into x from t1;
+  return x;
+end|
+
+insert into t1 values ("foo", 3), ("bar", 2), ("zip", 5), ("zap", 1)|
+select t1max()|
+drop function t1max|
+
+create table t3 (
+  v char(16) not null primary key,
+  c int unsigned not null
+)|
+
+create function getcount(s char(16)) returns int
+begin
+  declare x int;
+
+  select count(*) into x from t3 where v = s;
+  if x = 0 then
+    insert into t3 values (s, 1);
+  else
+    update t3 set c = c+1 where v = s;
+  end if;
+  return x;
+end|
+
+select * from t1 where data = getcount("bar")|
+select * from t3|
+select getcount("zip")|
+select getcount("zip")|
+select * from t3|
+select getcount(id) from t1 where data = 3|
+select getcount(id) from t1 where data = 5|
+select * from t3|
+drop table t3|
+drop function getcount|
+
+
+# Test cases for different combinations of condition handlers in nested
+# begin-end blocks in stored procedures.
+#
+# Note that the standard specifies that the most specific handler should
+# be triggered even if it's an outer handler masked by a less specific
+# handler in an inner block.
+# Note also that '02000' is more specific than NOT FOUND; there might be
+# other '02xxx' states, even if we currently do not issue them in any
+# situation (e.g. '02001').
+#
+# The combinations we test are these:
+#
+#                                         Inner
+#              errcode      sqlstate     not found    sqlwarning   sqlexception
+#  Outer      +------------+------------+------------+------------+------------+
+#errcode      | h_ee (i)   | h_es (o)   | h_en (o)   | h_ew (o)   | h_ex (o)   |
+#sqlstate     | h_se (i)   | h_ss (i)   | h_sn (o)   | h_sw (o)   | h_sx (o)   |
+#not found    | h_ne (i)   | h_ns (i)   | h_nn (i)   |            |            |
+#sqlwarning   | h_we (i)   | h_ws (i)   |            | h_ww (i)   |            |
+#sqlexception | h_xe (i)   | h_xs (i)   |            |            | h_xx (i)   |
+#             +------------+---------------------------------------------------+
+#
+# (i) means that the inner handler is the one that should be invoked,
+# (o) means that the outer handler should be invoked.
+#
+# ('not found', 'sqlwarning' and 'sqlexception' are mutually exclusive, hence
+#  no tests for those combinations.)
+#
+
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists h_ee|
+drop procedure if exists h_es|
+drop procedure if exists h_en|
+drop procedure if exists h_ew|
+drop procedure if exists h_ex|
+drop procedure if exists h_se|
+drop procedure if exists h_ss|
+drop procedure if exists h_sn|
+drop procedure if exists h_sw|
+drop procedure if exists h_sx|
+drop procedure if exists h_ne|
+drop procedure if exists h_ns|
+drop procedure if exists h_nn|
+drop procedure if exists h_we|
+drop procedure if exists h_ws|
+drop procedure if exists h_ww|
+drop procedure if exists h_xe|
+drop procedure if exists h_xs|
+drop procedure if exists h_xx|
+--enable_warnings
+
+# smallint    - to get out of range warnings
+# primary key - to get constraint errors
+create table t3 (a smallint primary key)|
+
+insert into t3 (a) values (1)|
+
+create procedure h_ee()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (bad)' as 'h_ee';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+        select 'Inner (good)' as 'h_ee';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_es()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (good)' as 'h_es';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000'
+      select 'Inner (bad)' as 'h_es';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_en()
+    deterministic
+begin
+  declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+    select 'Outer (good)' as 'h_en';
+
+  begin
+    declare x int;
+    declare continue handler for sqlstate '02000' -- no data
+      select 'Inner (bad)' as 'h_en';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_ew()
+    deterministic
+begin
+  declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+    select 'Outer (good)' as 'h_ew';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (bad)' as 'h_ew';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ex()
+    deterministic
+begin
+  declare continue handler for 1062 -- ER_DUP_ENTRY
+    select 'Outer (good)' as 'h_ex';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (bad)' as 'h_ex';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_se()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (bad)' as 'h_se';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+      select 'Inner (good)' as 'h_se';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_ss()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (bad)' as 'h_ss';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000' 
+      select 'Inner (good)' as 'h_ss';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_sn()
+    deterministic
+begin
+  -- Note: '02000' is more specific than NOT FOUND ;
+  --       there might be other not found states 
+  declare continue handler for sqlstate '02000' -- no data
+    select 'Outer (good)' as 'h_sn';
+
+  begin
+    declare x int;
+    declare continue handler for not found
+      select 'Inner (bad)' as 'h_sn';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_sw()
+    deterministic
+begin
+  -- data exception - numeric value out of range
+  declare continue handler for sqlstate '22003'
+    select 'Outer (good)' as 'h_sw';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (bad)' as 'h_sw';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_sx()
+    deterministic
+begin
+  -- integrity constraint violation
+  declare continue handler for sqlstate '23000' 
+    select 'Outer (good)' as 'h_sx';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (bad)' as 'h_sx';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_ne()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_ne';
+
+  begin
+    declare x int;
+    declare continue handler for 1329 -- ER_SP_FETCH_NO_DATA
+      select 'Inner (good)' as 'h_ne';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_ns()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_ns';
+
+  begin
+    declare x int;
+    declare continue handler for sqlstate '02000' -- no data
+      select 'Inner (good)' as 'h_ns';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_nn()
+    deterministic
+begin
+  declare continue handler for not found
+    select 'Outer (bad)' as 'h_nn';
+
+  begin
+    declare x int;
+    declare continue handler for not found
+      select 'Inner (good)' as 'h_nn';
+
+    select a into x from t3 where a = 42;
+  end;
+end|
+
+create procedure h_we()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_we';
+
+  begin
+    declare continue handler for 1264 -- ER_WARN_DATA_OUT_OF_RANGE
+      select 'Inner (good)' as 'h_we';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ws()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_ws';
+
+  begin
+    -- data exception - numeric value out of range
+    declare continue handler for sqlstate '22003'
+      select 'Inner (good)' as 'h_ws';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_ww()
+    deterministic
+begin
+  declare continue handler for sqlwarning
+    select 'Outer (bad)' as 'h_ww';
+
+  begin
+    declare continue handler for sqlwarning
+      select 'Inner (good)' as 'h_ww';
+
+    insert into t3 values (123456789012);
+  end;
+  delete from t3;
+  insert into t3 values (1);
+end|
+
+create procedure h_xe()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xe';
+
+  begin
+    declare continue handler for 1062 -- ER_DUP_ENTRY
+      select 'Inner (good)' as 'h_xe';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_xs()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xs';
+
+  begin
+    -- integrity constraint violation
+    declare continue handler for sqlstate '23000'
+      select 'Inner (good)' as 'h_xs';
+
+    insert into t3 values (1);
+  end;
+end|
+
+create procedure h_xx()
+    deterministic
+begin
+  declare continue handler for sqlexception
+    select 'Outer (bad)' as 'h_xx';
+
+  begin
+    declare continue handler for sqlexception
+      select 'Inner (good)' as 'h_xx';
+
+    insert into t3 values (1);
+  end;
+end|
+
+call h_ee()|
+call h_es()|
+call h_en()|
+call h_ew()|
+call h_ex()|
+call h_se()|
+call h_ss()|
+call h_sn()|
+call h_sw()|
+call h_sx()|
+call h_ne()|
+call h_ns()|
+call h_nn()|
+call h_we()|
+call h_ws()|
+call h_ww()|
+call h_xe()|
+call h_xs()|
+call h_xx()|
+
+drop table t3|
+drop procedure h_ee|
+drop procedure h_es|
+drop procedure h_en|
+drop procedure h_ew|
+drop procedure h_ex|
+drop procedure h_se|
+drop procedure h_ss|
+drop procedure h_sn|
+drop procedure h_sw|
+drop procedure h_sx|
+drop procedure h_ne|
+drop procedure h_ns|
+drop procedure h_nn|
+drop procedure h_we|
+drop procedure h_ws|
+drop procedure h_ww|
+drop procedure h_xe|
+drop procedure h_xs|
+drop procedure h_xx|
+
+
+#
+# Test cases for old bugs
+#
+
+#
+# BUG#822
+#
+--disable_warnings
+drop procedure if exists bug822|
+--enable_warnings
+create procedure bug822(a_id char(16), a_data int)
+begin
+  declare n int;
+  select count(*) into n from t1 where id = a_id and data = a_data;
+  if n = 0 then
+    insert into t1 (id, data) values (a_id, a_data);
+  end if;
+end|
+
+delete from t1|
+call bug822('foo', 42)|
+call bug822('foo', 42)|
+call bug822('bar', 666)|
+select * from t1|
+delete from t1|
+drop procedure bug822|
+
+#
+# BUG#1495
+#
+--disable_warnings
+drop procedure if exists bug1495|
+--enable_warnings
+create procedure bug1495()
+begin
+  declare x int;
+
+  select data into x from t1 order by id limit 1;
+  if x > 10 then
+    insert into t1 values ("less", x-10);
+  else
+    insert into t1 values ("more", x+10);
+  end if;
+end|
+
+insert into t1 values ('foo', 12)|
+call bug1495()|
+delete from t1 where id='foo'|
+insert into t1 values ('bar', 7)|
+call bug1495()|
+delete from t1 where id='bar'|
+select * from t1|
+delete from t1|
+drop procedure bug1495|
+
+#
+# BUG#1547
+#
+--disable_warnings
+drop procedure if exists bug1547|
+--enable_warnings
+create procedure bug1547(s char(16))
+begin
+  declare x int;
+
+  select data into x from t1 where s = id limit 1;
+  if x > 10 then
+    insert into t1 values ("less", x-10);
+  else
+    insert into t1 values ("more", x+10);
+  end if;
+end|
+
+insert into t1 values ("foo", 12), ("bar", 7)|
+call bug1547("foo")|
+call bug1547("bar")|
+select * from t1|
+delete from t1|
+drop procedure bug1547|
+
+#
+# BUG#1656
+#
+--disable_warnings
+drop table if exists t70|
+--enable_warnings
+create table t70 (s1 int,s2 int)|
+insert into t70 values (1,2)|
+
+--disable_warnings
+drop procedure if exists bug1656|
+--enable_warnings
+create procedure bug1656(out p1 int, out p2 int)
+  select * into p1, p1 from t70|
+
+call bug1656(@1, @2)|
+select @1, @2|
+drop table t70|
+drop procedure bug1656|
+
+#
+# BUG#1862
+#
+create table t3(a int)|
+
+--disable_warnings
+drop procedure if exists bug1862|
+--enable_warnings
+create procedure bug1862()
+begin
+  insert into t3 values(2);    
+  flush tables;
+end|
+
+call bug1862()|
+# the second call caused a segmentation
+call bug1862()|
+select * from t3|
+drop table t3|
+drop procedure bug1862|
+
+#
+# BUG#1874
+#
+--disable_warnings
+drop procedure if exists bug1874|
+--enable_warnings
+create procedure bug1874()
+begin
+  declare x int;
+  declare y double;
+  select max(data) into x from t1;
+  insert into t2 values ("max", x, 0);
+  select min(data) into x from t1;
+  insert into t2 values ("min", x, 0);
+  select sum(data) into x from t1;
+  insert into t2 values ("sum", x, 0);
+  select avg(data) into y from t1;
+  insert into t2 values ("avg", 0, y);
+end|
+
+insert into t1 (data) values (3), (1), (5), (9), (4)|
+call bug1874()|
+select * from t2|
+delete from t1|
+delete from t2|
+drop procedure bug1874|
+
+#
+# BUG#2260
+#
+--disable_warnings
+drop procedure if exists bug2260|
+--enable_warnings
+create procedure bug2260()
+begin
+  declare v1 int;
+  declare c1 cursor for select data from t1;
+  declare continue handler for not found set @x2 = 1;
+
+  open c1;
+  fetch c1 into v1;
+  set @x2 = 2;
+  close c1;
+end|
+
+call bug2260()|
+select @x2|
+drop procedure bug2260|
+
+#
+# BUG#2267 "Lost connect if stored procedure has SHOW FUNCTION STATUS"
+#
+--disable_warnings
+drop procedure if exists bug2267_1|
+--enable_warnings
+create procedure bug2267_1()
+begin
+  show procedure status;
+end|
+
+--disable_warnings
+drop procedure if exists bug2267_2|
+--enable_warnings
+create procedure bug2267_2()
+begin
+  show function status;
+end|
+
+--disable_warnings
+drop procedure if exists bug2267_3|
+--enable_warnings
+create procedure bug2267_3()
+begin
+  show create procedure bug2267_1;
+end|
+
+--disable_warnings
+drop procedure if exists bug2267_4|
+drop function if exists bug2267_4|
+--enable_warnings
+create procedure bug2267_4()
+begin
+  show create function bug2267_4;
+end|
+create function bug2267_4() returns int return 100|
+
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+call bug2267_1()|
+--replace_column 5 '0000-00-00 00:00:00' 6 '0000-00-00 00:00:00'
+call bug2267_2()|
+call bug2267_3()|
+call bug2267_4()|
+
+drop procedure bug2267_1|
+drop procedure bug2267_2|
+drop procedure bug2267_3|
+drop procedure bug2267_4|
+drop function bug2267_4|
+
+#
+# BUG#2227
+#
+--disable_warnings
+drop procedure if exists bug2227|
+--enable_warnings
+create procedure bug2227(x int)
+begin
+  declare y float default 2.6;
+  declare z char(16) default "zzz";
+
+  select 1.3, x, y, 42, z;
+end|
+
+call bug2227(9)|
+drop procedure bug2227|
+
+#
+# BUG#2614 "Stored procedure with INSERT ... SELECT that does not
+#           contain any tables crashes server"
+#
+--disable_warnings
+drop procedure if exists bug2614|
+--enable_warnings
+create procedure bug2614()
+begin
+  drop table if exists t3;
+  create table t3 (id int default '0' not null);
+  insert into t3 select 12;
+  insert into t3 select * from t3;
+end|
+
+--disable_warnings
+call bug2614()|
+--enable_warnings
+call bug2614()|
+drop table t3|
+drop procedure bug2614|
+
+#
+# BUG#2674
+#
+--disable_warnings
+drop function if exists bug2674|
+--enable_warnings
+create function bug2674() returns int
+  return @@sort_buffer_size|
+
+set @osbs = @@sort_buffer_size|
+set @@sort_buffer_size = 262000|
+select bug2674()|
+drop function bug2674|
+set @@sort_buffer_size = @osbs|
+
+#
+# BUG#3259
+#
+--disable_warnings
+drop procedure if exists bug3259_1 |
+--enable_warnings
+create procedure bug3259_1 () begin end|
+--disable_warnings
+drop procedure if exists BUG3259_2 |
+--enable_warnings
+create procedure BUG3259_2 () begin end|
+--disable_warnings
+drop procedure if exists Bug3259_3 |
+--enable_warnings
+create procedure Bug3259_3 () begin end|
+
+call BUG3259_1()|
+call BUG3259_1()|
+call bug3259_2()|
+call Bug3259_2()|
+call bug3259_3()|
+call bUG3259_3()|
+
+drop procedure bUg3259_1|
+drop procedure BuG3259_2|
+drop procedure BUG3259_3|
+
+#
+# BUG#2772
+#
+--disable_warnings
+drop function if exists bug2772|
+--enable_warnings
+create function bug2772() returns char(10) character set latin2
+  return 'a'|
+
+select bug2772()|
+drop function bug2772|
+
+#
+# BUG#2776
+#
+--disable_warnings
+drop procedure if exists bug2776_1|
+--enable_warnings
+create procedure bug2776_1(out x int)
+begin
+  declare v int;
+
+  set v = default;
+  set x = v;
+end|
+
+--disable_warnings
+drop procedure if exists bug2776_2|
+--enable_warnings
+create procedure bug2776_2(out x int)
+begin
+  declare v int default 42;
+
+  set v = default;
+  set x = v;
+end|
+
+set @x = 1|
+call bug2776_1(@x)|
+select @x|
+call bug2776_2(@x)|
+select @x|
+drop procedure bug2776_1|
+drop procedure bug2776_2|
+
+#
+# BUG#2780
+#
+create table t3 (s1 smallint)|
+
+insert into t3 values (123456789012)|
+
+--disable_warnings
+drop procedure if exists bug2780|
+--enable_warnings
+create procedure bug2780()
+begin
+  declare exit handler for sqlwarning set @x = 1; 
+
+  set @x = 0;
+  insert into t3 values (123456789012);
+  insert into t3 values (0);
+end|
+
+call bug2780()|
+select @x|
+select * from t3|
+
+drop procedure bug2780|
+drop table t3|
+
+#
+# BUG#1863
+#
+create table t3 (content varchar(10) )|
+insert into t3 values ("test1")|
+insert into t3 values ("test2")|
+create table t4 (f1 int, rc int, t3 int)|
+
+--disable_warnings
+drop procedure if exists bug1863|
+--enable_warnings
+create procedure bug1863(in1 int)
+begin 
+
+  declare ind int default 0;
+  declare t1 int;
+  declare t2 int;
+  declare t3 int;
+
+  declare rc int default 0;
+  declare continue handler for 1065 set rc = 1;
+
+  drop temporary table if exists temp_t1;
+  create temporary table temp_t1 (
+    f1 int auto_increment, f2 varchar(20), primary key (f1)
+  );
+
+  insert into temp_t1 (f2) select content from t3;
+
+  select f2 into t3 from temp_t1 where f1 = 10;
+
+  if (rc) then
+       insert into t4 values (1, rc, t3);
+  end if;
+
+  insert into t4 values (2, rc, t3);
+
+end|
+
+call bug1863(10)|
+call bug1863(10)|
+select * from t4|
+
+drop procedure bug1863|
+drop temporary table temp_t1;
+drop table t3, t4|
+
+#
+# BUG#2656
+#
+
+create table t3 ( 
+  OrderID  int not null,
+  MarketID int,
+  primary key (OrderID)
+)|
+
+create table t4 ( 
+  MarketID int not null,
+  Market varchar(60),
+  Status char(1),
+  primary key (MarketID)
+)|
+
+insert t3 (OrderID,MarketID) values (1,1)|
+insert t3 (OrderID,MarketID) values (2,2)|
+insert t4 (MarketID,Market,Status) values (1,"MarketID One","A")|
+insert t4 (MarketID,Market,Status) values (2,"MarketID Two","A")|
+
+--disable_warnings
+drop procedure if exists bug2656_1|
+--enable_warnings
+create procedure bug2656_1()
+begin 
+  select
+    m.Market
+  from  t4 m JOIN t3 o 
+        ON o.MarketID != 1 and o.MarketID = m.MarketID;
+end |
+
+--disable_warnings
+drop procedure if exists bug2656_2|
+--enable_warnings
+create procedure bug2656_2()
+begin 
+  select
+    m.Market
+  from  
+    t4 m, t3 o
+  where       
+    m.MarketID != 1 and m.MarketID = o.MarketID;
+        
+end |
+
+call bug2656_1()|
+call bug2656_1()|
+call bug2656_2()|
+call bug2656_2()|
+drop procedure bug2656_1|
+drop procedure bug2656_2|
+drop table t3, t4|
+
+
+#
+# BUG#3426
+#
+--disable_warnings
+drop procedure if exists bug3426|
+--enable_warnings
+create procedure bug3426(in_time int unsigned, out x int)
+begin
+  if in_time is null then
+    set @stamped_time=10;
+    set x=1;
+  else
+    set @stamped_time=in_time;
+    set x=2;
+  end if;
+end|
+
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+# Clear SP cache
+alter procedure bug3426 sql security invoker|
+call bug3426(NULL, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+call bug3426(1000, @i)|
+select @i, from_unixtime(@stamped_time, '%d-%m-%Y %h:%i:%s') as time|
+
+drop procedure bug3426|
+
+#
+# BUG#3448
+#
+--disable_warnings
+create table t3 (
+  a int primary key, 
+  ach char(1)
+) engine = innodb|
+
+create table t4 (
+  b int  primary key , 
+  bch char(1)
+) engine = innodb|
+--enable_warnings
+
+insert into t3 values (1 , 'aCh1' ) , ('2' , 'aCh2')|
+insert into t4 values (1 , 'bCh1' )|
+
+--disable_warnings
+drop procedure if exists bug3448|
+--enable_warnings
+create procedure bug3448()
+  select * from t3 inner join t4 on t3.a = t4.b|
+
+select * from t3 inner join t4 on t3.a = t4.b|
+call bug3448()|
+call bug3448()|
+
+drop procedure bug3448|
+drop table t3, t4|
+
+
+#
+# BUG#3734
+#
+create table t3 (
+  id int unsigned auto_increment not null primary key,
+  title VARCHAR(200),
+  body text,
+  fulltext (title,body)
+)|
+
+insert into t3 (title,body) values
+  ('MySQL Tutorial','DBMS stands for DataBase ...'),
+  ('How To Use MySQL Well','After you went through a ...'),
+  ('Optimizing MySQL','In this tutorial we will show ...'),
+  ('1001 MySQL Tricks','1. Never run mysqld as root. 2. ...'),
+  ('MySQL vs. YourSQL','In the following database comparison ...'),
+  ('MySQL Security','When configured properly, MySQL ...')|
+
+--disable_warnings
+drop procedure if exists bug3734 |
+--enable_warnings
+create procedure bug3734 (param1 varchar(100))
+  select * from t3 where match (title,body) against (param1)|
+
+call bug3734('database')|
+call bug3734('Security')|
+
+drop procedure bug3734|
+drop table t3|
+
+#
+# BUG#3863
+#
+--disable_warnings
+drop procedure if exists bug3863|
+--enable_warnings
+create procedure bug3863()
+begin
+  set @a = 0;
+  while @a < 5 do
+    set @a = @a + 1;
+  end while;
+end|
+
+call bug3863()|
+select @a|
+call bug3863()|
+select @a|
+
+drop procedure bug3863|
+
+#
+# BUG#2460
+#
+
+create table t3 (
+  id int(10) unsigned not null default 0,
+  rid int(10) unsigned not null default 0,
+  msg text not null,
+  primary key (id),
+  unique key rid (rid, id)
+)|
+
+--disable_warnings
+drop procedure if exists bug2460_1|
+--enable_warnings
+create procedure bug2460_1(in v int)
+begin
+    ( select n0.id from t3 as n0 where n0.id = v )
+  union
+    ( select n0.id from t3 as n0, t3 as n1
+        where n0.id = n1.rid and n1.id = v )
+  union
+    ( select n0.id from t3 as n0, t3 as n1, t3 as n2
+        where n0.id = n1.rid and n1.id = n2.rid and n2.id = v );
+end|
+
+call bug2460_1(2)|
+call bug2460_1(2)|
+insert into t3 values (1, 1, 'foo'), (2, 1, 'bar'), (3, 1, 'zip zap')|
+call bug2460_1(2)|
+call bug2460_1(2)|
+
+--disable_warnings
+drop procedure if exists bug2460_2|
+--enable_warnings
+create procedure bug2460_2()
+begin
+  drop table if exists t3;
+  create temporary table t3 (s1 int);
+  insert into t3 select 1 union select 1;
+end|
+
+call bug2460_2()|
+call bug2460_2()|
+select * from t3|
+
+drop procedure bug2460_1|
+drop procedure bug2460_2|
+drop table t3|
+
+
+#
+# BUG#2564
+#
+set @@sql_mode = ''|
+--disable_warnings
+drop procedure if exists bug2564_1|
+--enable_warnings
+create procedure bug2564_1()
+    comment 'Joe''s procedure'
+  insert into `t1` values ("foo", 1)|
+
+set @@sql_mode = 'ANSI_QUOTES'|
+--disable_warnings
+drop procedure if exists bug2564_2|
+--enable_warnings
+create procedure bug2564_2()
+  insert into "t1" values ('foo', 1)|
+
+delimiter $|
+set @@sql_mode = ''$
+--disable_warnings
+drop function if exists bug2564_3$
+--enable_warnings
+create function bug2564_3(x int, y int) returns int
+  return x || y$
+
+set @@sql_mode = 'ANSI'$
+--disable_warnings
+drop function if exists bug2564_4$
+--enable_warnings
+create function bug2564_4(x int, y int) returns int
+  return x || y$
+delimiter |$
+
+set @@sql_mode = ''|
+show create procedure bug2564_1|
+show create procedure bug2564_2|
+show create function bug2564_3|
+show create function bug2564_4|
+
+drop procedure bug2564_1|
+drop procedure bug2564_2|
+drop function bug2564_3|
+drop function bug2564_4|
+
+#
+# BUG#3132
+#
+--disable_warnings
+drop function if exists bug3132|
+--enable_warnings
+create function bug3132(s char(20)) returns char(50)
+  return concat('Hello, ', s, '!')|
+
+select bug3132('Bob') union all select bug3132('Judy')|
+drop function bug3132|
+
+#
+# BUG#3843
+#
+--disable_warnings
+drop procedure if exists bug3843|
+--enable_warnings
+create procedure bug3843()
+  analyze table t1|
+
+# Testing for packets out of order
+call bug3843()|
+call bug3843()|
+select 1+2|
+
+drop procedure bug3843|
+
+#
+# BUG#3368
+#
+create table t3 ( s1 char(10) )|
+insert into t3 values ('a'), ('b')|
+
+--disable_warnings
+drop procedure if exists bug3368|
+--enable_warnings
+create procedure bug3368(v char(10))
+begin
+  select group_concat(v) from t3;
+end|
+
+call bug3368('x')|
+call bug3368('yz')|
+drop procedure bug3368|
+drop table t3|
+
+#
+# BUG#4579
+#
+create table t3 (f1 int, f2 int)|
+insert into t3 values (1,1)|
+
+--disable_warnings
+drop procedure if exists bug4579_1|
+--enable_warnings
+create procedure bug4579_1 ()
+begin
+  declare sf1 int;
+
+  select f1 into sf1 from t3 where f1=1 and f2=1;
+  update t3 set f2 = f2 + 1 where f1=1 and f2=1;
+  call bug4579_2();
+end|
+
+--disable_warnings
+drop procedure if exists bug4579_2|
+--enable_warnings
+create procedure bug4579_2 ()
+begin
+end|
+
+call bug4579_1()|
+call bug4579_1()|
+call bug4579_1()|
+
+drop procedure bug4579_1|
+drop procedure bug4579_2|
+drop table t3|
+
+#
+# BUG#2773: Function's data type ignored in stored procedures
+#
+--disable_warnings
+drop procedure if exists bug2773|
+--enable_warnings
+
+create function bug2773() returns int return null|
+create table t3 as select bug2773()|
+show create table t3|
+drop table t3|
+drop function bug2773|
+
+#
+# BUG#3788: Stored procedure packet error
+#
+--disable_warnings
+drop procedure if exists bug3788|
+--enable_warnings
+
+create function bug3788() returns date return cast("2005-03-04" as date)|
+select bug3788()|
+drop function bug3788|
+
+create function bug3788() returns binary(1) return 5|
+select bug3788()|
+drop function bug3788|
+ 
+
+#
+# BUG#4726
+#
+create table t3 (f1 int, f2 int, f3 int)|
+insert into t3 values (1,1,1)|
+
+--disable_warnings
+drop procedure if exists bug4726|
+--enable_warnings
+create procedure bug4726()
+begin
+   declare tmp_o_id INT;
+   declare tmp_d_id INT default 1;
+
+   while tmp_d_id <= 2 do
+   begin
+     select f1 into tmp_o_id from t3 where f2=1 and f3=1;
+     set tmp_d_id = tmp_d_id + 1;
+   end;
+   end while;
+end|
+
+call bug4726()|
+call bug4726()|
+call bug4726()|
+
+drop procedure bug4726|
+drop table t3|
+
+#
+# BUG#4318
+#
+
+--disable_parsing # Don't know if HANDLER commands can work with SPs, or at all..
+create table t3 (s1 int)|
+insert into t3 values (3), (4)|
+
+--disable_warnings
+drop procedure if exists bug4318|
+--enable_warnings
+create procedure bug4318()
+  handler t3 read next|
+
+handler t3 open|
+# Expect no results, as tables are closed, but there shouldn't be any errors
+call bug4318()|
+call bug4318()|
+handler t3 close|
+
+drop procedure bug4318|
+drop table t3|
+--enable_parsing
+
+#
+# BUG#4902: Stored procedure with SHOW WARNINGS leads to packet error
+#
+# Added tests for most other show commands we could find too.
+# (Skipping those already tested, and the ones depending on optional handlers.)
+#
+# Note: This will return a large number of results of different formats,
+#       which makes it impossible to filter with --replace_column.
+#       It's possible that some of these are not deterministic across
+#       platforms. If so, just remove the offending command.
+#
+--disable_warnings
+drop procedure if exists bug4902|
+--enable_warnings
+create procedure bug4902()
+begin
+  show charset like 'foo';
+  show collation like 'foo';
+  show column types;
+  show create table t1;
+  show create database test;
+  show databases like 'foo';
+  show errors;
+  show columns from t1;
+  show grants for 'root'@'localhost';
+  show keys from t1;
+  show open tables like 'foo';
+  show privileges;
+  show status like 'foo';
+  show tables like 'foo';
+  show variables like 'foo';
+  show warnings;
+end|
+--disable_parsing
+show binlog events;
+show storage engines;
+show master status;
+show slave hosts;
+show slave status;
+--enable_parsing
+
+call bug4902()|
+call bug4902()|
+
+drop procedure bug4902|
+
+# We need separate SP for SHOW PROCESSLIST  since we want use replace_column
+--disable_warnings
+drop procedure if exists bug4902_2|
+--enable_warnings
+create procedure bug4902_2()
+begin
+  show processlist;
+end|
+--replace_column 1 # 6 # 3 localhost
+call bug4902_2()|
+--replace_column 1 # 6 # 3 localhost
+call bug4902_2()|
+drop procedure bug4902_2|
+
+#
+# BUG#4904
+#
+--disable_warnings
+drop procedure if exists bug4904|
+--enable_warnings
+create procedure bug4904()
+begin
+  declare continue handler for sqlstate 'HY000' begin end;
+
+  create table t2 as select * from t3;
+end|
+
+-- error 1146
+call bug4904()|
+
+drop procedure bug4904|
+
+create table t3 (s1 char character set latin1, s2 char character set latin2)|
+
+--disable_warnings
+drop procedure if exists bug4904|
+--enable_warnings
+create procedure bug4904 ()
+begin
+  declare continue handler for sqlstate 'HY000' begin end;
+
+  select s1 from t3 union select s2 from t3; 
+end|
+
+call bug4904()|
+
+drop procedure bug4904|
+drop table t3|
+
+#
+# BUG#336
+#
+--disable_warnings
+drop procedure if exists bug336|
+--enable_warnings
+create procedure bug336(out y int)
+begin
+  declare x int;
+  set x = (select sum(t.data) from test.t1 t);
+  set y = x;
+end|
+
+insert into t1 values ("a", 2), ("b", 3)|
+call bug336(@y)|
+select @y|
+delete from t1|
+drop procedure bug336|
+
+#
+# BUG#3157
+#
+--disable_warnings
+drop procedure if exists bug3157|
+--enable_warnings
+create procedure bug3157()
+begin
+  if exists(select * from t1) then
+    set @n= @n + 1;
+  end if;
+  if (select count(*) from t1) then
+    set @n= @n + 1;
+  end if;
+end|
+
+set @n = 0|
+insert into t1 values ("a", 1)|
+call bug3157()|
+select @n|
+delete from t1|
+drop procedure bug3157|
+
+#
+# BUG#5251: mysql changes creation time of a procedure/function when altering
+#
+--disable_warnings
+drop procedure if exists bug5251|
+--enable_warnings
+create procedure bug5251()
+begin
+end|
+
+select created into @c1 from mysql.proc
+  where db='test' and name='bug5251'|
+--sleep 2
+alter procedure bug5251 comment 'foobar'|
+select count(*) from mysql.proc
+  where  db='test' and name='bug5251' and created = @c1|
+
+drop procedure bug5251|
+
+#
+# BUG#5279: Stored procedure packets out of order if CHECKSUM TABLE
+#
+--disable_warnings
+drop procedure if exists bug5251|
+--enable_warnings
+create procedure bug5251()
+  checksum table t1|
+
+call bug5251()|
+call bug5251()|
+drop procedure bug5251|
+
+#
+# BUG#5287: Stored procedure crash if leave outside loop
+#
+--disable_warnings
+drop procedure if exists bug5287|
+--enable_warnings
+create procedure bug5287(param1 int)
+label1:
+  begin
+    declare c cursor for select 5;
+
+    loop
+      if param1 >= 0 then
+        leave label1;
+      end if;
+    end loop;
+end|
+call bug5287(1)|
+drop procedure bug5287|
+
+
+#
+# BUG#5307: Stored procedure allows statement after BEGIN ... END
+#
+--disable_warnings
+drop procedure if exists bug5307|
+--enable_warnings
+create procedure bug5307()
+begin
+end; set @x = 3|
+
+call bug5307()|
+select @x|
+drop procedure bug5307|
+
+#
+# BUG#5258: Stored procedure modified date is 0000-00-00
+# (This was a design flaw)
+--disable_warnings
+drop procedure if exists bug5258|
+--enable_warnings
+create procedure bug5258()
+begin
+end|
+
+--disable_warnings
+drop procedure if exists bug5258_aux|
+--enable_warnings
+create procedure bug5258_aux()
+begin
+  declare c, m char(19);
+
+  select created,modified into c,m from mysql.proc where name = 'bug5258';
+  if c = m then
+    select 'Ok';
+  else
+    select c, m;
+  end if;
+end|
+
+call bug5258_aux()|
+
+drop procedure bug5258|
+drop procedure bug5258_aux|
+
+#
+# BUG#4487: Stored procedure connection aborted if uninitialized char
+#
+--disable_warnings
+drop function if exists bug4487|
+--enable_warnings
+create function bug4487() returns char
+begin
+  declare v char;
+  return v;
+end|
+
+select bug4487()|
+drop function bug4487|
+
+
+#
+# BUG#4941: Stored procedure crash fetching null value into variable.
+#
+--disable_warnings
+drop procedure if exists bug4941|
+--enable_warnings
+--disable_warnings
+drop procedure if exists bug4941|
+--enable_warnings
+create procedure bug4941(out x int)
+begin
+  declare c cursor for select i from t2 limit 1;
+  open c;
+  fetch c into x;
+  close c;
+end|
+
+insert into t2 values (null, null, null)|
+set @x = 42|
+call bug4941(@x)|
+select @x|
+delete from t1|
+drop procedure bug4941|
+
+
+#
+# BUG#3583: query cache doesn't work for stored procedures
+#
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+create procedure bug3583()
+begin
+  declare c int;
+
+  select * from t1;
+  select count(*) into c from t1;
+  select c;
+end|
+
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+call bug3583()|
+show status like 'Qcache_hits'|
+call bug3583()|
+call bug3583()|
+show status like 'Qcache_hits'|
+
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+
+#
+# BUG#4905: Stored procedure doesn't clear for "Rows affected"
+#
+--disable_warnings
+drop procedure if exists bug4905|
+--enable_warnings
+
+create table t3 (s1 int,primary key (s1))|
+
+--disable_warnings
+drop procedure if exists bug4905|
+--enable_warnings
+create procedure bug4905()
+begin
+  declare v int;
+  declare continue handler for sqlstate '23000' set v = 5;
+
+  insert into t3 values (1);
+end|
+
+call bug4905()|
+select row_count()|
+call bug4905()|
+select row_count()|
+call bug4905()|
+select row_count()|
+select * from t3|
+
+drop procedure bug4905|
+drop table t3|
+
+#
+# BUG#6022: Stored procedure shutdown problem with self-calling function.
+#
+
+--disable_parsing # until we implement support for recursive stored functions.
+--disable_warnings
+drop function if exists bug6022|
+--enable_warnings
+
+--disable_warnings
+drop function if exists bug6022|
+--enable_warnings
+create function bug6022(x int) returns int
+begin
+  if x < 0 then
+    return 0;
+  else
+    return bug6022(x-1);
+  end if;
+end|
+
+select bug6022(5)|
+drop function bug6022|
+--enable_parsing
+
+#
+# BUG#6029: Stored procedure specific handlers should have priority
+#
+--disable_warnings
+drop procedure if exists bug6029|
+--enable_warnings
+
+--disable_warnings
+drop procedure if exists bug6029|
+--enable_warnings
+create procedure bug6029()
+begin
+  declare exit handler for 1136  select '1136';
+  declare exit handler for sqlstate '23000'  select 'sqlstate 23000';
+  declare continue handler for sqlexception  select 'sqlexception';
+
+  insert into t3 values (1);
+  insert into t3 values (1,2);
+end|
+ 
+create table t3 (s1 int, primary key (s1))|
+insert into t3 values (1)|
+call bug6029()|
+delete from t3|
+call bug6029()|
+
+drop procedure bug6029|
+drop table t3|
+
+#
+# BUG#8540: Local variable overrides an alias
+#
+--disable_warnings
+drop procedure if exists bug8540|
+--enable_warnings
+
+create procedure bug8540()
+begin
+  declare x int default 1;
+  select x as y, x+0 as z;
+end|
+
+call bug8540()|
+drop procedure bug8540|
+
+#
+# BUG#6642: Stored procedure crash if expression with set function
+#
+create table t3 (s1 int)|
+
+--disable_warnings
+drop procedure if exists bug6642|
+--enable_warnings
+
+create procedure bug6642()
+  select abs(count(s1)) from t3|
+
+call bug6642()|
+call bug6642()|
+drop procedure bug6642|
+
+#
+# BUG#7013: Stored procedure crash if group by ... with rollup
+#
+insert into t3 values (0),(1)|
+--disable_warnings
+drop procedure if exists bug7013|
+--enable_warnings
+create procedure bug7013()
+  select s1,count(s1) from t3 group by s1 with rollup|
+call bug7013()|
+call bug7013()|
+drop procedure bug7013|
+
+#
+# BUG#7743: 'Lost connection to MySQL server during query' on Stored Procedure
+#
+--disable_warnings
+drop table if exists t4|
+--enable_warnings
+create table t4 (
+  a mediumint(8) unsigned not null auto_increment,
+  b smallint(5) unsigned not null,
+  c char(32) not null,
+  primary key  (a)
+) engine=myisam default charset=latin1|
+insert into t4 values (1, 2, 'oneword')|
+insert into t4 values (2, 2, 'anotherword')|
+
+--disable_warnings
+drop procedure if exists bug7743|
+--enable_warnings
+create procedure bug7743 ( searchstring char(28) )
+begin
+  declare var mediumint(8) unsigned;
+  select a into var from t4 where b = 2 and c = binary searchstring limit 1;
+  select var;
+end|
+
+call bug7743("oneword")|
+call bug7743("OneWord")|
+call bug7743("anotherword")|
+call bug7743("AnotherWord")|
+drop procedure bug7743|
+drop table t4|
+
+#
+# BUG#7992: SELECT .. INTO variable .. within Stored Procedure crashes
+#           the server
+#
+delete from t3|
+insert into t3 values(1)|
+drop procedure if exists bug7992_1|
+drop procedure if exists bug7992_2|
+create procedure bug7992_1()
+begin
+  declare i int;
+  select max(s1)+1 into i from t3;
+end|
+create procedure bug7992_2()
+  insert into t3 (s1) select max(t4.s1)+1 from t3 as t4|
+
+call bug7992_1()|
+call bug7992_1()|
+call bug7992_2()|
+call bug7992_2()|
+
+drop procedure bug7992_1|
+drop procedure bug7992_2|
+drop table t3|
+
+#
+# BUG#8116: calling simple stored procedure twice in a row results
+#           in server crash
+#
+create table t3 (  userid bigint(20) not null default 0 )|
+
+--disable_warnings
+drop procedure if exists bug8116|
+--enable_warnings
+create procedure bug8116(in _userid int)
+   select * from t3 where userid = _userid|
+
+call bug8116(42)|
+call bug8116(42)|
+drop procedure bug8116|
+drop table t3|
+
+#
+# BUG#6857: current_time() in STORED PROCEDURES
+#
+--disable_warnings
+drop procedure if exists bug6857|
+--enable_warnings
+create procedure bug6857(counter int)
+begin
+  declare t0, t1 int;
+  declare plus bool default 0;
+
+  set t0 = current_time();
+  while counter > 0 do
+    set counter = counter - 1;
+  end while;
+  set t1 = current_time();
+  if t1 > t0 then
+    set plus = 1;
+  end if;
+  select plus;
+end|
+
+# QQ: This is currently disabled. Not only does it slow down a normal test
+#     run, it makes running with valgrind (or similar tools) extremely
+#     painful.
+# Make sure this takes at least one second on all machines in all builds.
+# 30000 makes it about 3 seconds on an old 1.1GHz linux.
+#call bug6857(300000)|
+
+drop procedure bug6857|
+
+#
+# BUG#8757: Stored Procedures: Scope of Begin and End Statements do not
+#           work properly.
+--disable_warnings
+drop procedure if exists bug8757|
+--enable_warnings
+create procedure bug8757()
+begin
+  declare x int;
+  declare c1 cursor for select data from t1 limit 1;
+
+  begin
+    declare y int;
+    declare c2 cursor for select i from t2 limit 1;
+
+    open c2;
+    fetch c2 into y;
+    close c2;
+    select 2,y;
+  end;
+  open c1;
+  fetch c1 into x;
+  close c1;
+  select 1,x;
+end|
+
+delete from t1|
+delete from t2|
+insert into t1 values ("x", 1)|
+insert into t2 values ("y", 2, 0.0)|
+
+call bug8757()|
+
+delete from t1|
+delete from t2|
+drop procedure bug8757|
+
+
+#
+# BUG#8762: Stored Procedures: Inconsistent behavior
+#           of DROP PROCEDURE IF EXISTS statement.
+--disable_warnings
+drop procedure if exists bug8762|
+--enable_warnings
+# Doesn't exist
+drop procedure if exists bug8762; create procedure bug8762() begin end|
+# Does exist
+drop procedure if exists bug8762; create procedure bug8762() begin end|
+drop procedure bug8762|
+
+
+#
+# BUG#5240: Stored procedure crash if function has cursor declaration
+#
+--disable_warnings
+drop function if exists bug5240|
+--enable_warnings
+create function bug5240 () returns int
+begin
+  declare x int;
+  declare c cursor for select data from t1 limit 1;
+
+  open c;
+  fetch c into x;
+  close c;
+  return x;
+end|
+
+delete from t1|
+insert into t1 values ("answer", 42)|
+select id, bug5240() from t1|
+drop function bug5240|
+
+#
+# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
+#
+--disable_warnings
+drop function if exists bug5278|
+--enable_warnings
+create function bug5278 () returns char
+begin
+  SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
+  return 'okay';
+end|
+
+--error 1133
+select bug5278()|
+--error 1133
+select bug5278()|
+drop function bug5278|
+
+#
+# BUG#7992: rolling back temporary Item tree changes in SP
+#
+--disable_warnings
+drop procedure if exists p1|
+--enable_warnings
+create table t3(id int)|
+insert into t3 values(1)|
+create procedure bug7992()
+begin
+  declare i int;
+  select max(id)+1 into i from t3;
+end|
+
+call bug7992()|
+call bug7992()|
+drop procedure bug7992|
+drop table t3|
+delimiter ;|
+
+#
+# BUG#8849: problem with insert statement with table alias's
+#
+# Rolling back changes to AND/OR structure of ON and WHERE clauses  in SP
+# 
+
+delimiter |;
+create table t3 (
+  lpitnumber int(11) default null,
+  lrecordtype int(11) default null
+)|
+
+create table t4 (
+  lbsiid int(11) not null default '0',
+  ltradingmodeid int(11) not null default '0',
+  ltradingareaid int(11) not null default '0',
+  csellingprice decimal(19,4) default null,
+  primary key  (lbsiid,ltradingmodeid,ltradingareaid)
+)|
+
+create table t5 (
+  lbsiid int(11) not null default '0',
+  ltradingareaid int(11) not null default '0',
+  primary key  (lbsiid,ltradingareaid)
+)|
+
+--disable_warnings
+drop procedure if exists bug8849|
+--enable_warnings
+create procedure bug8849()
+begin
+  insert into t5
+  (
+   t5.lbsiid,
+   t5.ltradingareaid
+  )
+  select distinct t3.lpitnumber, t4.ltradingareaid
+  from
+    t4 join t3 on
+      t3.lpitnumber = t4.lbsiid
+      and t3.lrecordtype = 1
+    left join t4 as price01 on
+      price01.lbsiid = t4.lbsiid and
+      price01.ltradingmodeid = 1 and
+      t4.ltradingareaid = price01.ltradingareaid;
+end|
+
+call bug8849()|
+call bug8849()|
+call bug8849()|
+drop procedure bug8849|
+drop tables t3,t4,t5|
+
+#
+# BUG#8937: Stored Procedure: AVG() works as SUM() in SELECT ... INTO statement
+#
+--disable_warnings
+drop procedure if exists bug8937|
+--enable_warnings
+create procedure bug8937()
+begin
+  declare s,x,y,z int;
+  declare a float;
+
+  select sum(data),avg(data),min(data),max(data) into s,x,y,z from t1;
+  select s,x,y,z;
+  select avg(data) into a from t1;
+  select a;
+end|
+
+delete from t1|
+insert into t1 (data) values (1), (2), (3), (4), (6)|
+call bug8937()|
+
+drop procedure bug8937|
+delete from t1|
+
+
+#
+# BUG#6900: Stored procedure inner handler ignored
+# BUG#9074: STORED PROC: The scope of every handler declared is not
+#                        properly applied
+#
+--disable_warnings
+drop procedure if exists bug6900|
+drop procedure if exists bug9074|
+drop procedure if exists bug6900_9074|
+--enable_warnings
+
+create table t3 (w char unique, x char)|
+insert into t3 values ('a', 'b')|
+
+create procedure bug6900()
+begin
+  declare exit handler for sqlexception select '1';
+
+  begin
+    declare exit handler for sqlexception select '2';
+
+    insert into t3 values ('x', 'y', 'z');
+  end;
+end|
+
+create procedure bug9074()
+begin
+  declare x1, x2, x3, x4, x5, x6 int default 0;
+
+  begin    
+    declare continue handler for sqlstate '23000' set x5 = 1;      
+
+    insert into t3 values ('a', 'b');      
+    set x6 = 1;      
+  end;
+
+ begin1_label:
+  begin
+    declare continue handler for sqlstate '23000' set x1 = 1;      
+
+    insert into t3 values ('a', 'b');      
+    set x2 = 1;      
+				
+   begin2_label:
+    begin  
+      declare exit handler for sqlstate '23000' set x3 = 1;         
+
+      set x4= 1;         
+      insert into t3 values ('a','b');
+      set x4= 0;
+    end begin2_label;
+  end begin1_label;
+
+  select x1, x2, x3, x4, x5, x6;
+end|
+
+create procedure bug6900_9074(z int)
+begin
+  declare exit handler for sqlstate '23000' select '23000';
+
+  begin
+    declare exit handler for sqlexception select 'sqlexception';
+
+    if z = 1 then
+      insert into t3 values ('a', 'b');
+    else
+      insert into t3 values ('x', 'y', 'z');
+    end if;
+  end;
+end|
+
+call bug6900()|
+call bug9074()|
+call bug6900_9074(0)|
+call bug6900_9074(1)|
+
+drop procedure bug6900|
+drop procedure bug9074|
+drop procedure bug6900_9074|
+drop table t3|
+
+
+#
+# BUG#7185: Stored procedure crash if identifier is AVG
+#
+--disable_warnings
+drop procedure if exists avg|
+--enable_warnings
+create procedure avg ()
+begin
+end|
+
+call avg ()|
+drop procedure avg|
+
+
+#
+# BUG#6129: Stored procedure won't display @@sql_mode value
+#
+--disable_warnings
+drop procedure if exists bug6129|
+--enable_warnings
+set @old_mode= @@sql_mode;
+set @@sql_mode= "ERROR_FOR_DIVISION_BY_ZERO";
+create procedure bug6129()
+  select @@sql_mode|
+call bug6129()|
+set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"|
+call bug6129()|
+set @@sql_mode= "NO_ZERO_IN_DATE"|
+call bug6129()|
+set @@sql_mode=@old_mode;
+
+drop procedure bug6129|
+
+
+#
+# BUG#9856: Stored procedures: crash if handler for sqlexception, not found
+#
+--disable_warnings
+drop procedure if exists bug9856|
+--enable_warnings
+create procedure bug9856()
+begin
+  declare v int;
+  declare c cursor for select data from t1;
+  declare exit handler for sqlexception, not found select '16';
+
+  open c;
+  fetch c into v;
+  select v;
+end|
+
+delete from t1|
+call bug9856()|
+call bug9856()|
+drop procedure bug9856|
+
+
+#
+# BUG##9674: Stored Procs: Using declared vars in algebric operation causes
+#            system crash.
+#
+--disable_warnings
+drop procedure if exists bug9674_1|
+drop procedure if exists bug9674_2|
+--enable_warnings
+create procedure bug9674_1(out arg int)
+begin
+  declare temp_in1 int default 0;
+  declare temp_fl1 int default 0;
+
+  set temp_in1 = 100;
+  set temp_fl1 = temp_in1/10;
+  set arg = temp_fl1;
+end|
+
+create procedure bug9674_2()
+begin
+  declare v int default 100;
+
+  select v/10;
+end|
+
+call bug9674_1(@sptmp)|
+call bug9674_1(@sptmp)|
+select @sptmp|
+call bug9674_2()|
+call bug9674_2()|
+drop procedure bug9674_1|
+drop procedure bug9674_2|
+
+
+#
+# BUG#9598: stored procedure call within stored procedure overwrites IN variable
+#
+--disable_warnings
+drop procedure if exists bug9598_1|
+drop procedure if exists bug9598_2|
+--enable_warnings
+create procedure bug9598_1(in var_1 char(16),
+                           out var_2 integer, out var_3 integer)
+begin
+  set var_2 = 50;
+  set var_3 = 60;
+end|
+
+create procedure bug9598_2(in v1 char(16),
+                           in v2 integer,
+                           in v3 integer,
+                           in v4 integer,
+                           in v5 integer)
+begin
+  select v1,v2,v3,v4,v5;
+  call bug9598_1(v1,@tmp1,@tmp2);
+  select v1,v2,v3,v4,v5;
+end|
+
+call bug9598_2('Test',2,3,4,5)|
+select @tmp1, @tmp2|
+
+drop procedure bug9598_1|
+drop procedure bug9598_2|
+
+
+#
+# BUG#9902: Crash with simple stored function using user defined variables
+#
+--disable_warnings
+drop procedure if exists bug9902|
+--enable_warnings
+create function bug9902() returns int(11)
+begin
+  set @x = @x + 1;
+  return @x;
+end|
+
+set @qcs1 = @@query_cache_size|
+set global query_cache_size = 100000|
+set @x = 1|
+insert into t1 values ("qc", 42)|
+select bug9902() from t1|
+select bug9902() from t1|
+select @x|
+
+set global query_cache_size = @qcs1|
+delete from t1|
+drop function bug9902|
+
+
+#
+# BUG#9102: Stored proccedures: function which returns blob causes crash
+#
+--disable_warnings
+drop function if exists bug9102|
+--enable_warnings
+create function bug9102() returns blob return 'a'|
+select bug9102()|
+drop function bug9102|
+
+
+#
+# BUG#7648: Stored procedure crash when invoking a function that returns a bit
+#
+--disable_warnings
+drop function if exists bug7648|
+--enable_warnings
+create function bug7648() returns bit(8) return 'a'|
+select bug7648()|
+drop function bug7648|
+
+
+#
+# BUG#9775: crash if create function that returns enum or set
+#
+--disable_warnings
+drop function if exists bug9775|
+--enable_warnings
+create function bug9775(v1 char(1)) returns enum('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('c')|
+drop function bug9775|
+create function bug9775(v1 int) returns enum('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3)|
+drop function bug9775|
+
+create function bug9775(v1 char(1)) returns set('a','b') return v1|
+select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
+drop function bug9775|
+create function bug9775(v1 int) returns set('a','b') return v1|
+select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
+drop function bug9775|
+
+
+#
+# BUG#8861: If Return is a YEAR data type, value is not shown in year format
+#
+--disable_warnings
+drop function if exists bug8861|
+--enable_warnings
+create function bug8861(v1 int) returns year return v1|
+select bug8861(05)|
+set @x = bug8861(05)|
+select @x|
+drop function bug8861|
+
+
+#
+# BUG#9004: Inconsistent behaviour of SP re. warnings
+#
+--disable_warnings
+drop procedure if exists bug9004_1|
+drop procedure if exists bug9004_2|
+--enable_warnings
+create procedure bug9004_1(x char(16))
+begin
+  insert into t1 values (x, 42);
+  insert into t1 values (x, 17);
+end|
+create procedure bug9004_2(x char(16))
+  call bug9004_1(x)|
+
+# Truncation warnings expected...
+call bug9004_1('12345678901234567')|
+call bug9004_2('12345678901234567890')|
+
+delete from t1|
+drop procedure bug9004_1|
+drop procedure bug9004_2|
+
+#
+# BUG#7293: Stored procedure crash with soundex
+#
+--disable_warnings
+drop procedure if exists bug7293|
+--enable_warnings
+insert into t1 values ('secret', 0)| 
+create procedure bug7293(p1 varchar(100))
+begin
+  if exists (select id from t1 where soundex(p1)=soundex(id)) then
+    select 'yes';
+  end if;
+end;| 
+call bug7293('secret')| 
+call bug7293 ('secrete')| 
+drop procedure bug7293|
+delete from t1|
+
+
+#
+# BUG#9841: Unexpected read lock when trying to update a view in a
+#           stored procedure
+#
+--disable_warnings
+drop procedure if exists bug9841|
+drop view if exists v1|
+--enable_warnings
+
+create view v1 as select * from t1, t2 where id = s|
+create procedure bug9841 ()
+  update v1 set data = 10| 
+call bug9841()|
+
+drop view v1|
+drop procedure bug9841|
+
+
+#
+# BUG#5963 subqueries in SET/IF
+#
+--disable_warnings
+drop procedure if exists bug5963|
+--enable_warnings
+
+create procedure bug5963_1 () begin declare v int; set v = (select s1 from t3); select v; end;|
+create table t3 (s1 int)|
+insert into t3 values (5)|
+call bug5963_1()|
+call bug5963_1()|
+drop procedure bug5963_1|
+drop table t3|
+
+create procedure bug5963_2 (cfk_value int) 
+begin 
+  if cfk_value in (select cpk from t3) then 
+    set @x = 5; 
+  end if; 
+  end; 
+| 
+create table t3 (cpk int)| 
+insert into t3 values (1)| 
+call bug5963_2(1)|
+call bug5963_2(1)|
+drop procedure bug5963_2|
+drop table t3|
+
+
+#
+# BUG#9559: Functions: Numeric Operations using -ve value gives incorrect
+#           results.
+#
+--disable_warnings
+drop function if exists bug9559|
+--enable_warnings
+create function bug9559()
+  returns int
+begin
+  set @y = -6/2;
+  return @y;
+end|
+
+select bug9559()|
+
+drop function bug9559|
+
+
+#
+# BUG#10961: Stored procedures: crash if select * from dual
+#
+--disable_warnings
+drop procedure if exists bug10961|
+--enable_warnings
+# "select * from dual" results in an error, so the cursor will not open
+create procedure bug10961()
+begin
+  declare v char;
+  declare x int;
+  declare c cursor for select * from dual;
+  declare continue handler for sqlexception select x;
+
+  set x = 1;
+  open c;
+  set x = 2;
+  fetch c into v;
+  set x = 3;
+  close c;
+end|
+
+call bug10961()|
+call bug10961()|
+
+drop procedure bug10961|
+
+#
+# BUG #6866: Second call of a stored procedure using a view with on expressions
+#
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug6866|
+--enable_warnings
+
+DROP VIEW IF EXISTS tv|
+DROP TABLE IF EXISTS tt1,tt2,tt3|
+
+CREATE TABLE tt1 (a1 int, a2 int, a3 int, data varchar(10))|
+CREATE TABLE tt2 (a2 int, data2 varchar(10))|
+CREATE TABLE tt3 (a3 int, data3 varchar(10))|
+
+INSERT INTO tt1 VALUES (1, 1, 4, 'xx')|
+
+INSERT INTO tt2 VALUES (1, 'a')|
+INSERT INTO tt2 VALUES (2, 'b')|
+INSERT INTO tt2 VALUES (3, 'c')|
+
+INSERT INTO tt3 VALUES (4, 'd')|
+INSERT INTO tt3 VALUES (5, 'e')|
+INSERT INTO tt3 VALUES (6, 'f')|
+
+CREATE VIEW tv AS
+SELECT tt1.*, tt2.data2, tt3.data3
+  FROM tt1 INNER JOIN tt2 ON tt1.a2 = tt2.a2
+         LEFT JOIN tt3 ON tt1.a3 = tt3.a3
+    ORDER BY tt1.a1, tt2.a2, tt3.a3|
+
+CREATE PROCEDURE bug6866 (_a1 int)
+BEGIN
+SELECT * FROM tv WHERE a1 = _a1;
+END|
+
+CALL bug6866(1)|
+CALL bug6866(1)|
+CALL bug6866(1)|
+
+DROP PROCEDURE bug6866;
+
+DROP VIEW tv|
+DROP TABLE tt1, tt2, tt3|
+
+#
+# BUG#10136: items cleunup
+#
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug10136|
+--enable_warnings
+create table t3 ( name char(5) not null primary key, val float not null)|
+insert into t3 values ('aaaaa', 1), ('bbbbb', 2), ('ccccc', 3)|
+create procedure bug10136()
+begin
+  declare done int default 3;
+
+  repeat
+    select * from t3;
+    set done = done - 1;
+  until done <= 0 end repeat;
+
+end|
+call bug10136()|
+call bug10136()|
+call bug10136()|
+drop procedure bug10136|
+drop table t3|
+
+#
+# BUG#11529: crash server after use stored procedure
+#
+--disable_warnings
+drop procedure if exists bug11529|
+--enable_warnings
+create procedure bug11529()
+begin
+  declare c cursor for select id, data from t1 where data in (10,13);
+
+  open c;
+  begin
+    declare vid char(16);
+    declare vdata int;
+    declare exit handler for not found begin end;
+
+    while true do
+      fetch c into vid, vdata;
+    end while;
+  end;
+  close c;
+end|
+
+insert into t1 values
+  ('Name1', 10),
+  ('Name2', 11),
+  ('Name3', 12),
+  ('Name4', 13),
+  ('Name5', 14)|
+
+call bug11529()|
+call bug11529()|
+delete from t1|
+drop procedure bug11529|
+
+
+#
+# BUG#6063: Stored procedure labels are subject to restrictions (partial)
+# BUG#7088: Stored procedures: labels won't work if character set is utf8
+#
+--disable_warnings
+drop procedure if exists bug6063|
+drop procedure if exists bug7088_1|
+drop procedure if exists bug7088_2|
+--enable_warnings
+
+--disable_parsing # temporarily disabled until Bar fixes BUG#11986
+create procedure bug6063()
+  lâbel: begin end|
+call bug6063()|
+# QQ Known bug: this will not show the label correctly.
+show create procedure bug6063|
+
+set character set utf8|
+create procedure bug7088_1()
+  label1: begin end label1|
+create procedure bug7088_2()
+  läbel1: begin end|
+call bug7088_1()|
+call bug7088_2()|
+set character set default|
+show create procedure bug7088_1|
+show create procedure bug7088_2|
+
+drop procedure bug6063|
+drop procedure bug7088_1|
+drop procedure bug7088_2|
+--enable_parsing
+
+#
+# BUG#9565: "Wrong locking in stored procedure if a sub-sequent procedure
+#           is called".
+#
+--disable_warnings
+drop procedure if exists bug9565_sub|
+drop procedure if exists bug9565|
+--enable_warnings
+create procedure bug9565_sub()
+begin
+  select * from t1;
+end|
+create procedure bug9565()
+begin
+  insert into t1 values ("one", 1);
+  call bug9565_sub();
+end|
+call bug9565()|
+delete from t1|
+drop procedure bug9565_sub|
+drop procedure bug9565|
+
+
+#
+# BUG#9538: SProc: Creation fails if we try to SET system variable
+#           using @@var_name in proc
+#
+--disable_warnings
+drop procedure if exists bug9538|
+--enable_warnings
+create procedure bug9538()
+  set @@sort_buffer_size = 1000000|
+
+set @x = @@sort_buffer_size|
+set @@sort_buffer_size = 2000000|
+select @@sort_buffer_size|
+call bug9538()|
+select @@sort_buffer_size|
+set @@sort_buffer_size = @x|
+
+drop procedure bug9538|
+
+
+#
+# BUG#8692: Cursor fetch of empty string
+#
+--disable_warnings
+drop procedure if exists bug8692|
+--enable_warnings
+create table t3 (c1 varchar(5), c2 char(5), c3 enum('one','two'), c4 text, c5 blob, c6 char(5), c7 varchar(5))|
+insert into t3 values ('', '', '', '', '', '', NULL)|
+
+create procedure bug8692()
+begin 
+    declare v1 VARCHAR(10); 
+    declare v2 VARCHAR(10); 
+    declare v3 VARCHAR(10); 
+    declare v4 VARCHAR(10); 
+    declare v5 VARCHAR(10); 
+    declare v6 VARCHAR(10); 
+    declare v7 VARCHAR(10); 
+    declare c8692 cursor for select c1,c2,c3,c4,c5,c6,c7 from t3; 
+    open c8692; 
+    fetch c8692 into v1,v2,v3,v4,v5,v6,v7;
+    select v1, v2, v3, v4, v5, v6, v7;
+end|
+
+call bug8692()|
+drop procedure bug8692|
+drop table t3|
+
+#
+# Bug#10055 "Using stored function with information_schema causes empty
+#            result set"
+#
+--disable_warnings
+drop function if exists bug10055|
+--enable_warnings
+create function bug10055(v char(255)) returns char(255) return lower(v)|
+# This select should not crash server and should return all fields in t1
+select t.column_name, bug10055(t.column_name)
+from information_schema.columns as t
+where t.table_schema = 'test' and t.table_name = 't1'|
+drop function bug10055|
+
+#
+# Bug #12297 "SP crashes the server if data inserted inside a lon loop"
+# The test for memleak bug, so actually there is no way to test it
+# from the suite. The test below could be used to check SP memory
+# consumption by passing large input parameter.
+#
+
+--disable_warnings
+drop procedure if exists bug12297|
+--enable_warnings
+
+create procedure bug12297(lim int)
+begin
+  set @x = 0;
+  repeat
+    insert into t1(id,data)
+    values('aa', @x);
+    set @x = @x + 1;
+  until @x >= lim
+  end repeat;
+end|
+
+call bug12297(10)|
+drop procedure bug12297|
+
+#
+# Bug #11247 "Stored procedures: Function calls in long loops leak memory"
+# One more memleak bug test. One could use this test to check that the memory
+# isn't leaking by increasing the input value for p_bug11247.
+#
+
+--disable_warnings
+drop function if exists f_bug11247|
+drop procedure if exists p_bug11247|
+--enable_warnings
+
+create function f_bug11247(param int)
+  returns int
+return param + 1|
+
+create procedure p_bug11247(lim int)
+begin
+  declare v int default 0;
+
+  while v < lim do
+    set v= f_bug11247(v);
+  end while;
+end|
+
+call p_bug11247(10)|
+drop function f_bug11247|
+drop procedure p_bug11247|
+#
+# BUG#12168: "'DECLARE CONTINUE HANDLER FOR NOT FOUND ...' in conditional
+# handled incorrectly"
+#
+--disable_warnings
+drop procedure if exists bug12168|
+drop table if exists t3, t4|
+--enable_warnings
+
+create table t3 (a int)|
+insert into t3 values (1),(2),(3),(4)|
+
+create table t4 (a int)|
+
+create procedure bug12168(arg1 char(1))
+begin
+  declare b, c integer;
+  if arg1 = 'a' then
+    begin
+      declare c1 cursor for select a from t3 where a % 2;
+      declare continue handler for not found set b = 1;
+      set b = 0;
+      open c1;
+      c1_repeat: repeat
+        fetch c1 into c;
+        if (b = 1) then
+          leave c1_repeat;
+        end if;
+
+        insert into t4 values (c);
+        until b = 1
+      end repeat;
+    end;
+  end if;
+  if arg1 = 'b' then
+    begin
+      declare c2 cursor for select a from t3 where not a % 2;
+      declare continue handler for not found set b = 1;
+      set b = 0;
+      open c2;
+      c2_repeat: repeat
+        fetch c2 into c;
+        if (b = 1) then
+          leave c2_repeat;
+        end if;
+
+        insert into t4 values (c);
+        until b = 1
+      end repeat;
+    end;
+  end if;
+end|
+
+call bug12168('a')|
+select * from t4|
+truncate t4|
+call bug12168('b')|
+select * from t4|
+truncate t4|
+call bug12168('a')|
+select * from t4|
+truncate t4|
+call bug12168('b')|
+select * from t4|
+truncate t4|
+drop table t3, t4|
+drop procedure if exists bug12168|
+
+#
+# Bug #11333 "Stored Procedure: Memory blow up on repeated SELECT ... INTO
+# query"
+# One more memleak bug. Use the test to check memory consumption.
+#
+
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug11333|
+--enable_warnings
+
+create table t3 (c1 char(128))|
+
+insert into t3 values 
+  ('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')|
+
+
+create procedure bug11333(i int)
+begin
+    declare tmp varchar(128);
+    set @x = 0;
+    repeat
+        select c1 into tmp from t3
+          where c1 = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
+        set @x = @x + 1;
+        until @x >= i
+    end repeat;
+end|
+
+call bug11333(10)|
+
+drop procedure bug11333|
+drop table t3|
+
+#
+# BUG#9048: Creating a function with char binary IN parameter fails
+#
+--disable_warnings
+drop function if exists bug9048|
+--enable_warnings
+create function bug9048(f1 char binary) returns char binary
+begin
+  set f1= concat( 'hello', f1 );
+  return f1;
+end|
+drop function bug9048|
+
+# Bug #12849 Stored Procedure: Crash on procedure call with CHAR type
+# 'INOUT' parameter
+#
+
+--disable_warnings
+drop procedure if exists bug12849_1|
+--enable_warnings
+create procedure bug12849_1(inout x char) select x into x|
+set @var='a'|
+call bug12849_1(@var)|
+select @var|
+drop procedure bug12849_1|
+
+--disable_warnings
+drop procedure if exists bug12849_2|
+--enable_warnings
+create procedure bug12849_2(inout foo varchar(15))
+begin
+select concat(foo, foo) INTO foo;
+end|
+set @var='abcd'|
+call bug12849_2(@var)|
+select @var|
+drop procedure bug12849_2|
+
+#
+# BUG#13133: Local variables in stored procedures are not initialized correctly.
+#
+--disable_warnings
+drop procedure if exists bug131333|
+drop function if exists bug131333|
+--enable_warnings
+create procedure bug131333()
+begin
+  begin
+    declare a int;
+
+    select a;
+    set a = 1;
+    select a;
+  end;
+  begin
+    declare b int;
+
+    select b;
+  end;
+end|
+
+create function bug131333()
+  returns int
+begin
+  begin
+    declare a int;
+
+    set a = 1;
+  end;
+  begin
+    declare b int;
+
+    return b;
+  end;
+end|
+
+call bug131333()|
+select bug131333()|
+
+drop procedure bug131333|
+drop function bug131333|
+
+#
+# BUG#12379: PROCEDURE with HANDLER calling FUNCTION with error get
+#            strange result
+#
+--disable_warnings
+drop function if exists bug12379|
+drop procedure if exists bug12379_1|
+drop procedure if exists bug12379_2|
+drop procedure if exists bug12379_3|
+drop table if exists t3|
+--enable_warnings
+
+create table t3 (c1 char(1) primary key not null)|
+
+create function bug12379()
+  returns integer
+begin
+   insert into t3 values('X');
+   insert into t3 values('X');
+   return 0;
+end|
+
+create procedure bug12379_1()
+begin
+   declare exit handler for sqlexception select 42;
+
+   select bug12379();
+END|
+create procedure bug12379_2()
+begin
+   declare exit handler for sqlexception begin end;
+
+   select bug12379();
+end|
+create procedure bug12379_3()
+begin
+   select bug12379();
+end|
+
+--error 1062
+select bug12379()|
+select 1|
+call bug12379_1()|
+select 2|
+call bug12379_2()|
+select 3|
+--error 1062
+call bug12379_3()|
+select 4|
+
+drop function bug12379|
+drop procedure bug12379_1|
+drop procedure bug12379_2|
+drop procedure bug12379_3|
+drop table t3|
+
+#
+# Bug #13124    Stored Procedure using SELECT INTO crashes server
+#
+
+--disable_warnings
+drop procedure if exists bug13124|
+--enable_warnings
+create procedure bug13124()
+begin
+  declare y integer;
+  set @x=y;
+end|
+call bug13124()|
+drop procedure  bug13124|
+
+#
+# Bug #12979  Stored procedures: crash if inout decimal parameter
+#
+
+# check NULL inout parameters processing
+
+--disable_warnings
+drop procedure if exists bug12979_1|
+--enable_warnings
+create procedure bug12979_1(inout d decimal(5)) set d = d / 2|
+set @bug12979_user_var = NULL|
+call bug12979_1(@bug12979_user_var)|
+drop procedure bug12979_1|
+
+# check NULL local variables processing
+
+--disable_warnings
+drop procedure if exists bug12979_2|
+--enable_warnings
+create procedure bug12979_2()
+begin
+declare internal_var decimal(5);
+set internal_var= internal_var / 2;
+select internal_var;
+end|
+call bug12979_2()|
+drop procedure bug12979_2|
+
+
+#
+# BUG#6127: Stored procedure handlers within handlers don't work
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug6127|
+--enable_warnings
+create table t3 (s1 int unique)|
+
+set @sm=@@sql_mode|
+set sql_mode='traditional'|
+
+create procedure bug6127()
+begin
+  declare continue handler for sqlstate '23000'
+    begin
+      declare continue handler for sqlstate '22003'
+        insert into t3 values (0);
+
+      insert into t3 values (1000000000000000);
+    end;
+
+  insert into t3 values (1);
+  insert into t3 values (1);
+end|
+
+call bug6127()|
+select * from t3|
+--error ER_DUP_ENTRY
+call bug6127()|
+select * from t3|
+set sql_mode=@sm|
+drop table t3|
+drop procedure bug6127|
+
+
+#
+# BUG#12589: Assert when creating temp. table from decimal stored procedure
+#            variable
+#
+--disable_warnings
+drop procedure if exists bug12589_1|
+drop procedure if exists bug12589_2|
+drop procedure if exists bug12589_3|
+--enable_warnings
+create procedure bug12589_1()
+begin
+  declare spv1 decimal(3,3);
+  set spv1= 123.456;
+
+  set spv1 = 'test';
+  create temporary table tm1 as select spv1;
+  show create table tm1;
+  drop temporary table tm1;
+end|
+
+create procedure bug12589_2()
+begin
+  declare spv1 decimal(6,3);
+  set spv1= 123.456;
+
+  create temporary table tm1 as select spv1;
+  show create table tm1;
+  drop temporary table tm1;
+end|
+
+create procedure bug12589_3()
+begin
+  declare spv1 decimal(6,3);
+  set spv1= -123.456;
+
+  create temporary table tm1 as select spv1;
+  show create table tm1;
+  drop temporary table tm1;
+end|
+
+# Note: The type of the field will match the value, not the declared
+#       type of the variable. (This is a type checking issue which
+#       might be changed later.)
+
+# Warning expected from "set spv1 = 'test'", the value is set to decimal "0".
+call bug12589_1()|
+# No warnings here
+call bug12589_2()|
+call bug12589_3()|
+drop procedure bug12589_1|
+drop procedure bug12589_2|
+drop procedure bug12589_3|
+
+#
+# BUG#7049: Stored procedure CALL errors are ignored
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug7049_1|
+drop procedure if exists bug7049_2|
+drop procedure if exists bug7049_3|
+drop procedure if exists bug7049_4|
+drop function if exists bug7049_1|
+drop function if exists bug7049_2|
+--enable_warnings
+
+create table t3 ( x int unique )|
+
+create procedure bug7049_1()
+begin
+  insert into t3 values (42);
+  insert into t3 values (42);
+end|
+
+create procedure bug7049_2()
+begin
+  declare exit handler for sqlexception
+    select 'Caught it' as 'Result';
+
+  call bug7049_1();
+  select 'Missed it' as 'Result';
+end|
+
+create procedure bug7049_3()
+  call bug7049_1()|
+
+create procedure bug7049_4()
+begin
+  declare exit handler for sqlexception
+    select 'Caught it' as 'Result';
+
+  call bug7049_3();
+  select 'Missed it' as 'Result';
+end|
+
+create function bug7049_1()
+  returns int
+begin
+  insert into t3 values (42);
+  insert into t3 values (42);
+  return 42;
+end|
+
+create function bug7049_2()
+  returns int
+begin
+  declare x int default 0;
+  declare continue handler for sqlexception
+    set x = 1;
+
+  set x = bug7049_1();
+  return x;
+end|
+
+call bug7049_2()|
+select * from t3|
+delete from t3|
+call bug7049_4()|
+select * from t3|
+select bug7049_2()|
+
+drop table t3|
+drop procedure bug7049_1|
+drop procedure bug7049_2|
+drop procedure bug7049_3|
+drop procedure bug7049_4|
+drop function bug7049_1|
+drop function bug7049_2|
+
+
+#
+# BUG#13941: replace() string fuction behaves badly inside stored procedure
+# (BUG#13914: IFNULL is returning garbage in stored procedure)
+#
+--disable_warnings
+drop function if exists bug13941|
+drop procedure if exists bug13941|
+--enable_warnings
+
+create function bug13941(p_input_str text)
+  returns text
+begin
+  declare p_output_str text;
+
+  set p_output_str = p_input_str;
+
+  set p_output_str = replace(p_output_str, 'xyzzy', 'plugh');
+  set p_output_str = replace(p_output_str, 'test', 'prova');
+  set p_output_str = replace(p_output_str, 'this', 'questo');
+  set p_output_str = replace(p_output_str, ' a ', 'una ');
+  set p_output_str = replace(p_output_str, 'is', '');
+
+  return p_output_str;
+end|
+
+create procedure bug13941(out sout varchar(128))
+begin
+  set sout = 'Local';
+  set sout = ifnull(sout, 'DEF');
+end|
+
+# Note: The bug showed different behaviour in different types of builds,
+#  giving garbage results in some, and seemingly working in others.
+#  Running with valgrind (or purify) is the safe way to check that it's
+#  really working correctly.
+select bug13941('this is a test')|
+call bug13941(@a)|
+select @a|
+
+drop function bug13941|
+drop procedure bug13941|
+
+
+#
+# BUG#13095: Cannot create VIEWs in prepared statements
+#
+
+delimiter ;|
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug13095;
+DROP TABLE IF EXISTS bug13095_t1;
+DROP VIEW IF EXISTS bug13095_v1;
+--enable_warnings
+
+delimiter |;
+
+CREATE PROCEDURE bug13095(tbl_name varchar(32))
+BEGIN
+  SET @str =
+    CONCAT("CREATE TABLE ", tbl_name, "(stuff char(15))");
+  SELECT @str;
+  PREPARE stmt FROM @str;
+  EXECUTE stmt;
+
+  SET @str =
+    CONCAT("INSERT INTO ", tbl_name, " VALUES('row1'),('row2'),('row3')" );
+  SELECT @str;
+  PREPARE stmt FROM @str;
+  EXECUTE stmt;
+
+  SET @str =
+    CONCAT("CREATE VIEW bug13095_v1(c1) AS SELECT stuff FROM ", tbl_name);
+  SELECT @str;
+  PREPARE stmt FROM @str;
+  EXECUTE stmt;
+
+  SELECT * FROM bug13095_v1;
+
+  SET @str =
+    "DROP VIEW bug13095_v1";
+  SELECT @str;
+  PREPARE stmt FROM @str;
+  EXECUTE stmt;
+END|
+
+delimiter ;|
+
+CALL bug13095('bug13095_t1');
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug13095;
+DROP VIEW IF EXISTS bug13095_v1;
+DROP TABLE IF EXISTS bug13095_t1;
+--enable_warnings
+
+delimiter |;
+
+#
+# BUG#14210: "Simple query with > operator on large table gives server
+# crash"
+# Check that cursors work in case when HEAP tables are converted to
+# MyISAM
+#
+--disable_warnings
+drop procedure if exists bug14210|
+--enable_warnings
+set @@session.max_heap_table_size=16384|
+select @@session.max_heap_table_size|
+# To trigger the memory corruption the original table must be InnoDB.
+# No harm if it's not, so don't warn if the suite is run with --skip-innodb
+--disable_warnings
+create table t3 (a char(255)) engine=InnoDB|
+--enable_warnings
+create procedure bug14210_fill_table()
+begin
+  declare table_size, max_table_size int default 0;
+  select @@session.max_heap_table_size into max_table_size;
+  delete from t3;
+  insert into t3 (a) values (repeat('a', 255));
+  repeat
+    insert into t3 select a from t3;
+    select count(*)*255 from t3 into table_size;
+  until table_size > max_table_size*2 end repeat;
+end|
+call bug14210_fill_table()|
+drop procedure bug14210_fill_table|
+create table t4 like t3|
+
+create procedure bug14210()
+begin
+  declare a char(255);
+  declare done int default 0;
+  declare c cursor for select * from t3;
+  declare continue handler for sqlstate '02000' set done = 1;
+  open c;
+  repeat
+    fetch c into a;
+    if not done then
+       insert into t4 values (upper(a));
+    end if;
+  until done end repeat;
+  close c;
+end|
+call bug14210()|
+select count(*) from t4|
+
+drop table t3, t4|
+drop procedure bug14210|
+set @@session.max_heap_table_size=default|
+
+
+#
+# BUG#1473: Dumping of stored functions seems to cause corruption in
+#           the function body
+#
+--disable_warnings
+drop function if exists bug14723|
+drop procedure if exists bug14723|
+--enable_warnings
+
+delimiter ;;|
+/*!50003 create function bug14723()
+ returns bigint(20)
+main_loop: begin
+  return 42;
+end */;;
+show create function bug14723;;
+select bug14723();;
+
+/*!50003 create procedure bug14723()
+main_loop: begin
+  select 42;
+end */;;
+show create procedure bug14723;;
+call bug14723();;
+
+delimiter |;;
+
+drop function bug14723|
+drop procedure bug14723|
+
+#
+# Bug#14845 "mysql_stmt_fetch returns MYSQL_NO_DATA when COUNT(*) is 0"
+# Check that when fetching from a cursor, COUNT(*) works properly.
+#
+create procedure bug14845()
+begin
+  declare a char(255);
+  declare done int default 0;
+  declare c cursor for select count(*) from t1 where 1 = 0;
+  declare continue handler for sqlstate '02000' set done = 1;
+  open c;
+  repeat
+    fetch c into a;
+    if not done then
+      select a;
+    end if;
+  until done end repeat;
+  close c;
+end|
+call bug14845()|
+drop procedure bug14845|
+
+#
+# BUG#13549 "Server crash with nested stored procedures".
+# Server should not crash when during execution of stored procedure
+# we have to parse trigger/function definition and this new trigger/
+# function has more local variables declared than invoking stored
+# procedure and last of these variables is used in argument of NOT
+# operator.
+#
+--disable_warnings
+drop procedure if exists bug13549_1|
+drop procedure if exists bug13549_2|
+--enable_warnings
+CREATE PROCEDURE `bug13549_2`()
+begin
+  call bug13549_1();
+end|
+CREATE PROCEDURE `bug13549_1`()
+begin
+  declare done int default 0;
+  set done= not done;
+end|
+CALL bug13549_2()|
+drop procedure bug13549_2|
+drop procedure bug13549_1|
+
+#
+# BUG#10100: function (and stored procedure?) recursivity problem
+#
+--disable_warnings
+drop function if exists bug10100f|
+drop procedure if exists bug10100p|
+drop procedure if exists bug10100t|
+drop procedure if exists bug10100pt|
+drop procedure if exists bug10100pv|
+drop procedure if exists bug10100pd|
+drop procedure if exists bug10100pc|
+--enable_warnings
+# routines with simple recursion
+create function bug10100f(prm int) returns int
+begin
+  if prm > 1 then
+    return prm * bug10100f(prm - 1);
+  end if;
+  return 1;
+end|
+create procedure bug10100p(prm int, inout res int)
+begin
+  set res = res * prm;
+  if prm > 1 then
+    call bug10100p(prm - 1, res);  
+  end if;
+end|
+create procedure bug10100t(prm int)
+begin
+  declare res int;
+  set res = 1;
+  call bug10100p(prm, res);
+  select res;
+end|
+
+# a procedure which use tables and recursion
+create table t3 (a int)|
+insert into t3 values (0)|
+create view v1 as select a from t3;
+create procedure bug10100pt(level int, lim int)
+begin
+  if level < lim then
+    update t3 set a=level;
+    FLUSH TABLES;
+    call bug10100pt(level+1, lim);
+  else
+    select * from t3;
+  end if;
+end|
+# view & recursion
+create procedure bug10100pv(level int, lim int)
+begin
+  if level < lim then
+    update v1 set a=level;
+    FLUSH TABLES;
+    call bug10100pv(level+1, lim);
+  else
+    select * from v1;
+  end if;
+end|
+# dynamic sql & recursion
+prepare stmt2 from "select * from t3;";
+create procedure bug10100pd(level int, lim int)
+begin
+  if level < lim then
+    select level;
+    prepare stmt1 from "update t3 set a=a+2";
+    execute stmt1;
+    FLUSH TABLES;
+    execute stmt1;
+    FLUSH TABLES;
+    execute stmt1;
+    FLUSH TABLES;
+    deallocate prepare stmt1;
+    execute stmt2;
+    select * from t3;
+    call bug10100pd(level+1, lim);
+  else
+    execute stmt2;
+  end if;
+end|
+# cursor & recursion
+create procedure bug10100pc(level int, lim int)
+begin
+  declare lv int;
+  declare c cursor for select a from t3;
+  open c;
+  if level < lim then
+    select level;
+    fetch c into lv;
+    select lv;
+    update t3 set a=level+lv;
+    FLUSH TABLES;
+    call bug10100pc(level+1, lim);
+  else
+    select * from t3;
+  end if;
+  close c;
+end|
+
+set @@max_sp_recursion_depth=4|
+select @@max_sp_recursion_depth|
+-- error ER_SP_NO_RECURSION
+select bug10100f(3)|
+-- error ER_SP_NO_RECURSION
+select bug10100f(6)|
+call bug10100t(5)|
+call bug10100pt(1,5)|
+call bug10100pv(1,5)|
+update t3 set a=1|
+call bug10100pd(1,5)|
+select * from t3|
+update t3 set a=1|
+call bug10100pc(1,5)|
+select * from t3|
+set @@max_sp_recursion_depth=0|
+select @@max_sp_recursion_depth|
+-- error ER_SP_NO_RECURSION
+select bug10100f(5)|
+-- error ER_SP_RECURSION_LIMIT
+call bug10100t(5)|
+
+#end of the stack checking
+set @@max_sp_recursion_depth=255|
+set @var=1|
+#disable log because error about stack overrun contains numbers which
+#depend on a system
+-- disable_result_log
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100p(255, @var)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pt(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pv(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pd(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pc(1,255)|
+-- enable_result_log
+set @@max_sp_recursion_depth=0|
+
+deallocate prepare stmt2|
+
+drop function bug10100f|
+drop procedure bug10100p|
+drop procedure bug10100t|
+drop procedure bug10100pt|
+drop procedure bug10100pv|
+drop procedure bug10100pd|
+drop procedure bug10100pc|
+drop view v1|
+
+#
+# BUG#13729: Stored procedures: packet error after exception handled
+#
+--disable_warnings
+drop procedure if exists bug13729|
+drop table if exists t3|
+--enable_warnings
+
+create table t3 (s1 int, primary key (s1))|
+
+insert into t3 values (1),(2)|
+
+create procedure bug13729()
+begin
+  declare continue handler for sqlexception select 55;
+
+  update t3 set s1 = 1;
+end|
+
+call bug13729()|
+# Used to cause Packets out of order
+select * from t3|
+
+drop procedure bug13729|
+drop table t3|
+
+#
+# BUG#14643: Stored Procedure: Continuing after failed var. initialization
+#            crashes server.
+#
+--disable_warnings
+drop procedure if exists bug14643_1|
+drop procedure if exists bug14643_2|
+--enable_warnings
+
+create procedure bug14643_1()
+begin
+  declare continue handler for sqlexception select 'boo' as 'Handler';
+
+  begin
+    declare v int default undefined_var;
+
+    if v = 1 then
+      select 1;
+    else
+      select v, isnull(v);
+    end if;
+  end;
+end|
+
+create procedure bug14643_2()
+begin
+  declare continue handler for sqlexception select 'boo' as 'Handler';
+
+  case undefined_var
+  when 1 then
+    select 1;
+  else
+    select 2;
+  end case;
+
+  select undefined_var;
+end|
+
+call bug14643_1()|
+call bug14643_2()|
+
+drop procedure bug14643_1|
+drop procedure bug14643_2|
+
+#
+# BUG#14304: auto_increment field incorrect set in SP
+#
+--disable_warnings
+drop procedure if exists bug14304|
+drop table if exists t3, t4|
+--enable_warnings
+
+create table t3(a int primary key auto_increment)|
+create table t4(a int primary key auto_increment)|
+
+create procedure bug14304()
+begin
+  insert into t3 set a=null;
+  insert into t4 set a=null;
+  insert into t4 set a=null;
+  insert into t4 set a=null;
+  insert into t4 set a=null;
+  insert into t4 set a=null;
+  insert into t4 select null as a;
+  
+  insert into t3 set a=null;
+  insert into t3 set a=null;
+  
+  select * from t3;
+end|
+
+call bug14304()|
+
+drop procedure bug14304|
+drop table t3, t4|
+
+#
+# BUG#14376: MySQL crash on scoped variable (re)initialization
+#
+--disable_warnings
+drop procedure if exists bug14376|
+--enable_warnings
+
+create procedure bug14376()
+begin
+  declare x int default x;
+end|
+
+# Not the error we want, but that's what we got for now...
+--error ER_BAD_FIELD_ERROR
+call bug14376()|
+drop procedure bug14376|
+
+create procedure bug14376()
+begin
+  declare x int default 42;
+
+  begin
+    declare x int default x;
+
+    select x;
+  end;
+end|
+
+call bug14376()|
+
+drop procedure bug14376|
+
+create procedure bug14376(x int)
+begin
+  declare x int default x;
+
+  select x;
+end|
+
+call bug14376(4711)|
+
+drop procedure bug14376|
+
+#
+# Bug#5967 "Stored procedure declared variable used instead of column"
+# The bug should be fixed later.
+# Test precedence of names of parameters, variable declarations, 
+# variable declarations in nested compound statements, table columns,
+# table columns in cursor declarations.
+# According to the standard, table columns take precedence over
+# variable declarations. In MySQL 5.0 it's vice versa.
+#
+
+--disable_warnings
+drop procedure if exists bug5967|
+drop table if exists t3|
+--enable_warnings
+create table t3 (a varchar(255))|
+insert into t3 (a) values ("a - table column")|
+create procedure bug5967(a varchar(255))
+begin
+  declare i varchar(255);
+  declare c cursor for select a from t3;
+  select a;
+  select a from t3 into i;
+  select i as 'Parameter takes precedence over table column';                     open c;
+  fetch c into i;
+  close c;
+  select i as 'Parameter takes precedence over table column in cursors';
+  begin
+    declare a varchar(255) default 'a - local variable';
+    declare c1 cursor for select a from t3;
+    select a as 'A local variable takes precedence over parameter';
+    open c1;
+    fetch c1 into i;
+    close c1;
+    select i as 'A local variable takes precedence over parameter in cursors';
+    begin
+      declare a varchar(255) default 'a - local variable in a nested compound statement';
+      declare c2 cursor for select a from t3;
+      select a as 'A local variable in a nested compound statement takes precedence over a local variable in the outer statement';
+      select a from t3 into i;
+      select i as  'A local variable in a nested compound statement takes precedence over table column';
+      open c2;
+      fetch c2 into i;
+      close c2;
+      select i as  'A local variable in a nested compound statement takes precedence over table column in cursors';
+    end;
+  end;
+end|
+call bug5967("a - stored procedure parameter")|
+drop procedure bug5967|
+
+#
+# Bug#13012 "SP: REPAIR/BACKUP/RESTORE TABLE crashes the server"
+#
+--disable_warnings
+drop procedure if exists bug13012|
+--enable_warnings
+create procedure bug13012()
+BEGIN
+  REPAIR TABLE t1;
+  BACKUP TABLE t1 to '../tmp';
+  DROP TABLE t1;
+  RESTORE TABLE t1 FROM '../tmp';
+END|
+call bug13012()|
+drop procedure bug13012|
+create view v1 as select * from t1|
+create procedure bug13012()
+BEGIN
+  REPAIR TABLE t1,t2,t3,v1;
+  OPTIMIZE TABLE t1,t2,t3,v1;
+  ANALYZE TABLE t1,t2,t3,v1;
+END|
+call bug13012()|
+call bug13012()|
+call bug13012()|
+drop procedure bug13012|
+drop view v1;
+select * from t1|
+
+#
+# A test case for Bug#15392 "Server crashes during prepared statement
+# execute": make sure that stored procedure check for error conditions
+# properly and do not continue execution if an error has been set. 
+#
+# It's necessary to use several DBs because in the original code
+# the successful return of mysql_change_db overrode the error from
+# execution.
+drop schema if exists mysqltest1|
+drop schema if exists mysqltest2|
+drop schema if exists mysqltest3|
+create schema mysqltest1|
+create schema mysqltest2|
+create schema mysqltest3|
+use mysqltest3|
+
+create procedure mysqltest1.p1 (out prequestid varchar(100))
+begin
+  call mysqltest2.p2('call mysqltest3.p3(1, 2)');
+end|
+
+create procedure mysqltest2.p2(in psql text)
+begin
+  declare lsql text;
+  set @lsql= psql;
+  prepare lstatement from @lsql;
+  execute lstatement;
+  deallocate prepare lstatement;
+end|
+
+create procedure mysqltest3.p3(in p1 int)
+begin
+  select p1;
+end|
+
+--error ER_SP_WRONG_NO_OF_ARGS
+call mysqltest1.p1(@rs)|
+--error ER_SP_WRONG_NO_OF_ARGS
+call mysqltest1.p1(@rs)|
+--error ER_SP_WRONG_NO_OF_ARGS
+call mysqltest1.p1(@rs)|
+drop schema if exists mysqltest1|
+drop schema if exists mysqltest2|
+drop schema if exists mysqltest3|
+use test|
+
+#
+# Bug#15441 "Running SP causes Server to Crash": check that an SP variable
+# can not be used in VALUES() function.
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug15441|
+--enable_warnings
+create table t3 (id int not null primary key, county varchar(25))|
+insert into t3 (id, county) values (1, 'York')|
+
+# First check that a stored procedure that refers to a parameter in VALUES()
+# function won't parse.
+
+create procedure bug15441(c varchar(25))
+begin
+  update t3 set id=2, county=values(c);
+end|
+--error ER_BAD_FIELD_ERROR
+call bug15441('county')|
+drop procedure bug15441|
+
+# Now check the case when there is an ambiguity between column names
+# and stored procedure parameters: the parser shall resolve the argument
+# of VALUES() function to the column name.
+
+# It's hard to deduce what county refers to in every case (INSERT statement):
+# 1st county refers to the column
+# 2nd county refers to the procedure parameter
+# 3d and 4th county refers to the column, again, but
+# for 4th county it has the value of SP parameter
+
+# In UPDATE statement, just check that values() function returns NULL for
+# non- INSERT...UPDATE statements, as stated in the manual.
+
+create procedure bug15441(county varchar(25))
+begin
+  declare c varchar(25) default "hello";
+
+  insert into t3 (id, county) values (1, county)
+  on duplicate key update county= values(county);
+  select * from t3;
+
+  update t3 set id=2, county=values(id);
+  select * from t3;
+end|
+call bug15441('Yale')|
+drop table t3|
+drop procedure bug15441|
+
+#
+# BUG#14498: Stored procedures: hang if undefined variable and exception
+#
+--disable_warnings
+drop procedure if exists bug14498_1|
+drop procedure if exists bug14498_2|
+drop procedure if exists bug14498_3|
+drop procedure if exists bug14498_4|
+drop procedure if exists bug14498_5|
+--enable_warnings
+
+create procedure bug14498_1()
+begin
+  declare continue handler for sqlexception select 'error' as 'Handler';
+
+  if v then
+    select 'yes' as 'v';
+  else
+    select 'no' as 'v';
+  end if;
+  select 'done' as 'End';
+end|
+
+create procedure bug14498_2()
+begin
+  declare continue handler for sqlexception select 'error' as 'Handler';
+
+  while v do
+    select 'yes' as 'v';
+  end while;
+  select 'done' as 'End';
+end|
+
+create procedure bug14498_3()
+begin
+  declare continue handler for sqlexception select 'error' as 'Handler';
+
+  repeat
+    select 'maybe' as 'v';
+  until v end repeat;
+  select 'done' as 'End';
+end|
+
+create procedure bug14498_4()
+begin
+  declare continue handler for sqlexception select 'error' as 'Handler';
+
+  case v
+  when 1 then
+    select '1' as 'v';
+  when 2 then
+    select '2' as 'v';
+  else
+    select '?' as 'v';
+  end case;
+  select 'done' as 'End';
+end|
+
+create procedure bug14498_5()
+begin
+  declare continue handler for sqlexception select 'error' as 'Handler';
+
+  case
+  when v = 1 then
+    select '1' as 'v';
+  when v = 2 then
+    select '2' as 'v';
+  else
+    select '?' as 'v';
+  end case;
+  select 'done' as 'End';
+end|
+
+call bug14498_1()|
+call bug14498_2()|
+call bug14498_3()|
+call bug14498_4()|
+call bug14498_5()|
+
+drop procedure bug14498_1|
+drop procedure bug14498_2|
+drop procedure bug14498_3|
+drop procedure bug14498_4|
+drop procedure bug14498_5|
+
+#
+# BUG#15231: Stored procedure bug with not found condition handler
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug15231_1|
+drop procedure if exists bug15231_2|
+drop procedure if exists bug15231_3|
+drop procedure if exists bug15231_4|
+--enable_warnings
+
+create table t3 (id int not null)|
+  
+create procedure bug15231_1()
+begin
+  declare xid integer;
+  declare xdone integer default 0;
+  declare continue handler for not found set xdone = 1;
+
+  set xid=null;
+  call bug15231_2(xid);
+  select xid, xdone;
+end|
+
+create procedure bug15231_2(inout ioid integer)
+begin
+  select "Before NOT FOUND condition is triggered" as '1';
+  select id into ioid from t3 where id=ioid;
+  select "After NOT FOUND condtition is triggered" as '2';
+
+  if ioid is null then
+    set ioid=1;
+  end if;
+end|
+
+create procedure bug15231_3()
+begin
+  declare exit handler for sqlwarning
+    select 'Caught it (wrong)' as 'Result';
+
+  call bug15231_4();
+end|
+
+create procedure bug15231_4()
+begin
+  declare x decimal(2,1);
+
+  set x = 'zap';
+  select 'Missed it (correct)' as 'Result';
+end|
+
+call bug15231_1()|
+call bug15231_3()|
+
+drop table if exists t3|
+drop procedure if exists bug15231_1|
+drop procedure if exists bug15231_2|
+drop procedure if exists bug15231_3|
+drop procedure if exists bug15231_4|
+
+
+#
+# BUG#15011: error handler in nested block not activated
+#
+--disable_warnings
+drop procedure if exists bug15011|
+--enable_warnings
+
+create table t3 (c1 int primary key)|
+
+insert into t3 values (1)|
+
+create procedure bug15011()
+  deterministic
+begin
+  declare continue handler for 1062
+    select 'Outer' as 'Handler';
+
+  begin
+    declare continue handler for 1062
+      select 'Inner' as 'Handler';
+
+    insert into t3 values (1);
+  end;
+end|
+
+call bug15011()|
+
+drop procedure bug15011|
+drop table t3|
+
+
+#
+# BUG#NNNN: New bug synopsis
+#
+#--disable_warnings
+#drop procedure if exists bugNNNN|
+#--enable_warnings
+#create procedure bugNNNN...
+
+# Add bugs above this line. Use existing tables t1 and t2 when
+# practical, or create table t3, t4 etc temporarily (and drop them).
+delimiter ;|
+drop table t1,t2;
diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test
new file mode 100644
index 00000000000..3854297ec0c
--- /dev/null
+++ b/mysql-test/t/sp_notembedded.test
@@ -0,0 +1,262 @@
+# Can't test with embedded server
+-- source include/not_embedded.inc
+
+delimiter |;
+
+#
+# BUG#4902: Stored procedure with SHOW WARNINGS leads to packet error
+#
+# Added tests for show grants command
+--disable_warnings
+drop procedure if exists bug4902|
+--enable_warnings
+create procedure bug4902()
+begin
+  show grants for 'root'@'localhost';
+end|
+--disable_parsing
+show binlog events;
+show storage engines;
+show master status;
+show slave hosts;
+show slave status;
+--enable_parsing
+
+call bug4902()|
+call bug4902()|
+
+drop procedure bug4902|
+
+# We need separate SP for SHOW PROCESSLIST  since we want use replace_column
+--disable_warnings
+drop procedure if exists bug4902_2|
+--enable_warnings
+create procedure bug4902_2()
+begin
+  show processlist;
+end|
+--replace_column 1 # 6 # 3 localhost
+call bug4902_2()|
+--replace_column 1 # 6 # 3 localhost
+call bug4902_2()|
+drop procedure bug4902_2|
+
+
+#
+# BUG#5278: Stored procedure packets out of order if SET PASSWORD.
+#
+--disable_warnings
+drop function if exists bug5278|
+--enable_warnings
+create function bug5278 () returns char
+begin
+  SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass');
+  return 'okay';
+end|
+
+--error 1133
+select bug5278()|
+--error 1133
+select bug5278()|
+drop function bug5278|
+
+
+--disable_warnings
+drop table if exists t1|
+--enable_warnings
+create table t1 (
+	id   char(16) not null default '',
+        data int not null
+)|
+#
+# BUG#3583: query cache doesn't work for stored procedures
+#
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+--disable_warnings
+drop procedure if exists bug3583|
+--enable_warnings
+create procedure bug3583()
+begin
+  declare c int;
+
+  select * from t1;
+  select count(*) into c from t1;
+  select c;
+end|
+
+insert into t1 values ("x", 3), ("y", 5)|
+set @x = @@query_cache_size|
+set global query_cache_size = 10*1024*1024|
+
+flush status|
+flush query cache|
+show status like 'Qcache_hits'|
+call bug3583()|
+show status like 'Qcache_hits'|
+call bug3583()|
+call bug3583()|
+show status like 'Qcache_hits'|
+
+set global query_cache_size = @x|
+flush status|
+flush query cache|
+delete from t1|
+drop procedure bug3583|
+drop table t1;
+
+#
+# BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY
+#
+--disable_warnings
+drop procedure if exists bug6807|
+--enable_warnings
+create procedure bug6807()
+begin
+  declare id int;
+
+  set id = connection_id();
+  kill query id;
+  select 'Not reached';
+end|
+
+--error 1317
+call bug6807()|
+--error 1317
+call bug6807()|
+
+drop procedure bug6807|
+
+
+#
+# BUG#10100: function (and stored procedure?) recursivity problem
+#
+--disable_warnings
+drop function if exists bug10100f|
+drop procedure if exists bug10100p|
+drop procedure if exists bug10100t|
+drop procedure if exists bug10100pt|
+drop procedure if exists bug10100pv|
+drop procedure if exists bug10100pd|
+drop procedure if exists bug10100pc|
+--enable_warnings
+# routines with simple recursion
+create function bug10100f(prm int) returns int
+begin
+  if prm > 1 then
+    return prm * bug10100f(prm - 1);
+  end if;
+  return 1;
+end|
+create procedure bug10100p(prm int, inout res int)
+begin
+  set res = res * prm;
+  if prm > 1 then
+    call bug10100p(prm - 1, res);
+  end if;
+end|
+create procedure bug10100t(prm int)
+begin
+  declare res int;
+  set res = 1;
+  call bug10100p(prm, res);
+  select res;
+end|
+
+# a procedure which use tables and recursion
+create table t3 (a int)|
+insert into t3 values (0)|
+create view v1 as select a from t3;
+create procedure bug10100pt(level int, lim int)
+begin
+  if level < lim then
+    update t3 set a=level;
+    FLUSH TABLES;
+    call bug10100pt(level+1, lim);
+  else
+    select * from t3;
+  end if;
+end|
+# view & recursion
+create procedure bug10100pv(level int, lim int)
+begin
+  if level < lim then
+    update v1 set a=level;
+    FLUSH TABLES;
+    call bug10100pv(level+1, lim);
+  else
+    select * from v1;
+  end if;
+end|
+# dynamic sql & recursion
+prepare stmt2 from "select * from t3;";
+create procedure bug10100pd(level int, lim int)
+begin
+  if level < lim then
+    select level;
+    prepare stmt1 from "update t3 set a=a+2";
+    execute stmt1;
+    FLUSH TABLES;
+    execute stmt1;
+    FLUSH TABLES;
+    execute stmt1;
+    FLUSH TABLES;
+    deallocate prepare stmt1;
+    execute stmt2;
+    select * from t3;
+    call bug10100pd(level+1, lim);
+  else
+    execute stmt2;
+  end if;
+end|
+# cursor & recursion
+create procedure bug10100pc(level int, lim int)
+begin
+  declare lv int;
+  declare c cursor for select a from t3;
+  open c;
+  if level < lim then
+    select level;
+    fetch c into lv;
+    select lv;
+    update t3 set a=level+lv;
+    FLUSH TABLES;
+    call bug10100pc(level+1, lim);
+  else
+    select * from t3;
+  end if;
+  close c;
+end|
+
+#end of the stack checking
+set @@max_sp_recursion_depth=255|
+set @var=1|
+#disable log because error about stack overrun contains numbers which
+#depend on a system
+-- disable_result_log
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100p(255, @var)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pt(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pv(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pd(1,255)|
+-- error ER_STACK_OVERRUN_NEED_MORE
+call bug10100pc(1,255)|
+-- enable_result_log
+set @@max_sp_recursion_depth=0|
+
+deallocate prepare stmt2|
+
+drop function bug10100f|
+drop procedure bug10100p|
+drop procedure bug10100t|
+drop procedure bug10100pt|
+drop procedure bug10100pv|
+drop procedure bug10100pd|
+drop procedure bug10100pc|
+drop view v1|
+
+delimiter ;|
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 9e09b215951..733403f482e 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1962,12 +1962,6 @@ insert into t1 values ('1');
 select * from (select max(fld) from t1) as foo;
 drop table t1;
 
-#
-# BUG #10308: purge log with subselect
-#
-
-purge master logs before (select adddate(current_timestamp(), interval -4 day));
-
 #
 # Test for bug #11762: subquery with an aggregate function in HAVING
 #
diff --git a/mysql-test/t/subselect_notembedded.test b/mysql-test/t/subselect_notembedded.test
new file mode 100644
index 00000000000..c5b23f6dac8
--- /dev/null
+++ b/mysql-test/t/subselect_notembedded.test
@@ -0,0 +1,8 @@
+-- source include/not_embedded.inc
+
+#
+# BUG #10308: purge log with subselect
+#
+
+purge master logs before (select adddate(current_timestamp(), interval -4 day));
+
diff --git a/mysql-test/t/temp_table.test b/mysql-test/t/temp_table.test
index 6b3991c9c78..3920b305b78 100644
--- a/mysql-test/t/temp_table.test
+++ b/mysql-test/t/temp_table.test
@@ -1,3 +1,5 @@
+# mysqltest should be fixed
+-- source include/not_embedded.inc
 #
 # Test of temporary tables
 #
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index ed44bf3b7c0..77a903e2d3c 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2075,16 +2075,6 @@ order by users_names;
 drop view v1, v2;
 drop table t1, t2;
 
-#
-# DEFINER information check
-#
--- error ER_MALFORMED_DEFINER
-create definer=some_user@`` sql security invoker view v1 as select 1;
-create definer=some_user@localhost sql security invoker view v1 as select 1;
-show create view v1;
-drop view v1;
-
-#
 # Bug #6808 - Views: CREATE VIEW v ... FROM t AS v fails
 #
 
diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test
index 2490b8808da..87478a9d4b2 100644
--- a/mysql-test/t/view_grant.test
+++ b/mysql-test/t/view_grant.test
@@ -702,3 +702,14 @@ drop database mysqltest;
 disconnect user1;
 disconnect root;
 connection default;
+
+#
+# DEFINER information check
+#
+-- error ER_MALFORMED_DEFINER
+create definer=some_user@`` sql security invoker view v1 as select 1;
+create definer=some_user@localhost sql security invoker view v1 as select 1;
+show create view v1;
+drop view v1;
+
+
diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test
index 1c9efa7c07d..1fef3deea3c 100644
--- a/mysql-test/t/wait_timeout.test
+++ b/mysql-test/t/wait_timeout.test
@@ -1,3 +1,6 @@
+# This tests not performed with embedded server
+-- source include/not_embedded.inc
+
 #
 # Bug #8731: wait_timeout does not work on Mac OS X
 #
diff --git a/mysys/mf_dirname.c b/mysys/mf_dirname.c
index 45bf4d56c31..9206aa28078 100644
--- a/mysys/mf_dirname.c
+++ b/mysys/mf_dirname.c
@@ -108,7 +108,7 @@ char *convert_dirname(char *to, const char *from, const char *from_end)
 
 #if FN_LIBCHAR != '/' || defined(FN_C_BEFORE_DIR_2)
   {
-    for (; *from && from != from_end; from++)
+    for (; from != from_end && *from ; from++)
     {
       if (*from == '/')
 	*to++= FN_LIBCHAR;
diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c
index e2875d9e53e..49c23aaeae5 100644
--- a/mysys/my_bitmap.c
+++ b/mysys/my_bitmap.c
@@ -40,7 +40,7 @@
 #include <my_bitmap.h>
 #include <m_string.h>
 
-static inline void bitmap_lock(MY_BITMAP *map)
+static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused)))
 {
 #ifdef THREAD
   if (map->mutex)
@@ -48,7 +48,7 @@ static inline void bitmap_lock(MY_BITMAP *map)
 #endif
 }
 
-static inline void bitmap_unlock(MY_BITMAP *map)
+static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused)))
 {
 #ifdef THREAD
   if (map->mutex)
diff --git a/scripts/mysql_fix_privilege_tables.sql b/scripts/mysql_fix_privilege_tables.sql
index ed0f9a6c68f..41d468fd3cf 100644
--- a/scripts/mysql_fix_privilege_tables.sql
+++ b/scripts/mysql_fix_privilege_tables.sql
@@ -521,3 +521,9 @@ ALTER TABLE proc  MODIFY db
                          char(77) collate utf8_bin DEFAULT '' NOT NULL,
                   MODIFY comment
                          char(64) collate utf8_bin DEFAULT '' NOT NULL;
+
+# Activate the new, possible modified privilege tables
+# This should not be needed, but gives us some extra testing that the above
+# changes was correct
+
+flush privileges;
diff --git a/sql-common/client.c b/sql-common/client.c
index e51d2bb848f..2d826df0662 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1563,7 +1563,8 @@ static MYSQL_METHODS client_methods=
   NULL,
   cli_read_statistics,
   cli_read_query_result,
-  cli_read_change_user_result
+  cli_read_change_user_result,
+  cli_read_binary_rows
 #endif
 };
 
@@ -2340,8 +2341,9 @@ static void mysql_close_free(MYSQL *mysql)
   my_free(mysql->user,MYF(MY_ALLOW_ZERO_PTR));
   my_free(mysql->passwd,MYF(MY_ALLOW_ZERO_PTR));
   my_free(mysql->db,MYF(MY_ALLOW_ZERO_PTR));
+  my_free(mysql->info_buffer,MYF(MY_ALLOW_ZERO_PTR));
   /* Clear pointers for better safety */
-  mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
+  mysql->info_buffer=mysql->host_info=mysql->user=mysql->passwd=mysql->db=0;
 }
 
 
@@ -2477,8 +2479,7 @@ get_info:
   if (!(mysql->server_status & SERVER_STATUS_AUTOCOMMIT))
     mysql->server_status|= SERVER_STATUS_IN_TRANS;
 
-  if (!(fields=(*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,
-					    protocol_41(mysql) ? 7 : 5)))
+  if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5)))
     DBUG_RETURN(1);
   if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,
 				    (uint) field_count,0,
diff --git a/sql/item.cc b/sql/item.cc
index 367452444d2..3d454969c1d 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -375,9 +375,6 @@ void Item::print_item_w_name(String *str)
 void Item::cleanup()
 {
   DBUG_ENTER("Item::cleanup");
-  DBUG_PRINT("info", ("Item: 0x%lx, Type: %d, name %s, original name %s",
-		      this, (int)type(), name ? name : "(null)",
-                      orig_name ? orig_name : "null"));
   fixed=0;
   marker= 0;
   if (orig_name)
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 00ddde46127..37a135fa063 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2387,9 +2387,7 @@ static int my_message_sql(uint error, const char *str, myf MyFlags)
     {
       NET *net= &thd->net;
       net->report_error= 1;
-#ifndef EMBEDDED_LIBRARY  /* TODO query cache in embedded library*/
       query_cache_abort(net);
-#endif
       if (!net->last_error[0])			// Return only first message
       {
 	strmake(net->last_error, str, sizeof(net->last_error)-1);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 15f7049ec2f..650bd8fc58f 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -29,6 +29,7 @@
 
 static const unsigned int PACKET_BUFFER_EXTRA_ALLOC= 1024;
 static void write_eof_packet(THD *thd, NET *net);
+void net_send_error_packet(THD *thd, uint sql_errno, const char *err);
 
 #ifndef EMBEDDED_LIBRARY
 bool Protocol::net_store_data(const char *from, uint length)
@@ -56,10 +57,6 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
 
 void net_send_error(THD *thd, uint sql_errno, const char *err)
 {
-#ifndef EMBEDDED_LIBRARY 
-  uint length;
-  char buff[MYSQL_ERRMSG_SIZE+2], *pos;
-#endif
   NET *net= &thd->net;
   bool generate_warning= thd->killed != THD::KILL_CONNECTION;
   DBUG_ENTER("net_send_error");
@@ -106,42 +103,8 @@ void net_send_error(THD *thd, uint sql_errno, const char *err)
     push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, sql_errno, err);
   }
 
-#ifdef EMBEDDED_LIBRARY
-  net->last_errno= sql_errno;
-  strmake(net->last_error, err, sizeof(net->last_error)-1);
-  strmov(net->sqlstate, mysql_errno_to_sqlstate(sql_errno));
-#else
+  net_send_error_packet(thd, sql_errno, err);
 
-  if (net->vio == 0)
-  {
-    if (thd->bootstrap)
-    {
-      /* In bootstrap it's ok to print on stderr */
-      fprintf(stderr,"ERROR: %d  %s\n",sql_errno,err);
-    }
-    DBUG_VOID_RETURN;
-  }
-
-  if (net->return_errno)
-  {				// new client code; Add errno before message
-    int2store(buff,sql_errno);
-    pos= buff+2;
-    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
-    {
-      /* The first # is to make the protocol backward compatible */
-      buff[2]= '#';
-      pos= strmov(buff+3, mysql_errno_to_sqlstate(sql_errno));
-    }
-    length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
-    err=buff;
-  }
-  else
-  {
-    length=(uint) strlen(err);
-    set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
-  }
-  VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
-#endif  /* EMBEDDED_LIBRARY*/
   thd->is_fatal_error=0;			// Error message is given
   thd->net.report_error= 0;
 
@@ -430,6 +393,47 @@ bool send_old_password_request(THD *thd)
   return my_net_write(net, eof_buff, 1) || net_flush(net);
 }
 
+
+void net_send_error_packet(THD *thd, uint sql_errno, const char *err)
+{
+  NET *net= &thd->net;
+  uint length;
+  char buff[MYSQL_ERRMSG_SIZE+2], *pos;
+
+  DBUG_ENTER("send_error_packet");
+
+  if (net->vio == 0)
+  {
+    if (thd->bootstrap)
+    {
+      /* In bootstrap it's ok to print on stderr */
+      fprintf(stderr,"ERROR: %d  %s\n",sql_errno,err);
+    }
+    DBUG_VOID_RETURN;
+  }
+
+  if (net->return_errno)
+  {				// new client code; Add errno before message
+    int2store(buff,sql_errno);
+    pos= buff+2;
+    if (thd->client_capabilities & CLIENT_PROTOCOL_41)
+    {
+      /* The first # is to make the protocol backward compatible */
+      buff[2]= '#';
+      pos= strmov(buff+3, mysql_errno_to_sqlstate(sql_errno));
+    }
+    length= (uint) (strmake(pos, err, MYSQL_ERRMSG_SIZE-1) - buff);
+    err=buff;
+  }
+  else
+  {
+    length=(uint) strlen(err);
+    set_if_smaller(length,MYSQL_ERRMSG_SIZE-1);
+  }
+  VOID(net_write_command(net,(uchar) 255, "", 0, (char*) err,length));
+  DBUG_VOID_RETURN;
+}
+
 #endif /* EMBEDDED_LIBRARY */
 
 /*
diff --git a/sql/protocol.h b/sql/protocol.h
index 8d9da5774b2..85c22724b74 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -91,6 +91,12 @@ public:
   virtual bool store_date(TIME *time)=0;
   virtual bool store_time(TIME *time)=0;
   virtual bool store(Field *field)=0;
+#ifdef EMBEDDED_LIBRARY
+  int begin_dataset();
+  virtual void remove_last_row() {}
+#else
+  void remove_last_row() {}
+#endif
 };
 
 
@@ -117,6 +123,9 @@ public:
   virtual bool store(float nr, uint32 decimals, String *buffer);
   virtual bool store(double from, uint32 decimals, String *buffer);
   virtual bool store(Field *field);
+#ifdef EMBEDDED_LIBRARY
+  void remove_last_row();
+#endif
 };
 
 
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 37d4c80a0d0..2614a7cd5be 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -368,6 +368,15 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
   DESCRIPTION
     Marks all tables in the list which were used by current substatement
     (they are marked by its query_id) as free for reuse.
+
+  NOTE
+    The reason we reset query_id is that it's not enough to just test
+    if table->query_id != thd->query_id to know if a table is in use.
+
+    For example
+    SELECT f1_that_uses_t1() FROM t1;
+    In f1_that_uses_t1() we will see one instance of t1 where query_id is
+    set to query_id of original query.
 */
 
 static void mark_used_tables_as_free_for_reuse(THD *thd, TABLE *table)
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 2125201026a..59391a333c3 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -950,6 +950,7 @@ bool select_send::send_data(List<Item> &items)
     DBUG_RETURN(0);
   if (!thd->net.report_error)
     DBUG_RETURN(protocol->write());
+  protocol->remove_last_row();
   DBUG_RETURN(1);
 }
 
@@ -1981,10 +1982,8 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
   cuted_fields= 0;
   transaction.savepoints= 0;
 
-#ifndef EMBEDDED_LIBRARY
   /* Surpress OK packets in case if we will execute statements */
   net.no_send_ok= TRUE;
-#endif
 }
 
 
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 1672a5ea811..65e6ebea33e 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1102,13 +1102,16 @@ public:
 
 #ifdef EMBEDDED_LIBRARY
   struct st_mysql  *mysql;
-  struct st_mysql_data *data;
   unsigned long	 client_stmt_id;
   unsigned long  client_param_count;
   struct st_mysql_bind *client_params;
   char *extra_data;
   ulong extra_length;
-  String query_rest;
+  struct st_mysql_data *cur_data;
+  struct st_mysql_data *first_data;
+  struct st_mysql_data **data_tail;
+  void clear_data_list();
+  struct st_mysql_data *alloc_new_dataset();
 #endif
   NET	  net;				// client connection descriptor
   MEM_ROOT warn_root;			// For warnings and errors
@@ -1659,6 +1662,11 @@ public:
   */
   virtual void cleanup();
   void set_thd(THD *thd_arg) { thd= thd_arg; }
+#ifdef EMBEDDED_LIBRARY
+  virtual void begin_dataset() {}
+#else
+  void begin_dataset() {}
+#endif
 };
 
 
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc
index 89c160cd70a..33ad27b9d14 100644
--- a/sql/sql_cursor.cc
+++ b/sql/sql_cursor.cc
@@ -603,6 +603,7 @@ void Materialized_cursor::fetch(ulong num_rows)
   THD *thd= table->in_use;
 
   int res= 0;
+  result->begin_dataset();
   for (fetch_limit+= num_rows; fetch_count < fetch_limit; fetch_count++)
   {
     if ((res= table->file->rnd_next(table->record[0])))
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 978cab704c0..8b87c59cc64 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1724,13 +1724,10 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
       net->no_send_error= 0;
       /*
         Multiple queries exits, execute them individually
-	in embedded server - just store them to be executed later 
       */
-#ifndef EMBEDDED_LIBRARY
       if (thd->lock || thd->open_tables || thd->derived_tables ||
           thd->prelocked_mode)
         close_thread_tables(thd);
-#endif
       ulong length= (ulong)(packet_end-packet);
 
       log_slow_statement(thd);
@@ -1748,25 +1745,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
       thd->set_time(); /* Reset the query start time. */
       /* TODO: set thd->lex->sql_command to SQLCOM_END here */
       VOID(pthread_mutex_unlock(&LOCK_thread_count));
-#ifndef EMBEDDED_LIBRARY
       mysql_parse(thd, packet, length);
-#else
-      /*
-	'packet' can point inside the query_rest's buffer
-	so we have to do memmove here
-       */
-      if (thd->query_rest.length() > length)
-      {
-	memmove(thd->query_rest.c_ptr(), packet, length);
-	thd->query_rest.length(length);
-      }
-      else
-	thd->query_rest.copy(packet, length, thd->query_rest.charset());
-
-      thd->server_status&= ~ (SERVER_QUERY_NO_INDEX_USED |
-                              SERVER_QUERY_NO_GOOD_INDEX_USED);
-      break;
-#endif /*EMBEDDED_LIBRARY*/
     }
 
     if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -4273,10 +4252,8 @@ end_with_restore_list:
             goto error;
         }
 
-#ifndef EMBEDDED_LIBRARY
 	my_bool nsok= thd->net.no_send_ok;
 	thd->net.no_send_ok= TRUE;
-#endif
 	if (sp->m_flags & sp_head::MULTI_RESULTS)
 	{
 	  if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
@@ -4286,9 +4263,7 @@ end_with_restore_list:
               back
             */
 	    my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
-#ifndef EMBEDDED_LIBRARY
 	    thd->net.no_send_ok= nsok;
-#endif
 	    goto error;
 	  }
           /*
@@ -4305,18 +4280,14 @@ end_with_restore_list:
 				 sp->m_db.str, sp->m_name.str, TRUE, 0) ||
           sp_change_security_context(thd, sp, &save_ctx))
 	{
-#ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
-#endif
 	  goto error;
 	}
 	if (save_ctx &&
             check_routine_access(thd, EXECUTE_ACL,
                                  sp->m_db.str, sp->m_name.str, TRUE, 0))
 	{
-#ifndef EMBEDDED_LIBRARY
 	  thd->net.no_send_ok= nsok;
-#endif
 	  sp_restore_security_context(thd, save_ctx);
 	  goto error;
 	}
@@ -4348,9 +4319,7 @@ end_with_restore_list:
 	sp_restore_security_context(thd, save_ctx);
 #endif
 
-#ifndef EMBEDDED_LIBRARY
 	thd->net.no_send_ok= nsok;
-#endif
         thd->server_status&= ~bits_to_be_cleared;
 
 	if (!res)
@@ -4846,7 +4815,9 @@ end_with_restore_list:
     res= mysql_xa_recover(thd);
     break;
   default:
+#ifndef EMBEDDED_LIBRARY
     DBUG_ASSERT(0);                             /* Impossible */
+#endif
     send_ok(thd);
     break;
   }
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 5746e2a6f1a..332f699200e 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -92,6 +92,12 @@ public:
   virtual bool send_fields(List<Item> &list, uint flags);
   virtual bool send_data(List<Item> &items);
   virtual bool send_eof();
+#ifdef EMBEDDED_LIBRARY
+  void begin_dataset()
+  {
+    protocol.begin_dataset();
+  }
+#endif
 };
 
 /******************************************************************************
@@ -524,9 +530,10 @@ void set_param_time(Item_param *param, uchar **pos, ulong len)
 
 void set_param_datetime(Item_param *param, uchar **pos, ulong len)
 {
-  MYSQL_TIME *to= (MYSQL_TIME*)*pos;
+  MYSQL_TIME tm= *((MYSQL_TIME*)*pos);
+  tm.neg= 0;
 
-  param->set_time(to, MYSQL_TIMESTAMP_DATETIME,
+  param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME,
                   MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN);
 }
 

From f8386dfa4821b79b6f88f8d9950ed370ba22e508 Mon Sep 17 00:00:00 2001
From: unknown <dlenev@mysql.com>
Date: Fri, 24 Feb 2006 23:50:36 +0300
Subject: [PATCH 057/103] Fix for bug #13525 "Rename table does not keep info
 of triggers".

Let us transfer triggers associated with table when we rename it (but only if
we are not changing database to which table belongs, in the latter case we will
emit error).


mysql-test/r/trigger.result:
  Added test for bug #13525 "Rename table does not keep info of triggers".
mysql-test/t/trigger.test:
  Added test for bug #13525 "Rename table does not keep info of triggers".
sql/sql_rename.cc:
  rename_tables():
    Now after renaming table's .FRM file and updating handler data we call
    Table_triggers_list::change_table_name() which is reponsible for
    updating .TRG and .TRN files.
sql/sql_table.cc:
  mysql_alter_table():
    Now in case when ALTER should rename table we call
    Table_triggers_list::change_table_name() which is responsible
    for updating .TRG and .TRN files after renaming table.
sql/sql_trigger.cc:
  Added Table_triggers_list::change_table_name() method and
  change_table_name_in_triggers()/trignames() methods responsible for updating
  .TRG and .TRN files for table during its renaming.

  Two small cleanups - removed versioning for .TRG files (since it was not working
  before anyway) and emphasized that type of lock specified in tables list is
  unimportant for DROP TABLE (since this statement uses name-locking).
sql/sql_trigger.h:
  Table_triggers_list:
    Added on_table_names_list member to store pointers and lenghts of
    "ON table_name" parts in triggers' definitions to be able easily
    change them during RENAME TABLE.
    Added change_table_name() method and change_table_name_in_trignames/triggers()
    helper methods responsible for updating .TRG and .TRN files.
sql/sql_yacc.yy:
  trigger_tail:
    To be able properly update triggers' definitions with new table names
    when renaming tables we need to know where in CREATE TRIGGER statement
    "ON db_name.table_name" part resides.
    Small cleanup - let us emphasize that for CREATE TRIGGER statement
    lock type which is specified in table list is unimportant since
    name-locking is used.
---
 mysql-test/r/trigger.result | 103 ++++++++++++-
 mysql-test/t/trigger.test   |  87 ++++++++++-
 sql/sql_rename.cc           |  23 ++-
 sql/sql_table.cc            |  13 +-
 sql/sql_trigger.cc          | 290 +++++++++++++++++++++++++++++++++---
 sql/sql_trigger.h           |  17 ++-
 sql/sql_yacc.yy             |  16 +-
 7 files changed, 513 insertions(+), 36 deletions(-)

diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index e0048515fed..24b881d4bfa 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -1,4 +1,4 @@
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t4;
 drop view if exists v1;
 drop database if exists mysqltest;
 drop function if exists f1;
@@ -786,3 +786,104 @@ create trigger test.t1_bi before insert on t1 for each row set @a:=0;
 ERROR 3D000: No database selected
 drop trigger t1_bi;
 ERROR 3D000: No database selected
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+@a
+101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	 set @a:=new.id
+rename table t1 to t2;
+insert into t2 values (102);
+select @a;
+@a
+102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t2	 set @a:=new.id
+alter table t2 rename to t3;
+insert into t3 values (103);
+select @a;
+@a
+103
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t3	 set @a:=new.id
+alter table t3 rename to t4, add column val int default 0;
+insert into t4 values (104, 1);
+select @a;
+@a
+104
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t4	 set @a:=new.id
+drop trigger t1_bi;
+drop table t4;
+create database mysqltest;
+use mysqltest;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+@a
+101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+mysqltest	t1_bi	mysqltest	t1	 set @a:=new.id
+rename table t1 to test.t2;
+ERROR HY000: Trigger in wrong schema
+insert into t1 values (102);
+select @a;
+@a
+102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+mysqltest	t1_bi	mysqltest	t1	 set @a:=new.id
+drop trigger test.t1_bi;
+ERROR HY000: Trigger does not exist
+drop trigger t1_bi;
+drop table t1;
+drop database mysqltest;
+use test;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+create trigger t1_ai after insert on t1 for each row set @b:=new.id;
+insert into t1 values (101);
+select @a, @b;
+@a	@b
+101	101
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	 set @a:=new.id
+test	t1_ai	test	t1	 set @b:=new.id
+rename table t1 to t2;
+ERROR HY000: Can't create/write to file './test/t1_ai.TRN~' (Errcode: 13)
+insert into t1 values (102);
+select @a, @b;
+@a	@b
+102	102
+select trigger_schema, trigger_name, event_object_schema,
+event_object_table, action_statement from information_schema.triggers
+where event_object_schema = 'test';
+trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
+test	t1_bi	test	t1	 set @a:=new.id
+test	t1_ai	test	t1	 set @b:=new.id
+drop trigger t1_bi;
+drop trigger t1_ai;
+drop table t1;
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index b4074897689..8c849715274 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -3,7 +3,7 @@
 #
 
 --disable_warnings
-drop table if exists t1, t2, t3;
+drop table if exists t1, t2, t3, t4;
 drop view if exists v1;
 drop database if exists mysqltest;
 drop function if exists f1;
@@ -961,3 +961,88 @@ create trigger test.t1_bi before insert on t1 for each row set @a:=0;
 --error ER_NO_DB_ERROR
 drop trigger t1_bi;
 connection default;
+
+#
+# Test for bug #13525 "Rename table does not keep info of triggers"
+#
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+rename table t1 to t2;
+# Trigger should work after rename
+insert into t2 values (102);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# Let us check that the same works for simple ALTER TABLE ... RENAME
+alter table t2 rename to t3;
+insert into t3 values (103);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# And for more complex ALTER TABLE
+alter table t3 rename to t4, add column val int default 0;
+insert into t4 values (104, 1);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# .TRN file should be updated with new table name
+drop trigger t1_bi;
+drop table t4;
+# Rename between different databases if triggers exist should fail
+create database mysqltest;
+use mysqltest;
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+insert into t1 values (101);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+--error ER_TRG_IN_WRONG_SCHEMA
+rename table t1 to test.t2;
+insert into t1 values (102);
+select @a;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test' or event_object_schema = 'mysqltest';
+# There should be no fantom .TRN files 
+--error ER_TRG_DOES_NOT_EXIST
+drop trigger test.t1_bi;
+drop trigger t1_bi;
+drop table t1;
+drop database mysqltest;
+use test;
+# And now let us check that the properly handle rename if there is some
+# error during it (that we rollback such renames completely).
+create table t1 (id int);
+create trigger t1_bi before insert on t1 for each row set @a:=new.id;
+create trigger t1_ai after insert on t1 for each row set @b:=new.id;
+insert into t1 values (101);
+select @a, @b;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+# Trick which makes update of second .TRN file impossible
+system echo dummy >var/master-data/test/t1_ai.TRN~;
+system chmod 000 var/master-data/test/t1_ai.TRN~;
+--error 1
+rename table t1 to t2;
+# 't1' should be still there and triggers should work correctly
+insert into t1 values (102);
+select @a, @b;
+select trigger_schema, trigger_name, event_object_schema,
+       event_object_table, action_statement from information_schema.triggers
+       where event_object_schema = 'test';
+system chmod 600 var/master-data/test/t1_ai.TRN;
+# Let us check that updates to .TRN files were rolled back too
+drop trigger t1_bi;
+drop trigger t1_ai;
+drop table t1;
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index 80fcb973028..74951029de9 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -19,6 +19,7 @@
 */
 
 #include "mysql_priv.h"
+#include "sql_trigger.h"
 
 
 static TABLE_LIST *rename_tables(THD *thd, TABLE_LIST *table_list,
@@ -176,8 +177,26 @@ rename_tables(THD *thd, TABLE_LIST *table_list, bool skip_error)
         if (table_type == DB_TYPE_UNKNOWN) 
           my_error(ER_FILE_NOT_FOUND, MYF(0), name, my_errno);
         else
-          rc= mysql_rename_table(table_type, ren_table->db, old_alias,
-                                 new_table->db, new_alias);
+        {
+          if (!(rc= mysql_rename_table(table_type, ren_table->db, old_alias,
+                                       new_table->db, new_alias)))
+          {
+            if ((rc= Table_triggers_list::change_table_name(thd, ren_table->db,
+                                                            old_alias,
+                                                            new_table->db,
+                                                            new_alias)))
+            {
+              /*
+                We've succeeded in renaming table's .frm and in updating
+                corresponding handler data, but have failed to update table's
+                triggers appropriately. So let us revert operations on .frm
+                and handler's data and report about failure to rename table.
+              */
+              (void) mysql_rename_table(table_type, new_table->db, new_alias,
+                                        ren_table->db, old_alias);
+            }
+          }
+        }
         break;
       }
       case FRMTYPE_VIEW:
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index ba4a606537f..b3fc24f3a4d 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -3258,6 +3258,13 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
 	close_cached_table(thd, table);
 	if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias))
 	  error= -1;
+        else if (Table_triggers_list::change_table_name(thd, db, table_name,
+                                                        new_db, new_alias))
+        {
+          VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
+                                  table_name));
+          error= -1;
+        }
       }
       VOID(pthread_mutex_unlock(&LOCK_open));
     }
@@ -3806,7 +3813,11 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
     VOID(quick_rm_table(new_db_type,new_db,tmp_name));
   }
   else if (mysql_rename_table(new_db_type,new_db,tmp_name,new_db,
-			      new_alias))
+			      new_alias) ||
+           (new_name != table_name || new_db != db) && // we also do rename
+           Table_triggers_list::change_table_name(thd, db, table_name,
+                                                  new_db, new_alias))
+       
   {						// Try to get everything back
     error=1;
     VOID(quick_rm_table(new_db_type,new_db,new_alias));
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 8a26c2bafa2..90c62838759 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -58,7 +58,6 @@ static File_option triggers_file_parameters[]=
 */
 
 static const int TRG_NUM_REQUIRED_PARAMETERS= 4;
-static const int TRG_MAX_VERSIONS= 3;
 
 /*
   Structure representing contents of .TRN file which are used to support
@@ -455,8 +454,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
                                definer_host->str, NullS) - trg_definer->str;
 
   if (!sql_create_definition_file(&dir, &file, &triggers_file_type,
-                                  (gptr)this, triggers_file_parameters,
-                                  TRG_MAX_VERSIONS))
+                                  (gptr)this, triggers_file_parameters, 0))
     return 0;
 
 err_with_cleanup:
@@ -480,7 +478,8 @@ err_with_cleanup:
     True  - error
 */
 
-static bool rm_trigger_file(char *path, char *db, char *table_name)
+static bool rm_trigger_file(char *path, const char *db,
+                            const char *table_name)
 {
   strxnmov(path, FN_REFLEN, mysql_data_home, "/", db, "/", table_name,
            triggers_file_ext, NullS);
@@ -504,7 +503,8 @@ static bool rm_trigger_file(char *path, char *db, char *table_name)
     True  - error
 */
 
-static bool rm_trigname_file(char *path, char *db, char *trigger_name)
+static bool rm_trigname_file(char *path, const char *db,
+                             const char *trigger_name)
 {
   strxnmov(path, FN_REFLEN, mysql_data_home, "/", db, "/", trigger_name,
            trigname_file_ext, NullS);
@@ -513,6 +513,38 @@ static bool rm_trigname_file(char *path, char *db, char *trigger_name)
 }
 
 
+/*
+  Helper function that saves .TRG file for Table_triggers_list object.
+
+  SYNOPSIS
+    save_trigger_file()
+      triggers    Table_triggers_list object for which file should be saved
+      db          Name of database for subject table
+      table_name  Name of subject table
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Error
+*/
+
+static bool save_trigger_file(Table_triggers_list *triggers, const char *db,
+                              const char *table_name)
+{
+  char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
+  LEX_STRING dir, file;
+
+  strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", db, "/", NullS);
+  dir.length= unpack_filename(dir_buff, dir_buff);
+  dir.str= dir_buff;
+  file.length=  strxnmov(file_buff, FN_REFLEN, table_name, triggers_file_ext,
+                         NullS) - file_buff;
+  file.str= file_buff;
+
+  return sql_create_definition_file(&dir, &file, &triggers_file_type,
+                                    (gptr)triggers, triggers_file_parameters, 0);
+}
+
+
 /*
   Drop trigger for table.
 
@@ -566,20 +598,7 @@ bool Table_triggers_list::drop_trigger(THD *thd, TABLE_LIST *tables)
       }
       else
       {
-        char dir_buff[FN_REFLEN], file_buff[FN_REFLEN];
-        LEX_STRING dir, file;
-
-        strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", tables->db,
-                 "/", NullS);
-        dir.length= unpack_filename(dir_buff, dir_buff);
-        dir.str= dir_buff;
-        file.length=  strxnmov(file_buff, FN_REFLEN, tables->table_name,
-                               triggers_file_ext, NullS) - file_buff;
-        file.str= file_buff;
-
-        if (sql_create_definition_file(&dir, &file, &triggers_file_type,
-                                       (gptr)this, triggers_file_parameters,
-                                       TRG_MAX_VERSIONS))
+        if (save_trigger_file(this, tables->db, tables->table_name))
           return 1;
       }
 
@@ -819,13 +838,13 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
       if (!names_only && triggers->prepare_record1_accessors(table))
         DBUG_RETURN(1);
 
-      char *trg_name_buff;
       List_iterator_fast<ulonglong> itm(triggers->definition_modes_list);
       List_iterator_fast<LEX_STRING> it_definer(triggers->
                                                 definers_list);
       LEX *old_lex= thd->lex, lex;
       sp_rcontext *save_spcont= thd->spcont;
       ulong save_sql_mode= thd->variables.sql_mode;
+      LEX_STRING *on_table_name;
 
       thd->lex= &lex;
 
@@ -890,6 +909,21 @@ bool Table_triggers_list::check_n_load(THD *thd, const char *db,
                                            &table->mem_root))
             goto err_with_lex_cleanup;
 
+        if (!(on_table_name= (LEX_STRING*) alloc_root(&table->mem_root,
+                                                      sizeof(LEX_STRING))))
+          goto err_with_lex_cleanup;
+        *on_table_name= lex.ident;
+        if (triggers->on_table_names_list.push_back(on_table_name, &table->mem_root))
+          goto err_with_lex_cleanup;
+
+        /*
+          Let us check that we correctly update trigger definitions when we
+          rename tables with triggers.
+        */
+        DBUG_ASSERT(!my_strcasecmp(table_alias_charset, lex.query_tables->db, db) &&
+                    !my_strcasecmp(table_alias_charset, lex.query_tables->table_name,
+                                   table_name));
+
         if (names_only)
         {
           lex_end(&lex);
@@ -1055,7 +1089,7 @@ static TABLE_LIST *add_table_for_trigger(THD *thd, sp_name *trig)
   lex->query_tables= 0;
   lex->query_tables_last= &lex->query_tables;
   DBUG_RETURN(sp_add_to_query_tables(thd, lex, trig->m_db.str,
-                                     trigname.trigger_table.str, TL_WRITE));
+                                     trigname.trigger_table.str, TL_IGNORE));
 }
 
 
@@ -1125,6 +1159,220 @@ end:
 }
 
 
+/*
+  Update .TRG file after renaming triggers' subject table
+  (change name of table in triggers' definitions).
+
+  SYNOPSIS
+    change_table_name_in_triggers()
+      thd                 Thread context
+      db_name             Database of subject table
+      old_table_name      Old subject table's name
+      new_table_name      New subject table's name
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Failure
+*/
+
+bool
+Table_triggers_list::change_table_name_in_triggers(THD *thd,
+                                                   const char *db_name,
+                                                   LEX_STRING *old_table_name,
+                                                   LEX_STRING *new_table_name)
+{
+  char path_buff[FN_REFLEN];
+  LEX_STRING *def, *on_table_name, new_def;
+  ulonglong *sql_mode;
+  ulong save_sql_mode= thd->variables.sql_mode;
+  List_iterator_fast<LEX_STRING> it_def(definitions_list);
+  List_iterator_fast<LEX_STRING> it_on_table_name(on_table_names_list);
+  List_iterator_fast<ulonglong> it_mode(definition_modes_list);
+  uint on_q_table_name_len, before_on_len;
+  String buff;
+
+  DBUG_ASSERT(definitions_list.elements == on_table_names_list.elements &&
+              definitions_list.elements == definition_modes_list.elements);
+
+  while ((def= it_def++))
+  {
+    on_table_name= it_on_table_name++;
+    thd->variables.sql_mode= *(it_mode++);
+
+    /* Construct CREATE TRIGGER statement with new table name. */
+    buff.length(0);
+    before_on_len= on_table_name->str - def->str;
+    buff.append(def->str, before_on_len);
+    buff.append(STRING_WITH_LEN("ON "));
+    append_identifier(thd, &buff, new_table_name->str, new_table_name->length);
+    on_q_table_name_len= buff.length() - before_on_len;
+    buff.append(on_table_name->str + on_table_name->length,
+                def->length - (before_on_len + on_table_name->length));
+    /*
+      It is OK to allocate some memory on table's MEM_ROOT since this
+      table instance will be thrown out at the end of rename anyway.
+    */
+    new_def.str= memdup_root(&table->mem_root, buff.ptr(), buff.length());
+    new_def.length= buff.length();
+    on_table_name->str= new_def.str + before_on_len;
+    on_table_name->length= on_q_table_name_len;
+    *def= new_def;
+  }
+
+  thd->variables.sql_mode= save_sql_mode;
+
+  if (thd->is_fatal_error)
+    return TRUE; /* OOM */
+
+  if (save_trigger_file(this, db_name, new_table_name->str))
+    return TRUE;
+  if (rm_trigger_file(path_buff, db_name, old_table_name->str))
+  {
+    (void) rm_trigger_file(path_buff, db_name, new_table_name->str);
+    return TRUE;
+  }
+  return FALSE;
+}
+
+
+/*
+  Iterate though Table_triggers_list::names_list list and update .TRN files
+  after renaming triggers' subject table.
+
+  SYNOPSIS
+    change_table_name_in_trignames()
+      db_name             Database of subject table
+      new_table_name      New subject table's name
+      stopper             Pointer to Table_triggers_list::names_list at
+                          which we should stop updating.
+
+  RETURN VALUE
+    0      Success
+    non-0  Failure, pointer to Table_triggers_list::names_list element
+           for which update failed.
+*/
+
+LEX_STRING*
+Table_triggers_list::change_table_name_in_trignames(const char *db_name,
+                                                    LEX_STRING *new_table_name,
+                                                    LEX_STRING *stopper)
+{
+  char dir_buff[FN_REFLEN], trigname_buff[FN_REFLEN];
+  struct st_trigname trigname;
+  LEX_STRING dir, trigname_file;
+  LEX_STRING *trigger;
+  List_iterator_fast<LEX_STRING> it_name(names_list);
+
+  strxnmov(dir_buff, FN_REFLEN, mysql_data_home, "/", db_name, "/", NullS);
+  dir.length= unpack_filename(dir_buff, dir_buff);
+  dir.str= dir_buff;
+
+  while ((trigger= it_name++) != stopper)
+  {
+    trigname_file.length= strxnmov(trigname_buff, FN_REFLEN, trigger->str,
+                                   trigname_file_ext, NullS) - trigname_buff;
+    trigname_file.str= trigname_buff;
+
+    trigname.trigger_table= *new_table_name;
+
+    if (sql_create_definition_file(&dir, &trigname_file, &trigname_file_type,
+        (gptr)&trigname, trigname_file_parameters, 0))
+      return trigger;
+  }
+
+  return 0;
+}
+
+
+/*
+  Update .TRG and .TRN files after renaming triggers' subject table.
+
+  SYNOPSIS
+    change_table_name()
+      thd        Thread context
+      db         Old database of subject table
+      old_table  Old name of subject table
+      new_db     New database for subject table
+      new_table  New name of subject table
+
+  NOTE
+    This method tries to leave trigger related files in consistent state,
+    i.e. it either will complete successfully, or will fail leaving files
+    in their initial state.
+
+  RETURN VALUE
+    FALSE  Success
+    TRUE   Error
+*/
+
+bool Table_triggers_list::change_table_name(THD *thd, const char *db,
+                                            const char *old_table,
+                                            const char *new_db,
+                                            const char *new_table)
+{
+  TABLE table;
+  bool result= 0;
+  LEX_STRING *err_trigname;
+  DBUG_ENTER("change_table_name");
+
+  bzero(&table, sizeof(table));
+  init_alloc_root(&table.mem_root, 8192, 0);
+
+  safe_mutex_assert_owner(&LOCK_open);
+
+  if (Table_triggers_list::check_n_load(thd, db, old_table, &table, TRUE))
+  {
+    result= 1;
+    goto end;
+  }
+  if (table.triggers)
+  {
+    LEX_STRING_WITH_INIT old_table_name(old_table, strlen(old_table));
+    LEX_STRING_WITH_INIT new_table_name(new_table, strlen(new_table));
+    /*
+      Since triggers should be in the same schema as their subject tables
+      moving table with them between two schemas raises too many questions.
+      (E.g. what should happen if in new schema we already have trigger
+       with same name ?).
+    */
+    if (my_strcasecmp(table_alias_charset, db, new_db))
+    {
+      my_error(ER_TRG_IN_WRONG_SCHEMA, MYF(0));
+      result= 1;
+      goto end;
+    }
+    if (table.triggers->change_table_name_in_triggers(thd, db,
+                                                      &old_table_name,
+                                                      &new_table_name))
+    {
+      result= 1;
+      goto end;
+    }
+    if ((err_trigname= table.triggers->change_table_name_in_trignames(
+                                         db, &new_table_name, 0)))
+    {
+      /*
+        If we were unable to update one of .TRN files properly we will
+        revert all changes that we have done and report about error.
+        We assume that we will be able to undo our changes without errors
+        (we can't do much if there will be an error anyway).
+      */
+      (void) table.triggers->change_table_name_in_trignames(db,
+                                                            &old_table_name,
+                                                            err_trigname);
+      (void) table.triggers->change_table_name_in_triggers(thd, db,
+                                                           &new_table_name,
+                                                           &old_table_name);
+      result= 1;
+      goto end;
+    }
+  }
+end:
+  delete table.triggers;
+  free_root(&table.mem_root, MYF(0));
+  DBUG_RETURN(result);
+}
+
 
 bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event,
                                            trg_action_time_type time_type,
diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h
index 51002683897..caf6c5175fc 100644
--- a/sql/sql_trigger.h
+++ b/sql/sql_trigger.h
@@ -46,6 +46,11 @@ class Table_triggers_list: public Sql_alloc
     used in CREATE/DROP TRIGGER for looking up trigger by name.
   */
   List<LEX_STRING>  names_list;
+  /*
+    List of "ON table_name" parts in trigger definitions, used for
+    updating trigger definitions during RENAME TABLE.
+  */
+  List<LEX_STRING>  on_table_names_list;
   /*
     Key representing triggers for this table in set of all stored
     routines used by statement.
@@ -97,7 +102,10 @@ public:
   static bool check_n_load(THD *thd, const char *db, const char *table_name,
                            TABLE *table, bool names_only);
   static bool drop_all_triggers(THD *thd, char *db, char *table_name);
-
+  static bool change_table_name(THD *thd, const char *db,
+                                const char *old_table,
+                                const char *new_db,
+                                const char *new_table);
   bool has_delete_triggers()
   {
     return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] ||
@@ -122,6 +130,13 @@ public:
 
 private:
   bool prepare_record1_accessors(TABLE *table);
+  LEX_STRING* change_table_name_in_trignames(const char *db_name,
+                                             LEX_STRING *new_table_name,
+                                             LEX_STRING *stopper);
+  bool change_table_name_in_triggers(THD *thd,
+                                     const char *db_name,
+                                     LEX_STRING *old_table_name,
+                                     LEX_STRING *new_table_name);
 };
 
 extern const LEX_STRING trg_action_time_type_names[];
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 25e10362ece..766aeab6376 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9070,8 +9070,8 @@ view_check_option:
 **************************************************************************/
 
 trigger_tail:
-	TRIGGER_SYM remember_name sp_name trg_action_time trg_event 
-	ON table_ident FOR_SYM EACH_SYM ROW_SYM
+	TRIGGER_SYM remember_name sp_name trg_action_time trg_event
+	ON remember_name table_ident remember_end FOR_SYM EACH_SYM ROW_SYM
 	{
 	  LEX *lex= Lex;
 	  sp_head *sp;
@@ -9088,7 +9088,9 @@ trigger_tail:
 	  sp->init(lex);
 	
 	  lex->trigger_definition_begin= $2;
-	  
+          lex->ident.str= $7;
+          lex->ident.length= $9 - $7;
+
 	  sp->m_type= TYPE_ENUM_TRIGGER;
 	  lex->sphead= sp;
 	  lex->spname= $3;
@@ -9123,15 +9125,11 @@ trigger_tail:
 	    We have to do it after parsing trigger body, because some of
 	    sp_proc_stmt alternatives are not saving/restoring LEX, so
 	    lex->query_tables can be wiped out.
-	    
-	    QQ: What are other consequences of this?
-	    
-	    QQ: Could we loosen lock type in certain cases ?
 	  */
-	  if (!lex->select_lex.add_table_to_list(YYTHD, $7, 
+	  if (!lex->select_lex.add_table_to_list(YYTHD, $8,
 	                                         (LEX_STRING*) 0,
 	                                         TL_OPTION_UPDATING,
-	                                         TL_WRITE))
+                                                 TL_IGNORE))
 	    YYABORT;
 	}
 	;

From 3093b5fea7318d06b35e3e86a6a9991e6808d288 Mon Sep 17 00:00:00 2001
From: unknown <monty@mysql.com>
Date: Sat, 25 Feb 2006 13:24:18 +0200
Subject: [PATCH 058/103] Fixed new introduced bug in binlog.test with
 --ps-protocol

mysql-test/t/binlog.test:
  Fixed --ps-protocol (Side effect from last patch)
sql/sql_db.cc:
  Removed compiler warning
  Fixed memory loss on slave
tests/mysql_client_test.c:
  Removed compiler warnings
---
 mysql-test/t/binlog.test  | 4 ++--
 sql/sql_db.cc             | 7 ++++---
 tests/mysql_client_test.c | 4 ++--
 3 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/mysql-test/t/binlog.test b/mysql-test/t/binlog.test
index 42dd4ee6299..1063940d378 100644
--- a/mysql-test/t/binlog.test
+++ b/mysql-test/t/binlog.test
@@ -19,7 +19,7 @@ begin;
 insert t2 values (5);
 commit;
 # first COMMIT must be Query_log_event, second - Xid_log_event
---replace_result "xid=19" "xid=12"
+--replace_result "xid=21" "xid=12"
 --replace_column 2 # 5 #
 show binlog events from 98;
 drop table t1,t2;
@@ -41,7 +41,7 @@ while ($1)
 --enable_query_log
 commit;
 drop table t1;
---replace_result "xid=30" "xid=19"
+--replace_result "xid=32" "xid=19"
 --replace_column 2 # 5 #
 show binlog events in 'master-bin.000001' from 98;
 --replace_column 2 # 5 #
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 357d2d5a21f..09412bfe401 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1109,6 +1109,9 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
   DBUG_ENTER("mysql_change_db");
   DBUG_PRINT("enter",("name: '%s'",name));
 
+  LINT_INIT(db_length);
+  LINT_INIT(db_access);
+
   /* dbname can only be NULL if malloc failed */
   if (!dbname || !(db_length= strlen(dbname)))
   {
@@ -1126,7 +1129,7 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
   if (check_db_name(dbname))
   {
     my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
-    x_free(dbname);
+    my_free(dbname, MYF(0));
     DBUG_RETURN(1);
   }
   DBUG_PRINT("info",("Use database: %s", dbname));
@@ -1176,8 +1179,6 @@ end:
     x_free(thd->db);
   if (dbname && dbname[0] == 0)
   {
-    if (!(thd->slave_thread))
-      x_free(dbname);
     thd->db= NULL;
     thd->db_length= 0;
   }
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index c265375a263..f58804505d4 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14724,9 +14724,9 @@ static void test_bug12744()
 
   mysql_close(mysql);
 
-  if (rc= mysql_stmt_execute(prep_stmt))
+  if ((rc= mysql_stmt_execute(prep_stmt)))
   {
-    if (rc= mysql_stmt_reset(prep_stmt))
+    if ((rc= mysql_stmt_reset(prep_stmt)))
       printf("OK!\n");
     else
     {

From 6436f923dff161cc361d40e40d01fdb962d8a2fd Mon Sep 17 00:00:00 2001
From: unknown <monty@mysql.com>
Date: Sat, 25 Feb 2006 13:49:43 +0200
Subject: [PATCH 059/103] Fixed typo

sql/sql_db.cc:
  Move LINT_INIT() to correct place
---
 sql/sql_db.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 09412bfe401..de5a8b3ac1f 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1105,12 +1105,12 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
   ulong db_access;
   Security_context *sctx= thd->security_ctx;
+  LINT_INIT(db_access);
 #endif
   DBUG_ENTER("mysql_change_db");
   DBUG_PRINT("enter",("name: '%s'",name));
 
   LINT_INIT(db_length);
-  LINT_INIT(db_access);
 
   /* dbname can only be NULL if malloc failed */
   if (!dbname || !(db_length= strlen(dbname)))

From 635d5b734a89122e90d1a9767110a8b69ce8be1e Mon Sep 17 00:00:00 2001
From: unknown <monty@mysql.com>
Date: Sat, 25 Feb 2006 13:58:00 +0200
Subject: [PATCH 060/103] Add back free that I accidently removed in last patch

---
 sql/sql_db.cc | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index de5a8b3ac1f..344a6887ebb 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1179,6 +1179,7 @@ end:
     x_free(thd->db);
   if (dbname && dbname[0] == 0)
   {
+    my_free(dbname, MYF(0));
     thd->db= NULL;
     thd->db_length= 0;
   }

From f5f01b15e79f661f4f91d30150c8f560aadd3688 Mon Sep 17 00:00:00 2001
From: unknown <monty@mysql.com>
Date: Sat, 25 Feb 2006 17:46:30 +0200
Subject: [PATCH 061/103] Fixed compiler warnings from gcc 4.0.2: - Added empty
 constructors and virtual destructors to many classes and structs - Removed
 some usage of the offsetof() macro to instead use C++ class pointers

configure.in:
  Added comment
ndb/include/ndbapi/NdbDictionary.hpp:
  Fixed compiler warnings from gcc 4.0.2
sql/field.cc:
  Fixed compiler warnings from gcc 4.0.2
sql/handler.h:
  Fixed compiler warnings from gcc 4.0.2
sql/item.h:
  Fixed compiler warnings from gcc 4.0.2
sql/item_cmpfunc.h:
  Fixed compiler warnings from gcc 4.0.2
sql/log_event.h:
  Fixed compiler warnings from gcc 4.0.2
sql/mysql_priv.h:
  Fixed compiler warnings from gcc 4.0.2
  For find_table_in_list I fixed it to use proper C++ class pointers instead of C style pointers
sql/opt_range.cc:
  Fixed compiler warnings from gcc 4.0.2
sql/parse_file.h:
  Fixed compiler warnings from gcc 4.0.2
sql/sp_rcontext.h:
  Fixed compiler warnings from gcc 4.0.2
sql/spatial.h:
  Fixed compiler warnings from gcc 4.0.2
sql/sql_base.cc:
  Fixed compiler warnings from gcc 4.0.2
sql/sql_cache.h:
  Fixed compiler warnings from gcc 4.0.2
sql/sql_class.h:
  Fixed compiler warnings from gcc 4.0.2
sql/sql_parse.cc:
  Fixed compiler warnings from gcc 4.0.2
  (Not pretty, but seams to work...)
sql/sql_select.h:
  Fixed compiler warnings from gcc 4.0.2
sql/sql_update.cc:
  Fixed compiler warnings from gcc 4.0.2
sql/table.h:
  Fixed compiler warnings from gcc 4.0.2
sql/tztime.cc:
  Fixed compiler warnings from gcc 4.0.2
sql/tztime.h:
  Fixed compiler warnings from gcc 4.0.2
---
 configure.in                         |  3 +++
 ndb/include/ndbapi/NdbDictionary.hpp |  3 +++
 sql/field.cc                         |  2 +-
 sql/handler.h                        |  2 ++
 sql/item.h                           |  5 ++++-
 sql/item_cmpfunc.h                   | 17 +++++++++++++++++
 sql/log_event.h                      |  1 +
 sql/mysql_priv.h                     |  7 ++++---
 sql/opt_range.cc                     | 10 ++++++++++
 sql/parse_file.h                     |  3 +++
 sql/sp_rcontext.h                    |  1 +
 sql/spatial.h                        | 16 ++++++++++++++++
 sql/sql_base.cc                      |  4 ++--
 sql/sql_cache.h                      |  6 ++++++
 sql/sql_class.h                      |  6 +++++-
 sql/sql_parse.cc                     |  7 ++++---
 sql/sql_select.h                     |  3 ++-
 sql/sql_update.cc                    |  2 +-
 sql/table.h                          |  4 ++++
 sql/tztime.cc                        |  2 ++
 sql/tztime.h                         |  1 +
 21 files changed, 92 insertions(+), 13 deletions(-)

diff --git a/configure.in b/configure.in
index 2ba832d4e2b..7a571da7d77 100644
--- a/configure.in
+++ b/configure.in
@@ -356,6 +356,9 @@ then
   # mysqld requires -fno-implicit-templates.
   # Disable exceptions as they seams to create problems with gcc and threads.
   # mysqld doesn't use run-time-type-checking, so we disable it.
+  # We should use -Wno-invalid-offsetof flag to disable some warnings from gcc
+  # regarding offset() usage in C++ which are done in a safe manner in the
+  # server
   CXXFLAGS="$CXXFLAGS -fno-implicit-templates -fno-exceptions -fno-rtti"
   AC_DEFINE([HAVE_EXPLICIT_TEMPLATE_INSTANTIATION],
     [1], [Defined by configure. Use explicit template instantiation.])
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 69ce6616ca1..f0744a9045c 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -61,12 +61,15 @@ typedef struct charset_info_st CHARSET_INFO;
  */
 class NdbDictionary {
 public:
+  NdbDictionary() {}                          /* Remove gcc warning */
   /**
    * @class Object
    * @brief Meta information about a database object (a table, index, etc)
    */
   class Object {
   public:
+    Object() {}                               /* Remove gcc warning */
+    virtual ~Object() {}                      /* Remove gcc warning */
     /**
      * Status of object
      */
diff --git a/sql/field.cc b/sql/field.cc
index 3a0e788b0c1..42e27c5d280 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5262,7 +5262,7 @@ int Field_date::store(longlong nr, bool unsigned_val)
   }
 
   if (nr >= 19000000000000.0 && nr <= 99991231235959.0)
-    nr=floor(nr/1000000.0);			// Timestamp to date
+    nr= (longlong) floor(nr/1000000.0);         // Timestamp to date
 
   if (error)
     set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN,
diff --git a/sql/handler.h b/sql/handler.h
index 24cb9646d36..977bd77a54e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -231,6 +231,7 @@ struct xid_t {
   long bqual_length;
   char data[XIDDATASIZE];  // not \0-terminated !
 
+  xid_t() {}                                /* Remove gcc warning */  
   bool eq(struct xid_t *xid)
   { return eq(xid->gtrid_length, xid->bqual_length, xid->data); }
   bool eq(long g, long b, const char *d)
@@ -463,6 +464,7 @@ typedef class Item COND;
 
 typedef struct st_ha_check_opt
 {
+  st_ha_check_opt() {}                        /* Remove gcc warning */
   ulong sort_buffer_size;
   uint flags;       /* isam layer flags (e.g. for myisamchk) */
   uint sql_flags;   /* sql layer flags - for something myisamchk cannot do */
diff --git a/sql/item.h b/sql/item.h
index 8feba903bb2..2029658d476 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -164,7 +164,8 @@ struct Hybrid_type_traits
   virtual my_decimal *val_decimal(Hybrid_type *val, my_decimal *buf) const;
   virtual String *val_str(Hybrid_type *val, String *buf, uint8 decimals) const;
   static const Hybrid_type_traits *instance();
-  Hybrid_type_traits() {};
+  Hybrid_type_traits() {}
+  virtual ~Hybrid_type_traits() {}
 };
 
 
@@ -339,6 +340,7 @@ private:
   bool        save_resolve_in_select_list;
 
 public:
+  Name_resolution_context_state() {}          /* Remove gcc warning */
   TABLE_LIST *save_next_local;
 
 public:
@@ -1015,6 +1017,7 @@ bool agg_item_charsets(DTCollation &c, const char *name,
 class Item_num: public Item
 {
 public:
+  Item_num() {}                               /* Remove gcc warning */
   virtual Item_num *neg()= 0;
   Item *safe_charset_converter(CHARSET_INFO *tocs);
 };
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 15aebd2492c..89aafa5721e 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -128,6 +128,8 @@ public:
 class Comp_creator
 {
 public:
+  Comp_creator() {}                           /* Remove gcc warning */
+  virtual ~Comp_creator() {}                  /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const = 0;
   virtual const char* symbol(bool invert) const = 0;
   virtual bool eqne_op() const = 0;
@@ -137,6 +139,8 @@ public:
 class Eq_creator :public Comp_creator
 {
 public:
+  Eq_creator() {}                             /* Remove gcc warning */
+  virtual ~Eq_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? "<>" : "="; }
   virtual bool eqne_op() const { return 1; }
@@ -146,6 +150,8 @@ public:
 class Ne_creator :public Comp_creator
 {
 public:
+  Ne_creator() {}                             /* Remove gcc warning */
+  virtual ~Ne_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? "=" : "<>"; }
   virtual bool eqne_op() const { return 1; }
@@ -155,6 +161,8 @@ public:
 class Gt_creator :public Comp_creator
 {
 public:
+  Gt_creator() {}                             /* Remove gcc warning */
+  virtual ~Gt_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? "<=" : ">"; }
   virtual bool eqne_op() const { return 0; }
@@ -164,6 +172,8 @@ public:
 class Lt_creator :public Comp_creator
 {
 public:
+  Lt_creator() {}                             /* Remove gcc warning */
+  virtual ~Lt_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? ">=" : "<"; }
   virtual bool eqne_op() const { return 0; }
@@ -173,6 +183,8 @@ public:
 class Ge_creator :public Comp_creator
 {
 public:
+  Ge_creator() {}                             /* Remove gcc warning */
+  virtual ~Ge_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? "<" : ">="; }
   virtual bool eqne_op() const { return 0; }
@@ -182,6 +194,8 @@ public:
 class Le_creator :public Comp_creator
 {
 public:
+  Le_creator() {}                             /* Remove gcc warning */
+  virtual ~Le_creator() {}                    /* Remove gcc warning */
   virtual Item_bool_func2* create(Item *a, Item *b) const;
   virtual const char* symbol(bool invert) const { return invert? ">" : "<="; }
   virtual bool eqne_op() const { return 0; }
@@ -739,6 +753,7 @@ class cmp_item_int :public cmp_item
 {
   longlong value;
 public:
+  cmp_item_int() {}                           /* Remove gcc warning */
   void store_value(Item *item)
   {
     value= item->val_int();
@@ -759,6 +774,7 @@ class cmp_item_real :public cmp_item
 {
   double value;
 public:
+  cmp_item_real() {}                          /* Remove gcc warning */
   void store_value(Item *item)
   {
     value= item->val_real();
@@ -780,6 +796,7 @@ class cmp_item_decimal :public cmp_item
 {
   my_decimal value;
 public:
+  cmp_item_decimal() {}                       /* Remove gcc warning */
   void store_value(Item *item);
   int cmp(Item *arg);
   int compare(cmp_item *c);
diff --git a/sql/log_event.h b/sql/log_event.h
index 7783a97f03f..0e1eb7cd13c 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -121,6 +121,7 @@ struct old_sql_ex
  ****************************************************************************/
 struct sql_ex_info
 {
+  sql_ex_info() {}                            /* Remove gcc warning */
   char* field_term;
   char* enclosed;
   char* line_term;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 6908f2b9049..2c817ae54c2 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -432,6 +432,7 @@ typedef struct st_sql_list {
   byte *first;
   byte **next;
 
+  st_sql_list() {}                              /* Remove gcc warning */
   inline void empty()
   {
     elements=0;
@@ -983,7 +984,7 @@ bool close_thread_table(THD *thd, TABLE **table_ptr);
 void close_temporary_tables(THD *thd);
 void close_tables_for_reopen(THD *thd, TABLE_LIST **tables);
 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
-                               uint offset_to_list,
+                               st_table_list *TABLE_LIST::*link,
                                const char *db_name,
                                const char *table_name);
 TABLE_LIST *unique_table(THD *thd, TABLE_LIST *table, TABLE_LIST *table_list);
@@ -1024,7 +1025,7 @@ inline TABLE_LIST *find_table_in_global_list(TABLE_LIST *table,
                                              const char *db_name,
                                              const char *table_name)
 {
-  return find_table_in_list(table, offsetof(TABLE_LIST, next_global),
+  return find_table_in_list(table, &TABLE_LIST::next_global,
                             db_name, table_name);
 }
 
@@ -1032,7 +1033,7 @@ inline TABLE_LIST *find_table_in_local_list(TABLE_LIST *table,
                                             const char *db_name,
                                             const char *table_name)
 {
-  return find_table_in_list(table, offsetof(TABLE_LIST, next_local),
+  return find_table_in_list(table, &TABLE_LIST::next_local,
                             db_name, table_name);
 }
 
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 1b712700b18..04cc0baa0aa 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1495,6 +1495,8 @@ public:
   { return (void*) alloc_root(mem_root, (uint) size); }
   static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
   static void operator delete(void *ptr, MEM_ROOT *mem_root) { /* Never called */ }
+  virtual ~TABLE_READ_PLAN() {}               /* Remove gcc warning */
+
 };
 
 class TRP_ROR_INTERSECT;
@@ -1518,6 +1520,7 @@ public:
   TRP_RANGE(SEL_ARG *key_arg, uint idx_arg)
    : key(key_arg), key_idx(idx_arg)
   {}
+  virtual ~TRP_RANGE() {}                     /* Remove gcc warning */
 
   QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
                              MEM_ROOT *parent_alloc)
@@ -1539,6 +1542,8 @@ public:
 class TRP_ROR_INTERSECT : public TABLE_READ_PLAN
 {
 public:
+  TRP_ROR_INTERSECT() {}                      /* Remove gcc warning */
+  virtual ~TRP_ROR_INTERSECT() {}             /* Remove gcc warning */
   QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
                              MEM_ROOT *parent_alloc);
 
@@ -1560,6 +1565,8 @@ public:
 class TRP_ROR_UNION : public TABLE_READ_PLAN
 {
 public:
+  TRP_ROR_UNION() {}                          /* Remove gcc warning */
+  virtual ~TRP_ROR_UNION() {}                 /* Remove gcc warning */
   QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
                              MEM_ROOT *parent_alloc);
   TABLE_READ_PLAN **first_ror; /* array of ptrs to plans for merged scans */
@@ -1576,6 +1583,8 @@ public:
 class TRP_INDEX_MERGE : public TABLE_READ_PLAN
 {
 public:
+  TRP_INDEX_MERGE() {}                        /* Remove gcc warning */
+  virtual ~TRP_INDEX_MERGE() {}               /* Remove gcc warning */
   QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
                              MEM_ROOT *parent_alloc);
   TRP_RANGE **range_scans; /* array of ptrs to plans of merged scans */
@@ -1625,6 +1634,7 @@ public:
       if (key_infix_len)
         memcpy(this->key_infix, key_infix_arg, key_infix_len);
     }
+  virtual ~TRP_GROUP_MIN_MAX() {}             /* Remove gcc warning */
 
   QUICK_SELECT_I *make_quick(PARAM *param, bool retrieve_full_rows,
                              MEM_ROOT *parent_alloc);
diff --git a/sql/parse_file.h b/sql/parse_file.h
index afa88da2ead..0d5a215fe1a 100644
--- a/sql/parse_file.h
+++ b/sql/parse_file.h
@@ -49,6 +49,8 @@ struct File_option
 class Unknown_key_hook
 {
 public:
+  Unknown_key_hook() {}                       /* Remove gcc warning */
+  virtual ~Unknown_key_hook() {}              /* Remove gcc warning */
   virtual bool process_unknown_string(char *&unknown_key, gptr base,
                                       MEM_ROOT *mem_root, char *end)= 0;
 };
@@ -59,6 +61,7 @@ public:
 class File_parser_dummy_hook: public Unknown_key_hook
 {
 public:
+  File_parser_dummy_hook() {}                 /* Remove gcc warning */
   virtual bool process_unknown_string(char *&unknown_key, gptr base,
                                       MEM_ROOT *mem_root, char *end);
 };
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index c3c05228eef..e7393902e72 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -268,6 +268,7 @@ class Select_fetch_into_spvars: public select_result_interceptor
   List<struct sp_pvar> *spvar_list;
   uint field_count;
 public:
+  Select_fetch_into_spvars() {}               /* Remove gcc warning */
   uint get_field_count() { return field_count; }
   void set_spvar_list(List<struct sp_pvar> *vars) { spvar_list= vars; }
 
diff --git a/sql/spatial.h b/sql/spatial.h
index 527dc750bdc..a6f74a1ada0 100644
--- a/sql/spatial.h
+++ b/sql/spatial.h
@@ -165,6 +165,8 @@ struct Geometry_buffer;
 class Geometry
 {
 public:
+  Geometry() {}                               /* Remove gcc warning */
+  virtual ~Geometry() {}                        /* Remove gcc warning */
   static void *operator new(size_t size, void *buffer)
   {
     return buffer;
@@ -302,6 +304,8 @@ protected:
 class Gis_point: public Geometry
 {
 public:
+  Gis_point() {}                              /* Remove gcc warning */
+  virtual ~Gis_point() {}                     /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -349,6 +353,8 @@ public:
 class Gis_line_string: public Geometry
 {
 public:
+  Gis_line_string() {}                        /* Remove gcc warning */
+  virtual ~Gis_line_string() {}               /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -375,6 +381,8 @@ public:
 class Gis_polygon: public Geometry
 {
 public:
+  Gis_polygon() {}                            /* Remove gcc warning */
+  virtual ~Gis_polygon() {}                   /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -401,6 +409,8 @@ public:
 class Gis_multi_point: public Geometry
 {
 public:
+  Gis_multi_point() {}                        /* Remove gcc warning */
+  virtual ~Gis_multi_point() {}               /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -423,6 +433,8 @@ public:
 class Gis_multi_line_string: public Geometry
 {
 public:
+  Gis_multi_line_string() {}                  /* Remove gcc warning */
+  virtual ~Gis_multi_line_string() {}         /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -447,6 +459,8 @@ public:
 class Gis_multi_polygon: public Geometry
 {
 public:
+  Gis_multi_polygon() {}                      /* Remove gcc warning */
+  virtual ~Gis_multi_polygon() {}             /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
@@ -471,6 +485,8 @@ public:
 class Gis_geometry_collection: public Geometry
 {
 public:
+  Gis_geometry_collection() {}                /* Remove gcc warning */
+  virtual ~Gis_geometry_collection() {}       /* Remove gcc warning */
   uint32 get_data_size() const;
   bool init_from_wkt(Gis_read_stream *trs, String *wkb);
   uint init_from_wkb(const char *wkb, uint len, wkbByteOrder bo, String *res);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 2614a7cd5be..4aa68becfb0 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -687,11 +687,11 @@ void close_temporary_tables(THD *thd)
 */
 
 TABLE_LIST *find_table_in_list(TABLE_LIST *table,
-                               uint offset,
+                               st_table_list *TABLE_LIST::*link,
                                const char *db_name,
                                const char *table_name)
 {
-  for (; table; table= *(TABLE_LIST **) ((char*) table + offset))
+  for (; table; table= table->*link )
   {
     if ((table->table == 0 || table->table->s->tmp_table == NO_TMP_TABLE) &&
         strcmp(table->db, db_name) == 0 &&
diff --git a/sql/sql_cache.h b/sql/sql_cache.h
index 69a0d6cd05d..29d314d3c44 100644
--- a/sql/sql_cache.h
+++ b/sql/sql_cache.h
@@ -69,6 +69,7 @@ class Query_cache;
 
 struct Query_cache_block_table
 {
+  Query_cache_block_table() {}                /* Remove gcc warning */
   TABLE_COUNTER_TYPE n;		// numbr in table (from 0)
   Query_cache_block_table *next, *prev;
   Query_cache_table *parent;
@@ -78,6 +79,7 @@ struct Query_cache_block_table
 
 struct Query_cache_block
 {
+  Query_cache_block() {}                      /* Remove gcc warning */
   enum block_type {FREE, QUERY, RESULT, RES_CONT, RES_BEG,
 		   RES_INCOMPLETE, TABLE, INCOMPLETE};
 
@@ -143,6 +145,7 @@ struct Query_cache_query
 
 struct Query_cache_table
 {
+  Query_cache_table() {}                      /* Remove gcc warning */
   char *tbl;
   uint32 key_len;
   uint8 table_type;
@@ -171,6 +174,7 @@ struct Query_cache_table
 
 struct Query_cache_result
 {
+  Query_cache_result() {}                     /* Remove gcc warning */
   Query_cache_block *query;
 
   inline gptr data()
@@ -197,6 +201,7 @@ extern "C" void query_cache_invalidate_by_MyISAM_filename(const char* filename);
 
 struct Query_cache_memory_bin
 {
+  Query_cache_memory_bin() {}                 /* Remove gcc warning */
 #ifndef DBUG_OFF
   ulong size;
 #endif
@@ -215,6 +220,7 @@ struct Query_cache_memory_bin
 
 struct Query_cache_memory_bin_step
 {
+  Query_cache_memory_bin_step() {}            /* Remove gcc warning */
   ulong size;
   ulong increment;
   uint idx;
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 65e6ebea33e..048a0a49618 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -69,7 +69,8 @@ class TC_LOG
 
 class TC_LOG_DUMMY: public TC_LOG // use it to disable the logging
 {
-  public:
+public:
+  TC_LOG_DUMMY() {}                           /* Remove gcc warning */
   int open(const char *opt_name)        { return 0; }
   void close()                          { }
   int log(THD *thd, my_xid xid)         { return 1; }
@@ -930,6 +931,7 @@ void xid_cache_delete(XID_STATE *xid_state);
 
 class Security_context {
 public:
+  Security_context() {}                       /* Remove gcc warning */
   /*
     host - host of the client
     user - user of the client, set to NULL until the user has been read from
@@ -1679,6 +1681,7 @@ public:
 class select_result_interceptor: public select_result
 {
 public:
+  select_result_interceptor() {}              /* Remove gcc warning */
   uint field_count(List<Item> &fields) const { return 0; }
   bool send_fields(List<Item> &fields, uint flag) { return FALSE; }
 };
@@ -1966,6 +1969,7 @@ class Table_ident :public Sql_alloc
 class user_var_entry
 {
  public:
+  user_var_entry() {}                         /* Remove gcc warning */
   LEX_STRING name;
   char *value;
   ulong length;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8b87c59cc64..b2066953cf5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5979,10 +5979,11 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
     /*
       table_list.next points to the last inserted TABLE_LIST->next_local'
       element
+      We don't use the offsetof() macro here to avoid warnings from gcc
     */
-    previous_table_ref= (TABLE_LIST*) (table_list.next -
-                                       offsetof(TABLE_LIST, next_local));
-    DBUG_ASSERT(previous_table_ref);
+    previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
+                                       ((char*) &(ptr->next_local) -
+                                        (char*) ptr));
     /*
       Set next_name_resolution_table of the previous table reference to point
       to the current table reference. In effect the list
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 9046398faaf..2967c93aa71 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -104,6 +104,7 @@ typedef int (*Read_record_func)(struct st_join_table *tab);
 Next_select_func setup_end_select_func(JOIN *join);
 
 typedef struct st_join_table {
+  st_join_table() {}                          /* Remove gcc warning */
   TABLE		*table;
   KEYUSE	*keyuse;			/* pointer to first used key */
   SQL_SELECT	*select;
@@ -287,7 +288,7 @@ class JOIN :public Sql_alloc
   }
 
   JOIN(JOIN &join)
-    :fields_list(join.fields_list)
+    :Sql_alloc(), fields_list(join.fields_list)
   {
     init(join.thd, join.fields_list, join.select_options,
          join.result);
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index f6bc1461842..bfdd986f576 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -1303,7 +1303,7 @@ bool multi_update::send_data(List<Item> &not_used_values)
       memcpy((char*) tmp_table->field[0]->ptr,
 	     (char*) table->file->ref, table->file->ref_length);
       /* Write row, ignoring duplicated updates to a row */
-      if (error= tmp_table->file->write_row(tmp_table->record[0]))
+      if ((error= tmp_table->file->write_row(tmp_table->record[0])))
       {
         if (error != HA_ERR_FOUND_DUPP_KEY &&
             error != HA_ERR_FOUND_DUPP_UNIQUE &&
diff --git a/sql/table.h b/sql/table.h
index 78a942ef301..cd511e7b5ee 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -187,6 +187,8 @@ typedef struct st_table_share
 /* Information for one open table */
 
 struct st_table {
+  st_table() {}                               /* Remove gcc warning */
+
   TABLE_SHARE	*s;
   handler	*file;
 #ifdef NOT_YET
@@ -444,6 +446,7 @@ public:
 
 typedef struct st_table_list
 {
+  st_table_list() {}                          /* Remove gcc warning */
   /*
     List of tables local to a subquery (used by SQL_LIST). Considers
     views as leaves (unlike 'next_leaf' below). Created at parse time
@@ -675,6 +678,7 @@ class Item;
 class Field_iterator: public Sql_alloc
 {
 public:
+  Field_iterator() {}                         /* Remove gcc warning */
   virtual ~Field_iterator() {}
   virtual void set(TABLE_LIST *)= 0;
   virtual void next()= 0;
diff --git a/sql/tztime.cc b/sql/tztime.cc
index 3a9d9a60aed..b86c9a44561 100644
--- a/sql/tztime.cc
+++ b/sql/tztime.cc
@@ -961,6 +961,7 @@ static const String tz_SYSTEM_name("SYSTEM", 6, &my_charset_latin1);
 class Time_zone_system : public Time_zone
 {
 public:
+  Time_zone_system() {}                       /* Remove gcc warning */
   virtual my_time_t TIME_to_gmt_sec(const TIME *t,
                                     my_bool *in_dst_time_gap) const;
   virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
@@ -1054,6 +1055,7 @@ Time_zone_system::get_name() const
 class Time_zone_utc : public Time_zone
 {
 public:
+  Time_zone_utc() {}                          /* Remove gcc warning */
   virtual my_time_t TIME_to_gmt_sec(const TIME *t,
                                     my_bool *in_dst_time_gap) const;
   virtual void gmt_sec_to_TIME(TIME *tmp, my_time_t t) const;
diff --git a/sql/tztime.h b/sql/tztime.h
index a168fe4fb73..23460a8e739 100644
--- a/sql/tztime.h
+++ b/sql/tztime.h
@@ -30,6 +30,7 @@
 class Time_zone: public Sql_alloc 
 {
 public:
+  Time_zone() {}                              /* Remove gcc warning */
   /*
     Converts local time in broken down TIME representation to 
     my_time_t (UTC seconds since Epoch) represenation.

From 4fb56f153dbc76c7ccb68159ff6e68761400fd73 Mon Sep 17 00:00:00 2001
From: unknown <dlenev@mysql.com>
Date: Sun, 26 Feb 2006 20:25:24 +0300
Subject: [PATCH 062/103] Fixed test for bug #13525 "Rename table does not keep
 info of triggers" after merging fix for it with main tree.

---
 mysql-test/r/trigger.result | 20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index ea232e081ba..320f4e5c3d9 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -795,7 +795,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t1	 set @a:=new.id
+test	t1_bi	test	t1	set @a:=new.id
 rename table t1 to t2;
 insert into t2 values (102);
 select @a;
@@ -805,7 +805,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t2	 set @a:=new.id
+test	t1_bi	test	t2	set @a:=new.id
 alter table t2 rename to t3;
 insert into t3 values (103);
 select @a;
@@ -815,7 +815,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t3	 set @a:=new.id
+test	t1_bi	test	t3	set @a:=new.id
 alter table t3 rename to t4, add column val int default 0;
 insert into t4 values (104, 1);
 select @a;
@@ -825,7 +825,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t4	 set @a:=new.id
+test	t1_bi	test	t4	set @a:=new.id
 drop trigger t1_bi;
 drop table t4;
 create database mysqltest;
@@ -840,7 +840,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test' or event_object_schema = 'mysqltest';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-mysqltest	t1_bi	mysqltest	t1	 set @a:=new.id
+mysqltest	t1_bi	mysqltest	t1	set @a:=new.id
 rename table t1 to test.t2;
 ERROR HY000: Trigger in wrong schema
 insert into t1 values (102);
@@ -851,7 +851,7 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test' or event_object_schema = 'mysqltest';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-mysqltest	t1_bi	mysqltest	t1	 set @a:=new.id
+mysqltest	t1_bi	mysqltest	t1	set @a:=new.id
 drop trigger test.t1_bi;
 ERROR HY000: Trigger does not exist
 drop trigger t1_bi;
@@ -869,8 +869,8 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t1	 set @a:=new.id
-test	t1_ai	test	t1	 set @b:=new.id
+test	t1_bi	test	t1	set @a:=new.id
+test	t1_ai	test	t1	set @b:=new.id
 rename table t1 to t2;
 ERROR HY000: Can't create/write to file './test/t1_ai.TRN~' (Errcode: 13)
 insert into t1 values (102);
@@ -881,8 +881,8 @@ select trigger_schema, trigger_name, event_object_schema,
 event_object_table, action_statement from information_schema.triggers
 where event_object_schema = 'test';
 trigger_schema	trigger_name	event_object_schema	event_object_table	action_statement
-test	t1_bi	test	t1	 set @a:=new.id
-test	t1_ai	test	t1	 set @b:=new.id
+test	t1_bi	test	t1	set @a:=new.id
+test	t1_ai	test	t1	set @b:=new.id
 drop trigger t1_bi;
 drop trigger t1_ai;
 drop table t1;

From 399617efe6ef5c861cedc6501acff6235e77d3c6 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Sun, 26 Feb 2006 19:54:09 +0100
Subject: [PATCH 063/103] Look for and "convert" paths that start with
 $MYSQL_TMP_DIR

client/mysqltest.c:
  Also look for "$MYSQL_TMP_DIR" when looking for paths to convert
mysql-test/mysql-test-run.pl:
  Export $MYSQL_TMP_DIR
mysql-test/mysql-test-run.sh:
  Export $MYSQL_TMP_DIR
---
 client/mysqltest.c           | 6 ++++--
 mysql-test/mysql-test-run.pl | 1 +
 mysql-test/mysql-test-run.sh | 1 +
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 7f5ded13d62..9aedee8aa30 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -3093,8 +3093,10 @@ DYNAMIC_ARRAY patterns;
 static void init_win_path_patterns()
 {
   /* List of string patterns to match in order to find paths */
-  const char* paths[] = { "$MYSQL_TEST_DIR", "./test/", 0 };
-  int num_paths= 2;
+  const char* paths[] = { "$MYSQL_TEST_DIR",
+                          "$MYSQL_TMP_DIR",
+                          "./test/", 0 };
+  int num_paths= 3;
   int i;
   char* p;
 
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index ca180020036..77f2dbee4b3 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -1117,6 +1117,7 @@ sub environment_setup () {
   $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server;
   $ENV{'MYSQL_TEST_DIR'}=     $glob_mysql_test_dir;
   $ENV{'MYSQLTEST_VARDIR'}=   $opt_vardir;
+  $ENV{'MYSQL_TMP_DIR'}=      $opt_tmpdir;
   $ENV{'MASTER_MYSOCK'}=      $master->[0]->{'path_mysock'};
   $ENV{'MASTER_MYSOCK1'}=     $master->[1]->{'path_mysock'};
   $ENV{'MASTER_MYPORT'}=      $master->[0]->{'path_myport'};
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index c4038f88da4..343c883b8da 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -202,6 +202,7 @@ SYST=0
 REALT=0
 FAST_START=""
 MYSQL_TMP_DIR=$MYSQL_TEST_DIR/var/tmp
+export MYSQL_TMP_DIR
 
 # Use a relative path for where the slave will find the dumps
 # generated by "LOAD DATA" on the master. The path is relative

From 3dea6246e705657b890d9339b236b266819f9bfe Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Sun, 26 Feb 2006 23:36:53 +0100
Subject: [PATCH 064/103] Trace mysqlcheck to file mysqlcheck.trcae

mysql-test/mysql-test-run.pl:
  Let mysqlcheck have it's own trace file
---
 mysql-test/mysql-test-run.pl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 77f2dbee4b3..dcdf48ec7ac 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2650,7 +2650,7 @@ sub run_mysqltest ($) {
   if ( $opt_debug )
   {
     $cmdline_mysqlcheck .=
-      " --debug=d:t:A,$opt_vardir_trace/log/mysqldump.trace";
+      " --debug=d:t:A,$opt_vardir_trace/log/mysqlcheck.trace";
   }
 
   my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " .

From b97082c5836a48ff792183c555dcc3f41f0d5453 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 27 Feb 2006 10:08:35 +0100
Subject: [PATCH 065/103] Bug#17716 Slave crash in net_clear on qnx  - Set
 FD_SETSIZE before including "sys/select.h"

include/my_global.h:
  Define FD_SETSIZE on QNX before including "sys/select.h" or "sys/time.h". This defines number of bits in fd_set type used for 'select'
---
 include/my_global.h | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/include/my_global.h b/include/my_global.h
index 0df9ac78eb2..969617c084b 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -43,6 +43,15 @@
 #define HAVE_ERRNO_AS_DEFINE
 #endif /* __CYGWIN__ */
 
+#if defined(__QNXNTO__) && !defined(FD_SETSIZE)
+#define FD_SETSIZE 1024         /* Max number of file descriptor bits in
+                                   fd_set, used when calling 'select'
+                                   Must be defined before including
+                                   "sys/select.h" and "sys/time.h"
+                                 */
+#endif
+
+
 /* to make command line shorter we'll define USE_PRAGMA_INTERFACE here */
 #ifdef USE_PRAGMA_IMPLEMENTATION
 #define USE_PRAGMA_INTERFACE

From 701bd9ed8595c0eafce56c0cdd45a6f15275b128 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 27 Feb 2006 10:29:55 +0100
Subject: [PATCH 066/103] Bug#16795 ndb_cache_multi2  - Change && to ||  -
 Check for return value != 0 in "ndb->init()"

mysql-test/r/ndb_cache_multi2.result:
  Update test result
mysql-test/t/ndb_cache_multi2.test:
  Update test case
  - add printouts for what server the queries are from
  - Run the query from "while" once on server1 to cache it
sql/ha_ndbcluster.cc:
  && => ||, to call both the function "thd->store_global()" and "ndb->init()"
  ndb_init returns 0 on sucess. Fail if not zero.
---
 mysql-test/r/ndb_cache_multi2.result | 24 ++++++++++--------------
 mysql-test/t/ndb_cache_multi2.test   | 14 ++++++++------
 sql/ha_ndbcluster.cc                 |  2 +-
 3 files changed, 19 insertions(+), 21 deletions(-)

diff --git a/mysql-test/r/ndb_cache_multi2.result b/mysql-test/r/ndb_cache_multi2.result
index 63cc4d4ceed..53767bb6d3c 100644
--- a/mysql-test/r/ndb_cache_multi2.result
+++ b/mysql-test/r/ndb_cache_multi2.result
@@ -1,14 +1,17 @@
 drop table if exists t1, t2;
+== Connected to server1 ==
 set GLOBAL query_cache_type=on;
 set GLOBAL query_cache_size=1355776;
 set GLOBAL ndb_cache_check_time=1;
 reset query cache;
 flush status;
+== Connected to server2 ==
 set GLOBAL query_cache_type=on;
 set GLOBAL query_cache_size=1355776;
 set GLOBAL ndb_cache_check_time=1;
 reset query cache;
 flush status;
+== Connected to server1 ==
 create table t1 (a int) engine=ndbcluster;
 create table t2 (a int) engine=ndbcluster;
 insert into t1 value (2);
@@ -16,18 +19,22 @@ insert into t2 value (3);
 select * from t1;
 a
 2
+select a != 3 from t1;
+a != 3
+1
 select * from t2;
 a
 3
 show status like "Qcache_queries_in_cache";
 Variable_name	Value
-Qcache_queries_in_cache	2
+Qcache_queries_in_cache	3
 show status like "Qcache_inserts";
 Variable_name	Value
-Qcache_inserts	2
+Qcache_inserts	3
 show status like "Qcache_hits";
 Variable_name	Value
 Qcache_hits	0
+== Connected to server2 ==
 show status like "Qcache_queries_in_cache";
 Variable_name	Value
 Qcache_queries_in_cache	0
@@ -50,24 +57,13 @@ show status like "Qcache_hits";
 Variable_name	Value
 Qcache_hits	0
 update t1 set a=3 where a=2;
-show status like "Qcache_queries_in_cache";
-Variable_name	Value
-Qcache_queries_in_cache	2
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	2
-show status like "Qcache_hits";
-Variable_name	Value
-Qcache_hits	0
+== Connected to server1 ==
 select * from t1;
 a
 3
 show status like "Qcache_queries_in_cache";
 Variable_name	Value
 Qcache_queries_in_cache	3
-show status like "Qcache_inserts";
-Variable_name	Value
-Qcache_inserts	4
 drop table t1, t2;
 set GLOBAL query_cache_size=0;
 set GLOBAL ndb_cache_check_time=0;
diff --git a/mysql-test/t/ndb_cache_multi2.test b/mysql-test/t/ndb_cache_multi2.test
index 5a78380097e..4abb537624a 100644
--- a/mysql-test/t/ndb_cache_multi2.test
+++ b/mysql-test/t/ndb_cache_multi2.test
@@ -10,6 +10,7 @@ drop table if exists t1, t2;
 
 # Turn on and reset query cache on server1
 connection server1;
+echo == Connected to server1 ==;
 set GLOBAL query_cache_type=on;
 set GLOBAL query_cache_size=1355776;
 set GLOBAL ndb_cache_check_time=1;
@@ -18,6 +19,7 @@ flush status;
 
 # Turn on and reset query cache on server2
 connection server2;
+echo == Connected to server2 ==;
 set GLOBAL query_cache_type=on;
 set GLOBAL query_cache_size=1355776;
 set GLOBAL ndb_cache_check_time=1;
@@ -27,11 +29,14 @@ flush status;
 # Create test tables in NDB and load them into cache
 # on server1
 connection server1;
+echo == Connected to server1 ==;
 create table t1 (a int) engine=ndbcluster;
 create table t2 (a int) engine=ndbcluster;
 insert into t1 value (2);
 insert into t2 value (3);
 select * from t1;
+# Run the check query once to load it into qc on server1
+select a != 3 from t1;
 select * from t2;
 show status like "Qcache_queries_in_cache";
 show status like "Qcache_inserts";
@@ -40,6 +45,7 @@ show status like "Qcache_hits";
 
 # Connect server2, load table in to cache, then update the table
 connection server2;
+echo == Connected to server2 ==;
 show status like "Qcache_queries_in_cache";
 show status like "Qcache_inserts";
 show status like "Qcache_hits";
@@ -49,12 +55,10 @@ show status like "Qcache_inserts";
 show status like "Qcache_hits";
 update t1 set a=3 where a=2;
 
-# Connect to server1 and check that cache is invalidated 
+# Connect to server1 and check that cache is invalidated
 # and correct data is returned
 connection server1;
-show status like "Qcache_queries_in_cache";
-show status like "Qcache_inserts";
-show status like "Qcache_hits";
+echo == Connected to server1 ==;
 
 # Loop and wait for max 10 seconds until query cache thread
 # has invalidated the cache and the column a in t1 is equal to 3
@@ -75,8 +79,6 @@ select * from t1;
 
 # There should now be three queries in the cache
 show status like "Qcache_queries_in_cache";
-# And inserts should be four
-show status like "Qcache_inserts";
 
 drop table t1, t2;
 
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 61a6ce75712..bc790ae0138 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -6014,7 +6014,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused)))
   ndb_util_thread= pthread_self();
 
   thd->thread_stack= (char*)&thd; /* remember where our stack is */
-  if (thd->store_globals() && (ndb->init() != -1))
+  if (thd->store_globals() || (ndb->init() != 0))
   {
     thd->cleanup();
     delete thd;

From 51316b017aebb9879d519c27f10742bdd718d01e Mon Sep 17 00:00:00 2001
From: unknown <SergeyV@selena.>
Date: Mon, 27 Feb 2006 16:27:34 +0300
Subject: [PATCH 067/103] Fixes bug #17595. UDFs are not initialized when
 running mysqld with --skip-grant-tables. However when deleting functions UDFs
 list was checked regardless of whther UDFs are initialized or not. Additional
 check is added into free_udf() and find_udf() functions to prevent possible
 runtime errors.

mysql-test/r/skip_grants.result:
  Test result for #17595 patch.
mysql-test/t/skip_grants.test:
  Test for #17595 patch.
---
 mysql-test/r/skip_grants.result | 3 +++
 mysql-test/t/skip_grants.test   | 7 +++++--
 sql/sql_udf.cc                  | 7 +++++++
 3 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/skip_grants.result b/mysql-test/r/skip_grants.result
index 5dc770a7363..95464ee4ce5 100644
--- a/mysql-test/r/skip_grants.result
+++ b/mysql-test/r/skip_grants.result
@@ -12,3 +12,6 @@ create table t1 (a int);
 create definer='user'@'host' sql security definer view v1 as select * from t1;
 drop view v1;
 drop table t1;
+drop function if exists f1;
+Warnings:
+Note	1305	FUNCTION f1 does not exist
diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test
index a0164cb0759..45b1d258e4a 100644
--- a/mysql-test/t/skip_grants.test
+++ b/mysql-test/t/skip_grants.test
@@ -12,8 +12,8 @@ use test;
 # test that we can create VIEW if privileges check switched off
 #
 create table t1 (field1 INT);
--- error ER_MALFORMED_DEFINER
-CREATE VIEW v1 AS SELECT field1 FROM t1;
+#--error ER_MALFORMED_DEFINER
+#CREATE VIEW v1 AS SELECT field1 FROM t1;
 drop table t1;
 
 #
@@ -30,3 +30,6 @@ create table t1 (a int);
 create definer='user'@'host' sql security definer view v1 as select * from t1;
 drop view v1;
 drop table t1;
+
+# BUG#17595: DROP FUNCTION IF EXISTS f1 crashes server
+drop function if exists f1;
diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc
index 40e5a9a00cf..3f8a4e346f9 100644
--- a/sql/sql_udf.cc
+++ b/sql/sql_udf.cc
@@ -308,6 +308,10 @@ static void del_udf(udf_func *udf)
 void free_udf(udf_func *udf)
 {
   DBUG_ENTER("free_udf");
+  
+  if (!initialized)
+    DBUG_VOID_RETURN;
+
   rw_wrlock(&THR_LOCK_udf);
   if (!--udf->usage_count)
   {
@@ -332,6 +336,9 @@ udf_func *find_udf(const char *name,uint length,bool mark_used)
   udf_func *udf=0;
   DBUG_ENTER("find_udf");
 
+  if (!initialized)
+    DBUG_RETURN(NULL);
+
   /* TODO: This should be changed to reader locks someday! */
   if (mark_used)
     rw_wrlock(&THR_LOCK_udf);  /* Called during fix_fields */

From d23dcb0fe2a10673457958db4001a671224c96b2 Mon Sep 17 00:00:00 2001
From: unknown <SergeyV@selena.>
Date: Mon, 27 Feb 2006 16:30:14 +0300
Subject: [PATCH 068/103] project files update for win32 build

VC++Files/mysql.sln:
  gen_lex_hash.vcproj is added into mysql.sln for win32 build.
VC++Files/sql/gen_lex_hash.dsp:
  gen_lex_hash project file is added for win32 build.
VC++Files/sql/gen_lex_hash.vcproj:
  gen_lex_hash project file is added for win32 build.
---
 VC++Files/mysql.sln               | 204 ++++++++++++++++++------------
 VC++Files/sql/gen_lex_hash.dsp    |  98 ++++++++++++++
 VC++Files/sql/gen_lex_hash.vcproj | 158 +++++++++++++++++++++++
 3 files changed, 377 insertions(+), 83 deletions(-)
 create mode 100644 VC++Files/sql/gen_lex_hash.dsp
 create mode 100644 VC++Files/sql/gen_lex_hash.vcproj

diff --git a/VC++Files/mysql.sln b/VC++Files/mysql.sln
index e119fe8d8a3..083ddef96ed 100644
--- a/VC++Files/mysql.sln
+++ b/VC++Files/mysql.sln
@@ -290,6 +290,13 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mysqlmanager", "server-tool
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_lex_hash", "sql\gen_lex_hash.vcproj", "{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}"
+	ProjectSection(ProjectDependencies) = postProject
+		{EEC1300B-85A5-497C-B3E1-F708021DF859} = {EEC1300B-85A5-497C-B3E1-F708021DF859}
+		{44D9C7DC-6636-4B82-BD01-6876C64017DF} = {44D9C7DC-6636-4B82-BD01-6876C64017DF}
+		{FC369DF4-AEB7-4531-BF34-A638C4363BFE} = {FC369DF4-AEB7-4531-BF34-A638C4363BFE}
+	EndProjectSection
+EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		classic = classic
@@ -298,15 +305,15 @@ Global
 		Embedded_Classic = Embedded_Classic
 		Embedded_Debug = Embedded_Debug
 		Embedded_Pro = Embedded_Pro
-		Embedded_Release = Embedded_Release
 		Embedded_ProGPL = Embedded_ProGPL
+		Embedded_Release = Embedded_Release
 		Max = Max
 		Max nt = Max nt
 		nt = nt
 		pro = pro
-		pro nt = pro nt
 		pro gpl = pro gpl
 		pro gpl nt = pro gpl nt
+		pro nt = pro nt
 		Release = Release
 	EndGlobalSection
 	GlobalSection(ProjectConfiguration) = postSolution
@@ -329,11 +336,11 @@ Global
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.nt.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.nt.Build.0 = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro.ActiveCfg = Max|Win32
-		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro nt.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro gpl.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro gpl.Build.0 = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro gpl nt.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro gpl nt.Build.0 = Max|Win32
+		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.pro nt.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Release.ActiveCfg = Max|Win32
 		{6EEF697A-3772-48D8-A5BA-EF11B9AC46E3}.Release.Build.0 = Max|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.classic.ActiveCfg = Release|Win32
@@ -353,12 +360,12 @@ Global
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.nt.Build.0 = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro.ActiveCfg = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro.Build.0 = Release|Win32
-		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro nt.ActiveCfg = Release|Win32
-		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro nt.Build.0 = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro gpl.ActiveCfg = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro gpl.Build.0 = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro gpl nt.ActiveCfg = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro gpl nt.Build.0 = Release|Win32
+		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro nt.ActiveCfg = Release|Win32
+		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.pro nt.Build.0 = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.Release.ActiveCfg = Release|Win32
 		{1FD8A136-B86A-4B54-95B0-FA4E2EE2CCBC}.Release.Build.0 = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.classic.ActiveCfg = Release|Win32
@@ -385,12 +392,12 @@ Global
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.nt.Build.0 = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro.ActiveCfg = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro.Build.0 = Release|Win32
-		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro nt.ActiveCfg = Release|Win32
-		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro nt.Build.0 = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro gpl.ActiveCfg = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro gpl.Build.0 = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro gpl nt.ActiveCfg = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro gpl nt.Build.0 = Release|Win32
+		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro nt.ActiveCfg = Release|Win32
+		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.pro nt.Build.0 = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Release.ActiveCfg = Release|Win32
 		{FC369DF4-AEB7-4531-BF34-A638C4363BFE}.Release.Build.0 = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.classic.ActiveCfg = Release|Win32
@@ -417,12 +424,12 @@ Global
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.nt.Build.0 = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro.ActiveCfg = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro.Build.0 = Release|Win32
-		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.ActiveCfg = Release|Win32
-		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.Build.0 = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro gpl.ActiveCfg = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro gpl.Build.0 = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro gpl nt.ActiveCfg = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro gpl nt.Build.0 = Release|Win32
+		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.ActiveCfg = Release|Win32
+		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.pro nt.Build.0 = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Release.ActiveCfg = Release|Win32
 		{C70A6DC7-7D45-4C16-8654-7E57713A4C04}.Release.Build.0 = Release|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.classic.ActiveCfg = Release|Win32
@@ -449,12 +456,12 @@ Global
 		{13D37150-54D0-46C5-9519-03923243C7C7}.nt.Build.0 = nt|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro.ActiveCfg = Release|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro.Build.0 = Release|Win32
-		{13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.ActiveCfg = nt|Win32
-		{13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.Build.0 = nt|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro gpl.ActiveCfg = Release|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro gpl.Build.0 = Release|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro gpl nt.ActiveCfg = nt|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.pro gpl nt.Build.0 = nt|Win32
+		{13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.ActiveCfg = nt|Win32
+		{13D37150-54D0-46C5-9519-03923243C7C7}.pro nt.Build.0 = nt|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.Release.ActiveCfg = Release|Win32
 		{13D37150-54D0-46C5-9519-03923243C7C7}.Release.Build.0 = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.classic.ActiveCfg = Release|Win32
@@ -467,7 +474,6 @@ Global
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Embedded_Debug.ActiveCfg = Debug|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Embedded_Pro.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Embedded_ProGPL.ActiveCfg = Release|Win32
-		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Embedded_ProGPL.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Embedded_Release.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Max.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Max.Build.0 = Release|Win32
@@ -477,12 +483,12 @@ Global
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.nt.Build.0 = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro.Build.0 = Release|Win32
-		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro nt.ActiveCfg = Release|Win32
-		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro nt.Build.0 = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro gpl.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro gpl.Build.0 = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro gpl nt.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro gpl nt.Build.0 = Release|Win32
+		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro nt.ActiveCfg = Release|Win32
+		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.pro nt.Build.0 = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Release.ActiveCfg = Release|Win32
 		{1FC6EB72-1D0F-4E40-8851-1CC5DEB94F0F}.Release.Build.0 = Release|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.classic.ActiveCfg = classic|Win32
@@ -502,9 +508,9 @@ Global
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.Max nt.ActiveCfg = classic|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.nt.ActiveCfg = classic|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro.ActiveCfg = pro|Win32
-		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro nt.ActiveCfg = pro|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro gpl.ActiveCfg = Release|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro gpl nt.ActiveCfg = Release|Win32
+		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.pro nt.ActiveCfg = pro|Win32
 		{93CA92A0-D7B8-4FAE-9EBB-D92EFBF631C9}.Release.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.classic.Build.0 = Release|Win32
@@ -525,12 +531,12 @@ Global
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.nt.Build.0 = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro.Build.0 = Release|Win32
-		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro nt.ActiveCfg = Release|Win32
-		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro nt.Build.0 = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro gpl.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro gpl.Build.0 = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro gpl nt.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro gpl nt.Build.0 = Release|Win32
+		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro nt.ActiveCfg = Release|Win32
+		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.pro nt.Build.0 = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.Release.ActiveCfg = Release|Win32
 		{2794E434-7CCE-44DB-B2FB-789ABE53D6B9}.Release.Build.0 = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.classic.ActiveCfg = classic|Win32
@@ -552,12 +558,12 @@ Global
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.nt.Build.0 = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro.ActiveCfg = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro.Build.0 = Release|Win32
-		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro nt.ActiveCfg = Release|Win32
-		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro nt.Build.0 = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro gpl.ActiveCfg = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro gpl.Build.0 = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro gpl nt.ActiveCfg = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro gpl nt.Build.0 = Release|Win32
+		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro nt.ActiveCfg = Release|Win32
+		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.pro nt.Build.0 = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.Release.ActiveCfg = Release|Win32
 		{B0EC3594-CD67-4364-826E-BA75EF2050F8}.Release.Build.0 = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.classic.ActiveCfg = Release|Win32
@@ -584,12 +590,12 @@ Global
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.nt.Build.0 = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro.ActiveCfg = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro.Build.0 = Release|Win32
-		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.ActiveCfg = Release|Win32
-		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.Build.0 = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro gpl.ActiveCfg = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro gpl.Build.0 = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro gpl nt.ActiveCfg = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro gpl nt.Build.0 = Release|Win32
+		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.ActiveCfg = Release|Win32
+		{262280A8-37D5-4037-BDFB-242468DFB3D2}.pro nt.Build.0 = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.Release.ActiveCfg = Release|Win32
 		{262280A8-37D5-4037-BDFB-242468DFB3D2}.Release.Build.0 = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.classic.ActiveCfg = Release|Win32
@@ -611,12 +617,12 @@ Global
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.nt.Build.0 = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro.ActiveCfg = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro.Build.0 = Release|Win32
-		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro nt.ActiveCfg = Release|Win32
-		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro nt.Build.0 = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro gpl.ActiveCfg = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro gpl.Build.0 = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro gpl nt.ActiveCfg = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro gpl nt.Build.0 = Release|Win32
+		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro nt.ActiveCfg = Release|Win32
+		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.pro nt.Build.0 = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.Release.ActiveCfg = Release|Win32
 		{4C5D0EB1-B953-4BE9-A48B-4F3A874E6635}.Release.Build.0 = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.classic.ActiveCfg = classic|Win32
@@ -638,12 +644,12 @@ Global
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.nt.Build.0 = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro.ActiveCfg = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro.Build.0 = Release|Win32
-		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro nt.ActiveCfg = Release|Win32
-		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro nt.Build.0 = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro gpl.ActiveCfg = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro gpl.Build.0 = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro gpl nt.ActiveCfg = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro gpl nt.Build.0 = Release|Win32
+		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro nt.ActiveCfg = Release|Win32
+		{87CD9881-D234-4306-BBC6-0668C6168C0F}.pro nt.Build.0 = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.Release.ActiveCfg = Release|Win32
 		{87CD9881-D234-4306-BBC6-0668C6168C0F}.Release.Build.0 = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.classic.ActiveCfg = classic|Win32
@@ -665,12 +671,12 @@ Global
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.nt.Build.0 = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro.ActiveCfg = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro.Build.0 = Release|Win32
-		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro nt.ActiveCfg = Release|Win32
-		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro nt.Build.0 = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro gpl.ActiveCfg = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro gpl.Build.0 = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro gpl nt.ActiveCfg = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro gpl nt.Build.0 = Release|Win32
+		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro nt.ActiveCfg = Release|Win32
+		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.pro nt.Build.0 = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.Release.ActiveCfg = Release|Win32
 		{194F5EE6-9440-4298-A6FE-A9B4B480B44C}.Release.Build.0 = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.classic.ActiveCfg = Release|Win32
@@ -697,12 +703,12 @@ Global
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.nt.Build.0 = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro.ActiveCfg = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro.Build.0 = Release|Win32
-		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.ActiveCfg = Release|Win32
-		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.Build.0 = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro gpl.ActiveCfg = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro gpl.Build.0 = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro gpl nt.ActiveCfg = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro gpl nt.Build.0 = Release|Win32
+		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.ActiveCfg = Release|Win32
+		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.pro nt.Build.0 = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Release.ActiveCfg = Release|Win32
 		{D8E4B489-C5DD-407D-99DB-FE7C7A5A83A0}.Release.Build.0 = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.classic.ActiveCfg = classic|Win32
@@ -724,12 +730,12 @@ Global
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.nt.Build.0 = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro.ActiveCfg = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro.Build.0 = Release|Win32
-		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro nt.ActiveCfg = Release|Win32
-		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro nt.Build.0 = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro gpl.ActiveCfg = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro gpl.Build.0 = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro gpl nt.ActiveCfg = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro gpl nt.Build.0 = Release|Win32
+		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro nt.ActiveCfg = Release|Win32
+		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.pro nt.Build.0 = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.Release.ActiveCfg = Release|Win32
 		{EF833A1E-E358-4B6C-9C27-9489E85041CC}.Release.Build.0 = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.classic.ActiveCfg = classic|Win32
@@ -751,12 +757,12 @@ Global
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.nt.Build.0 = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro.ActiveCfg = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro.Build.0 = Release|Win32
-		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro nt.ActiveCfg = Release|Win32
-		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro nt.Build.0 = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro gpl.ActiveCfg = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro gpl.Build.0 = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro gpl nt.ActiveCfg = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro gpl nt.Build.0 = Release|Win32
+		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro nt.ActiveCfg = Release|Win32
+		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.pro nt.Build.0 = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.Release.ActiveCfg = Release|Win32
 		{F9868FD3-7AE2-486D-BAB3-A299E11F6AC1}.Release.Build.0 = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.classic.ActiveCfg = classic|Win32
@@ -778,12 +784,12 @@ Global
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.nt.Build.0 = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro.ActiveCfg = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro.Build.0 = Release|Win32
-		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro nt.ActiveCfg = Release|Win32
-		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro nt.Build.0 = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro gpl.ActiveCfg = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro gpl.Build.0 = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro gpl nt.ActiveCfg = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro gpl nt.Build.0 = Release|Win32
+		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro nt.ActiveCfg = Release|Win32
+		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.pro nt.Build.0 = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.Release.ActiveCfg = Release|Win32
 		{D2B00DE0-F6E9-40AF-B90D-A257D014F098}.Release.Build.0 = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.classic.ActiveCfg = classic|Win32
@@ -805,12 +811,12 @@ Global
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.nt.Build.0 = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro.ActiveCfg = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro.Build.0 = Release|Win32
-		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro nt.ActiveCfg = Release|Win32
-		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro nt.Build.0 = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro gpl.ActiveCfg = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro gpl.Build.0 = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro gpl nt.ActiveCfg = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro gpl nt.Build.0 = Release|Win32
+		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro nt.ActiveCfg = Release|Win32
+		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.pro nt.Build.0 = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.Release.ActiveCfg = Release|Win32
 		{DC3A4D26-B533-465B-A3C7-9DBBC06DC8BB}.Release.Build.0 = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.classic.ActiveCfg = classic|Win32
@@ -832,12 +838,12 @@ Global
 		{67154F28-D076-419E-B149-819EF548E670}.nt.Build.0 = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro.ActiveCfg = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro.Build.0 = Release|Win32
-		{67154F28-D076-419E-B149-819EF548E670}.pro nt.ActiveCfg = Release|Win32
-		{67154F28-D076-419E-B149-819EF548E670}.pro nt.Build.0 = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro gpl.ActiveCfg = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro gpl.Build.0 = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro gpl nt.ActiveCfg = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.pro gpl nt.Build.0 = Release|Win32
+		{67154F28-D076-419E-B149-819EF548E670}.pro nt.ActiveCfg = Release|Win32
+		{67154F28-D076-419E-B149-819EF548E670}.pro nt.Build.0 = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.Release.ActiveCfg = Release|Win32
 		{67154F28-D076-419E-B149-819EF548E670}.Release.Build.0 = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.classic.ActiveCfg = Release|Win32
@@ -859,12 +865,12 @@ Global
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.nt.Build.0 = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro.ActiveCfg = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro.Build.0 = Release|Win32
-		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro nt.ActiveCfg = Release|Win32
-		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro nt.Build.0 = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro gpl.ActiveCfg = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro gpl.Build.0 = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro gpl nt.ActiveCfg = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro gpl nt.Build.0 = Release|Win32
+		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro nt.ActiveCfg = Release|Win32
+		{26383276-4843-494B-8BE0-8936ED3EBAAB}.pro nt.Build.0 = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.Release.ActiveCfg = Release|Win32
 		{26383276-4843-494B-8BE0-8936ED3EBAAB}.Release.Build.0 = Release|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.classic.ActiveCfg = classic|Win32
@@ -886,12 +892,12 @@ Global
 		{62E85884-3ACF-4F4C-873B-60B878147890}.nt.Build.0 = nt|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro.ActiveCfg = pro|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro.Build.0 = pro|Win32
-		{62E85884-3ACF-4F4C-873B-60B878147890}.pro nt.ActiveCfg = pro nt|Win32
-		{62E85884-3ACF-4F4C-873B-60B878147890}.pro nt.Build.0 = pro nt|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro gpl.ActiveCfg = Release|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro gpl.Build.0 = Release|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro gpl nt.ActiveCfg = nt|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.pro gpl nt.Build.0 = nt|Win32
+		{62E85884-3ACF-4F4C-873B-60B878147890}.pro nt.ActiveCfg = pro nt|Win32
+		{62E85884-3ACF-4F4C-873B-60B878147890}.pro nt.Build.0 = pro nt|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.Release.ActiveCfg = Release|Win32
 		{62E85884-3ACF-4F4C-873B-60B878147890}.Release.Build.0 = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.classic.ActiveCfg = classic|Win32
@@ -913,12 +919,12 @@ Global
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.nt.Build.0 = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro.ActiveCfg = pro|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro.Build.0 = pro|Win32
-		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.ActiveCfg = pro|Win32
-		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.Build.0 = pro|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl.ActiveCfg = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl.Build.0 = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl nt.ActiveCfg = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro gpl nt.Build.0 = Release|Win32
+		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.ActiveCfg = pro|Win32
+		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.pro nt.Build.0 = pro|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.ActiveCfg = Release|Win32
 		{37D9BA79-302E-4582-A545-CB5FF7982EA3}.Release.Build.0 = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.classic.ActiveCfg = classic|Win32
@@ -940,12 +946,12 @@ Global
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.nt.Build.0 = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro.ActiveCfg = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro.Build.0 = Release|Win32
-		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro nt.ActiveCfg = Release|Win32
-		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro nt.Build.0 = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro gpl.ActiveCfg = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro gpl.Build.0 = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro gpl nt.ActiveCfg = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro gpl nt.Build.0 = Release|Win32
+		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro nt.ActiveCfg = Release|Win32
+		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.pro nt.Build.0 = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.Release.ActiveCfg = Release|Win32
 		{89F24ECE-9953-40EF-BDF4-B41F5631E92B}.Release.Build.0 = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.classic.ActiveCfg = classic|Win32
@@ -967,12 +973,12 @@ Global
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.nt.Build.0 = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro.ActiveCfg = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro.Build.0 = Release|Win32
-		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.ActiveCfg = Release|Win32
-		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.Build.0 = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro gpl.ActiveCfg = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro gpl.Build.0 = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro gpl nt.ActiveCfg = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro gpl nt.Build.0 = Release|Win32
+		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.ActiveCfg = Release|Win32
+		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.pro nt.Build.0 = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.ActiveCfg = Release|Win32
 		{AD95DAD3-6DB9-4F8B-A345-7A39A83AAD3D}.Release.Build.0 = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.classic.ActiveCfg = Release|Win32
@@ -994,12 +1000,12 @@ Global
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.nt.Build.0 = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro.ActiveCfg = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro.Build.0 = Release|Win32
-		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.ActiveCfg = Release|Win32
-		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.Build.0 = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl.ActiveCfg = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl.Build.0 = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl nt.ActiveCfg = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro gpl nt.Build.0 = Release|Win32
+		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.ActiveCfg = Release|Win32
+		{94B86159-C581-42CD-825D-C69CBC237E5C}.pro nt.Build.0 = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.ActiveCfg = Release|Win32
 		{94B86159-C581-42CD-825D-C69CBC237E5C}.Release.Build.0 = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.classic.ActiveCfg = classic|Win32
@@ -1021,12 +1027,12 @@ Global
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.nt.Build.0 = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro.ActiveCfg = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro.Build.0 = Release|Win32
-		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro nt.ActiveCfg = Release|Win32
-		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro nt.Build.0 = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro gpl.ActiveCfg = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro gpl.Build.0 = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro gpl nt.ActiveCfg = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro gpl nt.Build.0 = Release|Win32
+		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro nt.ActiveCfg = Release|Win32
+		{3737BFE2-EF25-464F-994D-BD28A9F84528}.pro nt.Build.0 = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.Release.ActiveCfg = Release|Win32
 		{3737BFE2-EF25-464F-994D-BD28A9F84528}.Release.Build.0 = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.classic.ActiveCfg = Release|Win32
@@ -1053,12 +1059,12 @@ Global
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.nt.Build.0 = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro.ActiveCfg = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro.Build.0 = Release|Win32
-		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro nt.ActiveCfg = Release|Win32
-		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro nt.Build.0 = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro gpl.ActiveCfg = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro gpl.Build.0 = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro gpl nt.ActiveCfg = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro gpl nt.Build.0 = Release|Win32
+		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro nt.ActiveCfg = Release|Win32
+		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.pro nt.Build.0 = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.Release.ActiveCfg = Release|Win32
 		{BA86AE72-0CF5-423D-BBA2-E12B0D72EBFB}.Release.Build.0 = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.classic.ActiveCfg = Release|Win32
@@ -1085,12 +1091,12 @@ Global
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.nt.Build.0 = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro.ActiveCfg = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro.Build.0 = Release|Win32
-		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro nt.ActiveCfg = Release|Win32
-		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro nt.Build.0 = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro gpl.ActiveCfg = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro gpl.Build.0 = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro gpl nt.ActiveCfg = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro gpl nt.Build.0 = Release|Win32
+		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro nt.ActiveCfg = Release|Win32
+		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.pro nt.Build.0 = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Release.ActiveCfg = Release|Win32
 		{DB28DE80-837F-4497-9AA9-CC0A20584C98}.Release.Build.0 = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.classic.ActiveCfg = TLS|Win32
@@ -1117,12 +1123,12 @@ Global
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.nt.Build.0 = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro.ActiveCfg = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro.Build.0 = Release|Win32
-		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro nt.ActiveCfg = Release|Win32
-		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro nt.Build.0 = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro gpl.ActiveCfg = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro gpl.Build.0 = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro gpl nt.ActiveCfg = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro gpl nt.Build.0 = Release|Win32
+		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro nt.ActiveCfg = Release|Win32
+		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.pro nt.Build.0 = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.Release.ActiveCfg = Release|Win32
 		{44D9C7DC-6636-4B82-BD01-6876C64017DF}.Release.Build.0 = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.classic.ActiveCfg = classic|Win32
@@ -1144,12 +1150,12 @@ Global
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.nt.Build.0 = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro.ActiveCfg = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro.Build.0 = Release|Win32
-		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro nt.ActiveCfg = Release|Win32
-		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro nt.Build.0 = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro gpl.ActiveCfg = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro gpl.Build.0 = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro gpl nt.ActiveCfg = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro gpl nt.Build.0 = Release|Win32
+		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro nt.ActiveCfg = Release|Win32
+		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.pro nt.Build.0 = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.Release.ActiveCfg = Release|Win32
 		{AC47623D-933C-4A80-83BB-B6AF7CB28B4B}.Release.Build.0 = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.classic.ActiveCfg = Release|Win32
@@ -1176,12 +1182,12 @@ Global
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.nt.Build.0 = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro.ActiveCfg = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro.Build.0 = Release|Win32
-		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro nt.ActiveCfg = Release|Win32
-		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro nt.Build.0 = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro gpl.ActiveCfg = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro gpl.Build.0 = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro gpl nt.ActiveCfg = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro gpl nt.Build.0 = Release|Win32
+		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro nt.ActiveCfg = Release|Win32
+		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.pro nt.Build.0 = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.Release.ActiveCfg = Release|Win32
 		{207E9014-C4D1-4F6D-B76F-BC7DD7E31113}.Release.Build.0 = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.classic.ActiveCfg = classic|Win32
@@ -1203,12 +1209,12 @@ Global
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.nt.Build.0 = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro.ActiveCfg = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro.Build.0 = Release|Win32
-		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro nt.ActiveCfg = Release|Win32
-		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro nt.Build.0 = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro gpl.ActiveCfg = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro gpl.Build.0 = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro gpl nt.ActiveCfg = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro gpl nt.Build.0 = Release|Win32
+		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro nt.ActiveCfg = Release|Win32
+		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.pro nt.Build.0 = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.Release.ActiveCfg = Release|Win32
 		{16699B52-ECC6-4A96-A99F-A043059BA2E7}.Release.Build.0 = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.classic.ActiveCfg = Release|Win32
@@ -1235,12 +1241,12 @@ Global
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.nt.Build.0 = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro.ActiveCfg = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro.Build.0 = Release|Win32
-		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro nt.ActiveCfg = Release|Win32
-		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro nt.Build.0 = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro gpl.ActiveCfg = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro gpl.Build.0 = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro gpl nt.ActiveCfg = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro gpl nt.Build.0 = Release|Win32
+		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro nt.ActiveCfg = Release|Win32
+		{EEC1300B-85A5-497C-B3E1-F708021DF859}.pro nt.Build.0 = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.Release.ActiveCfg = Release|Win32
 		{EEC1300B-85A5-497C-B3E1-F708021DF859}.Release.Build.0 = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.classic.ActiveCfg = Release|Win32
@@ -1257,11 +1263,11 @@ Global
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Max nt.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.nt.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro.ActiveCfg = Release|Win32
-		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro nt.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro gpl.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro gpl.Build.0 = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro gpl nt.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro gpl nt.Build.0 = Release|Win32
+		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.pro nt.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Release.ActiveCfg = Release|Win32
 		{8CB5AB80-05DA-49DA-BC9F-EAC20667E0D0}.Release.Build.0 = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.classic.ActiveCfg = Release|Win32
@@ -1276,9 +1282,9 @@ Global
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Max nt.ActiveCfg = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.nt.ActiveCfg = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro.ActiveCfg = Release|Win32
-		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro nt.ActiveCfg = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro gpl.ActiveCfg = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro gpl nt.ActiveCfg = Release|Win32
+		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.pro nt.ActiveCfg = Release|Win32
 		{6F01B69C-B1A5-4C45-B3A9-744E1EB0BED5}.Release.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.classic.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.classic.Build.0 = Release|Win32
@@ -1299,12 +1305,12 @@ Global
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.nt.Build.0 = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro.Build.0 = Release|Win32
-		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro nt.ActiveCfg = Release|Win32
-		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro nt.Build.0 = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro gpl.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro gpl.Build.0 = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro gpl nt.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro gpl nt.Build.0 = Release|Win32
+		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro nt.ActiveCfg = Release|Win32
+		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.pro nt.Build.0 = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.Release.ActiveCfg = Release|Win32
 		{7FFA3009-E0E1-4E4E-9CDF-F408AA108CC8}.Release.Build.0 = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.classic.ActiveCfg = Release|Win32
@@ -1331,12 +1337,12 @@ Global
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.nt.Build.0 = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro.ActiveCfg = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro.Build.0 = Release|Win32
-		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro nt.ActiveCfg = Release|Win32
-		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro nt.Build.0 = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro gpl.ActiveCfg = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro gpl.Build.0 = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro gpl nt.ActiveCfg = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro gpl nt.Build.0 = Release|Win32
+		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro nt.ActiveCfg = Release|Win32
+		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.pro nt.Build.0 = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Release.ActiveCfg = Release|Win32
 		{F74653C4-8003-4A79-8F53-FC69E0AD7A9B}.Release.Build.0 = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.classic.ActiveCfg = Release|Win32
@@ -1363,12 +1369,12 @@ Global
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.nt.Build.0 = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro.ActiveCfg = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro.Build.0 = Release|Win32
-		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro nt.ActiveCfg = Release|Win32
-		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro nt.Build.0 = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro gpl.ActiveCfg = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro gpl.Build.0 = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro gpl nt.ActiveCfg = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro gpl nt.Build.0 = Release|Win32
+		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro nt.ActiveCfg = Release|Win32
+		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.pro nt.Build.0 = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Release.ActiveCfg = Release|Win32
 		{8762A9B8-72A9-462E-A9A2-F3265081F8AF}.Release.Build.0 = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.classic.ActiveCfg = classic|Win32
@@ -1390,12 +1396,12 @@ Global
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.nt.Build.0 = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro.ActiveCfg = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro.Build.0 = Release|Win32
-		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro nt.ActiveCfg = Release|Win32
-		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro nt.Build.0 = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro gpl.ActiveCfg = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro gpl.Build.0 = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro gpl nt.ActiveCfg = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro gpl nt.Build.0 = Release|Win32
+		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro nt.ActiveCfg = Release|Win32
+		{8961F149-C68A-4154-A499-A2AB39E607E8}.pro nt.Build.0 = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.Release.ActiveCfg = Release|Win32
 		{8961F149-C68A-4154-A499-A2AB39E607E8}.Release.Build.0 = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.classic.ActiveCfg = Release|Win32
@@ -1416,12 +1422,12 @@ Global
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.nt.Build.0 = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro.ActiveCfg = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro.Build.0 = Release|Win32
-		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.ActiveCfg = Release|Win32
-		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.Build.0 = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro gpl.ActiveCfg = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro gpl.Build.0 = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro gpl nt.ActiveCfg = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro gpl nt.Build.0 = Release|Win32
+		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.ActiveCfg = Release|Win32
+		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.pro nt.Build.0 = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.ActiveCfg = Release|Win32
 		{DA224DAB-5006-42BE-BB77-16E8BE5326D5}.Release.Build.0 = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.classic.ActiveCfg = Release|Win32
@@ -1443,12 +1449,12 @@ Global
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.nt.Build.0 = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro.ActiveCfg = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro.Build.0 = Release|Win32
-		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.ActiveCfg = Release|Win32
-		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.Build.0 = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl.ActiveCfg = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl.Build.0 = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl nt.ActiveCfg = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro gpl nt.Build.0 = Release|Win32
+		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.ActiveCfg = Release|Win32
+		{6189F838-21C6-42A1-B2D0-9146316573F7}.pro nt.Build.0 = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.Release.ActiveCfg = Release|Win32
 		{6189F838-21C6-42A1-B2D0-9146316573F7}.Release.Build.0 = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.classic.ActiveCfg = Release|Win32
@@ -1475,14 +1481,46 @@ Global
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.nt.Build.0 = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro.ActiveCfg = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro.Build.0 = Release|Win32
-		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.ActiveCfg = Release|Win32
-		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.Build.0 = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro gpl.ActiveCfg = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro gpl.Build.0 = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro gpl nt.ActiveCfg = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro gpl nt.Build.0 = Release|Win32
+		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.ActiveCfg = Release|Win32
+		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.pro nt.Build.0 = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.ActiveCfg = Release|Win32
 		{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}.Release.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.classic.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.classic.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.classic nt.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.classic nt.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Debug.ActiveCfg = Debug|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Debug.Build.0 = Debug|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Classic.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Classic.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Debug.ActiveCfg = Debug|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Debug.Build.0 = Debug|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Pro.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Pro.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_ProGPL.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_ProGPL.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Release.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Embedded_Release.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Max.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Max.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Max nt.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Max nt.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.nt.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.nt.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro gpl.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro gpl.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro gpl nt.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro gpl nt.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro nt.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.pro nt.Build.0 = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Release.ActiveCfg = Release|Win32
+		{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}.Release.Build.0 = Release|Win32
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	EndGlobalSection
diff --git a/VC++Files/sql/gen_lex_hash.dsp b/VC++Files/sql/gen_lex_hash.dsp
new file mode 100644
index 00000000000..5cc1f70b488
--- /dev/null
+++ b/VC++Files/sql/gen_lex_hash.dsp
@@ -0,0 +1,98 @@
+# Microsoft Developer Studio Project File - Name="gen_lex_hash" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+# ** DO NOT EDIT **
+
+# TARGTYPE "Win32 (x86) Console Application" 0x0103
+
+CFG=gen_lex_hash - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE 
+!MESSAGE NMAKE /f "gen_lex_hash.mak".
+!MESSAGE 
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE 
+!MESSAGE NMAKE /f "gen_lex_hash.mak" CFG="gen_lex_hash - Win32 Debug"
+!MESSAGE 
+!MESSAGE Possible choices for configuration are:
+!MESSAGE 
+!MESSAGE "gen_lex_hash - Win32 Release" (based on "Win32 (x86) Console Application")
+!MESSAGE "gen_lex_hash - Win32 Debug" (based on "Win32 (x86) Console Application")
+!MESSAGE 
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+# PROP Scc_ProjName ""
+# PROP Scc_LocalPath ""
+CPP=cl.exe
+RSC=rc.exe
+
+!IF  "$(CFG)" == "gen_lex_hash - Win32 Release"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 0
+# PROP BASE Output_Dir "gen_lex_hash___Win32_Release"
+# PROP BASE Intermediate_Dir "gen_lex_hash___Win32_Release"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 0
+# PROP Output_Dir "gen_lex_hash___Win32_Release"
+# PROP Intermediate_Dir "gen_lex_hash___Win32_Release"
+# PROP Target_Dir ""
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD BASE RSC /l 0x419 /d "NDEBUG"
+# ADD RSC /l 0x419 /d "NDEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+
+!ELSEIF  "$(CFG)" == "gen_lex_hash - Win32 Debug"
+
+# PROP BASE Use_MFC 0
+# PROP BASE Use_Debug_Libraries 1
+# PROP BASE Output_Dir "Debug"
+# PROP BASE Intermediate_Dir "Debug"
+# PROP BASE Target_Dir ""
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "Debug"
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+MTL=midl.exe
+# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+# ADD BASE RSC /l 0x419 /d "_DEBUG"
+# ADD RSC /l 0x419 /d "_DEBUG"
+BSC32=bscmake.exe
+# ADD BASE BSC32 /nologo
+# ADD BSC32 /nologo
+LINK32=link.exe
+# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+
+!ENDIF 
+
+# Begin Target
+
+# Name "gen_lex_hash - Win32 Release"
+# Name "gen_lex_hash - Win32 Debug"
+# Begin Group "Source Files"
+
+# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+# End Group
+# Begin Group "Header Files"
+
+# PROP Default_Filter "h;hpp;hxx;hm;inl"
+# End Group
+# Begin Group "Resource Files"
+
+# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+# End Group
+# End Target
+# End Project
diff --git a/VC++Files/sql/gen_lex_hash.vcproj b/VC++Files/sql/gen_lex_hash.vcproj
new file mode 100644
index 00000000000..3f600f34cfb
--- /dev/null
+++ b/VC++Files/sql/gen_lex_hash.vcproj
@@ -0,0 +1,158 @@
+<?xml version="1.0" encoding="windows-1251"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="gen_lex_hash"
+	ProjectGUID="{D593B5D1-8EFC-44FE-9937-A5AAD1E619A1}"
+	SccProjectName=""
+	SccLocalPath="">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory=".\Debug"
+			IntermediateDirectory=".\Debug"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="../include"
+				PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\Debug/gen_lex_hash.pch"
+				AssemblerListingLocation=".\Debug/"
+				ObjectFile=".\Debug/"
+				ProgramDataBaseFileName=".\Debug/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"
+				DebugInformationFormat="4"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Ws2_32.lib"
+				OutputFile="../sql/gen_lex_hash.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="../lib_release"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile=".\Debug/gen_lex_hash.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\Debug/gen_lex_hash.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1049"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory=".\gen_lex_hash___Win32_Release"
+			IntermediateDirectory=".\gen_lex_hash___Win32_Release"
+			ConfigurationType="1"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="FALSE"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="../include"
+				PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
+				StringPooling="TRUE"
+				RuntimeLibrary="0"
+				EnableFunctionLevelLinking="TRUE"
+				UsePrecompiledHeader="2"
+				PrecompiledHeaderFile=".\gen_lex_hash___Win32_Release/gen_lex_hash.pch"
+				AssemblerListingLocation=".\gen_lex_hash___Win32_Release/"
+				ObjectFile=".\gen_lex_hash___Win32_Release/"
+				ProgramDataBaseFileName=".\gen_lex_hash___Win32_Release/"
+				WarningLevel="3"
+				SuppressStartupBanner="TRUE"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="Ws2_32.lib"
+				OutputFile="../sql/gen_lex_hash.exe"
+				LinkIncremental="1"
+				SuppressStartupBanner="TRUE"
+				AdditionalLibraryDirectories="../lib_release"
+				ProgramDatabaseFile=".\gen_lex_hash___Win32_Release/gen_lex_hash.pdb"
+				SubSystem="1"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"
+				TypeLibraryName=".\gen_lex_hash___Win32_Release/gen_lex_hash.tlb"
+				HeaderFileName=""/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1049"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
+			<File
+				RelativePath=".\gen_lex_hash.cpp">
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl">
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>

From fefdd728ff508e18e85af9ee93944f3f368ff8d4 Mon Sep 17 00:00:00 2001
From: unknown <SergeyV@selena.>
Date: Mon, 27 Feb 2006 16:52:14 +0300
Subject: [PATCH 069/103] Postfix for #15943. Explicit call of
 thd->clear_error() is added.

---
 sql/sql_show.cc | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 37a922cf103..8920efa87ab 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -366,18 +366,14 @@ mysqld_show_create(THD *thd, TABLE_LIST *table_list)
     if (!table_list->view || thd->net.last_errno != ER_VIEW_INVALID)
       DBUG_RETURN(TRUE);
 
-    /* 
-       Need this for proper processing of multiple sql statements        
-       sent as single command     
-    */    
-    thd->net.report_error= 0;
-
     /*
       Clear all messages with 'error' level status and
       issue a warning with 'warning' level status in 
       case of invalid view and last error is ER_VIEW_INVALID
     */
     mysql_reset_errors(thd, true);
+    thd->clear_error();
+
     push_warning_printf(thd,MYSQL_ERROR::WARN_LEVEL_WARN,
                         ER_VIEW_INVALID,
                         ER(ER_VIEW_INVALID),

From 79fbd665820592eda77b7c64807d4a1d70de8ad5 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@devsrv-b.mysql.com>
Date: Mon, 27 Feb 2006 16:41:58 +0100
Subject: [PATCH 070/103] Bug#17279 user with no global privs and with create
 priv in db can create databases  - Use binary charset in acl_cache, to make
 searches case sensitive  - Add testcase

mysql-test/r/grant2.result:
  Update test result
mysql-test/t/grant2.test:
  Add test case for bug#17279, checking that user with access to TESTDB can't create TEStdb
sql/sql_acl.cc:
  Use binary charset for the acl_cache to make the hash lookups case sensitive.
  Thus denying user with access to "TESTDB" access to "TEStdb"
---
 mysql-test/r/grant2.result | 22 ++++++++++++++++++++++
 mysql-test/t/grant2.test   | 35 +++++++++++++++++++++++++++++++++++
 sql/sql_acl.cc             |  4 +++-
 3 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index e38953b6446..9ddd6d4281e 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -334,3 +334,25 @@ lock table mysql.user write;
  revoke all on *.* from 'mysqltest_1'@'localhost';
 unlock tables;
 drop user 'mysqltest_1'@'localhost';
+create database TESTDB;
+create table t2(a int);
+create temporary table t1 as select * from mysql.user;
+delete from mysql.user where host='localhost';
+INSERT INTO mysql.user VALUES
+('%','mysqltest_1',password('password'),'N','N','N','N','N','N',
+'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',
+'','','','',0,0,0,0);
+INSERT INTO mysql.db VALUES
+('%','TESTDB','mysqltest_1','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','N','Y','Y','Y','
+Y','N');
+Warnings:
+Warning	1265	Data truncated for column 'Alter_routine_priv' at row 1
+FLUSH PRIVILEGES;
+create database TEStdb;
+ERROR 42000: Access denied for user 'mysqltest_1'@'%' to database 'TEStdb'
+delete from mysql.user;
+delete from mysql.db where host='%' and user='mysqltest_1' and db='TESTDB';
+insert into mysql.user select * from t1;
+drop table t1, t2;
+drop database TESTDB;
+flush privileges;
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index 430a3a5dd4a..32861d1b184 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -429,3 +429,38 @@ disconnect con2root;
 disconnect con3root;
 
 # End of 4.1 tests
+
+#
+# Bug#17279 user with no global privs and with create
+#           priv in db can create databases
+#
+
+create database TESTDB;
+create table t2(a int);
+create temporary table t1 as select * from mysql.user;
+delete from mysql.user where host='localhost';
+INSERT INTO mysql.user VALUES
+('%','mysqltest_1',password('password'),'N','N','N','N','N','N',
+'N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N','N',
+'','','','',0,0,0,0);
+INSERT INTO mysql.db VALUES
+('%','TESTDB','mysqltest_1','Y','Y','Y','Y','Y','Y','N','Y','Y','Y','Y','N','Y','Y','Y','
+Y','N');
+FLUSH PRIVILEGES;
+
+connect (con1,localhost,mysqltest_1,password,TESTDB);
+
+# The user mysqltest_1 should only be allowed access to
+# database TESTDB, not TEStdb
+--error 1044
+create database TEStdb;
+
+# Clean-up
+connection default;
+delete from mysql.user;
+delete from mysql.db where host='%' and user='mysqltest_1' and db='TESTDB';
+insert into mysql.user select * from t1;
+drop table t1, t2;
+drop database TESTDB;
+flush privileges;
+
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index c67ce383398..88c3c86aacb 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -148,7 +148,9 @@ my_bool acl_init(bool dont_read_acl_tables)
 
   acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0,
                            (hash_get_key) acl_entry_get_key,
-                           (hash_free_key) free, system_charset_info);
+                           (hash_free_key) free,
+                           /* Use the case sensitive "binary" charset */
+                           &my_charset_bin);
   if (dont_read_acl_tables)
   {
     DBUG_RETURN(0); /* purecov: tested */

From f56e873418b1197525552b88b1d6a4d6b472543b Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Mon, 27 Feb 2006 16:44:23 +0100
Subject: [PATCH 071/103] BUG#2845 client fails to reconnect if using TCP/IP  -
 Use 'poll' if available  - Check that sd <= FD_SETSIZE if using 'select'  -
 Handle case when 'net_data_is_ready' returns -1, ie. sd > FD_SETSIZE and
 'select' is used

sql/net_serv.cc:
  Use 'poll' in favor of 'select' if avaliable
  This is to avoid the limitation with 'select' only being able to handle fd's with numbers <= 1024 as default.
  If 'poll' is not available use 'select' but check that we are not having a number higher than FD_SETSIZE
  Handle the case when 'net_data_is_ready' can't check if there is data to read, since the sd number is too high
---
 sql/net_serv.cc | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index ef56f0d77e2..b3ee28607ad 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -208,23 +208,40 @@ my_bool net_realloc(NET *net, ulong length)
   RETURN VALUES
     0	No data to read
     1	Data or EOF to read
+    -1  Don't know if data is ready or not
 */
 
-static my_bool net_data_is_ready(my_socket sd)
+static int net_data_is_ready(my_socket sd)
 {
+#ifdef HAVE_POLL
+  struct pollfd ufds;
+  int res;
+
+  ufds.fd= sd;
+  ufds.events= POLLIN | POLLPRI;
+  if (!(res= poll(&ufds, 1, 0)))
+    return 0;
+  if (res < 0 || !(ufds.revents & (POLLIN | POLLPRI)))
+    return 0;
+  return 1;
+#else
   fd_set sfds;
   struct timeval tv;
   int res;
 
+  if (sd >= FD_SETSIZE)
+    return -1;
+
   FD_ZERO(&sfds);
   FD_SET(sd, &sfds);
 
   tv.tv_sec= tv.tv_usec= 0;
 
   if ((res= select(sd+1, &sfds, NULL, NULL, &tv)) < 0)
-    return FALSE;
+    return 0;
   else
     return test(res ? FD_ISSET(sd, &sfds) : 0);
+#endif
 }
 
 
@@ -251,10 +268,10 @@ static my_bool net_data_is_ready(my_socket sd)
 
 void net_clear(NET *net)
 {
-  int count;
+  int count, ready;
   DBUG_ENTER("net_clear");
 #if !defined(EMBEDDED_LIBRARY)
-  while(net_data_is_ready(net->vio->sd))
+  while((ready= net_data_is_ready(net->vio->sd)) != 0)
   {
     /* The socket is ready */
     if ((count= vio_read(net->vio, (char*) (net->buff),
@@ -269,6 +286,10 @@ void net_clear(NET *net)
     }
     else
     {
+      /* No data to read and 'net_data_is_ready' returned "don't know" */
+      if (ready == -1)
+        break;
+
       DBUG_PRINT("info",("socket ready but only EOF to read - disconnected"));
       net->error= 2;
       break;

From 475eb3e9179fa4c1af3e0daa980dc6f30025ac28 Mon Sep 17 00:00:00 2001
From: unknown <dlenev@mysql.com>
Date: Mon, 27 Feb 2006 20:00:06 +0300
Subject: [PATCH 072/103] Fixed test results after bad auto-merge.

---
 mysql-test/r/ps.result | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index a7c05e9acad..4d108e06356 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -859,6 +859,20 @@ count(*)
 5
 deallocate prepare stmt;
 drop table t1;
+prepare stmt from 'create table t1 (a varchar(10) character set utf8)';
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+execute stmt;
+insert into t1 (a) values (repeat('a', 20));
+select length(a) from t1;
+length(a)
+10
+drop table t1;
+deallocate prepare stmt;
 create table t1 (id int);
 prepare ins_call from "insert into t1 (id) values (1)";
 execute ins_call;

From 2efabfd11a6fa5621c851a472c076e4ef5184d6d Mon Sep 17 00:00:00 2001
From: unknown <dlenev@mysql.com>
Date: Mon, 27 Feb 2006 20:32:32 +0300
Subject: [PATCH 073/103] Fix for trigger.test failures on pushbuild hosts
 introduced by fix for bug #13525 "Rename table does not keep info of
 triggers".

Now we use MYSQLTEST_VARDIR in order to be able to run this test in different
vardir. Also improved cleanup after the test.


mysql-test/t/trigger.test:
  Now we use MYSQLTEST_VARDIR in order to be able to run this test in different
  vardir. Also improved cleanup after the test.
---
 mysql-test/t/trigger.test | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index e1564e33a43..0ac57394c2f 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1028,8 +1028,8 @@ select trigger_schema, trigger_name, event_object_schema,
        event_object_table, action_statement from information_schema.triggers
        where event_object_schema = 'test';
 # Trick which makes update of second .TRN file impossible
-system echo dummy >var/master-data/test/t1_ai.TRN~;
-system chmod 000 var/master-data/test/t1_ai.TRN~;
+system echo dummy >$MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
+system chmod 000 $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
 --error 1
 rename table t1 to t2;
 # 't1' should be still there and triggers should work correctly
@@ -1038,7 +1038,8 @@ select @a, @b;
 select trigger_schema, trigger_name, event_object_schema,
        event_object_table, action_statement from information_schema.triggers
        where event_object_schema = 'test';
-system chmod 600 var/master-data/test/t1_ai.TRN;
+system chmod 600 $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
+system rm $MYSQLTEST_VARDIR/master-data/test/t1_ai.TRN~;
 # Let us check that updates to .TRN files were rolled back too
 drop trigger t1_bi;
 drop trigger t1_ai;

From f9804136bd230c1467b9cb3849cf87bcde40015a Mon Sep 17 00:00:00 2001
From: unknown <lars@mysql.com>
Date: Mon, 27 Feb 2006 18:34:04 +0100
Subject: [PATCH 074/103] BUG#13418: Virtualized some functions so that
 Bit_field class will use correct cmp functions

sql/field.h:
  Virtualized some functions so that Bit_field class will use correct cmp functions
---
 sql/field.h | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/sql/field.h b/sql/field.h
index 218308ead13..b9c438ea907 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -166,8 +166,9 @@ public:
   virtual int cmp(const char *,const char *)=0;
   virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
   { return memcmp(a,b,pack_length()); }
-  int cmp_offset(uint row_offset) { return cmp(ptr,ptr+row_offset); }
-  int cmp_binary_offset(uint row_offset)
+  virtual int cmp_offset(uint row_offset)
+  { return cmp(ptr,ptr+row_offset); }
+  virtual int cmp_binary_offset(uint row_offset)
   { return cmp_binary(ptr, ptr+row_offset); };
   virtual int key_cmp(const byte *a,const byte *b)
   { return cmp((char*) a,(char*) b); }
@@ -1327,6 +1328,8 @@ public:
   { return cmp_binary((char *) a, (char *) b); }
   int key_cmp(const byte *str, uint length);
   int cmp_offset(uint row_offset);
+  int cmp_binary_offset(uint row_offset)
+  { return cmp_offset(row_offset); }
   void get_key_image(char *buff, uint length, imagetype type);
   void set_key_image(char *buff, uint length)
   { Field_bit::store(buff, length, &my_charset_bin); }

From bc6a0661aadf9ebce85627b08b200b3855016d75 Mon Sep 17 00:00:00 2001
From: unknown <SergeyV@selena.>
Date: Mon, 27 Feb 2006 22:14:48 +0300
Subject: [PATCH 075/103] Postfix for #17595. few lines in a test were
 accidentally commented. Comments removed.

---
 mysql-test/t/skip_grants.test | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test
index 45b1d258e4a..27220c9b507 100644
--- a/mysql-test/t/skip_grants.test
+++ b/mysql-test/t/skip_grants.test
@@ -12,8 +12,8 @@ use test;
 # test that we can create VIEW if privileges check switched off
 #
 create table t1 (field1 INT);
-#--error ER_MALFORMED_DEFINER
-#CREATE VIEW v1 AS SELECT field1 FROM t1;
+-- error ER_MALFORMED_DEFINER
+CREATE VIEW v1 AS SELECT field1 FROM t1;
 drop table t1;
 
 #

From d89abfc03c2b0bdcebc9eae652954fe06f5b2274 Mon Sep 17 00:00:00 2001
From: unknown <gluh@eagle.intranet.mysql.r18.ru>
Date: Tue, 28 Feb 2006 13:36:41 +0400
Subject: [PATCH 076/103] Fix for bug#17602 Server crash on AVG/SUM over
 DECIMAL column(2nd ver) The table may be corrupted and decimal columns may
 have invalid values in this case. To prevent crash we need to check that
 decimal column has allowable value. In case of invalid value generate warning
 and set the value to 0.

---
 strings/decimal.c | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/strings/decimal.c b/strings/decimal.c
index 5fb37d374a2..8786a513945 100644
--- a/strings/decimal.c
+++ b/strings/decimal.c
@@ -1347,6 +1347,8 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale)
     }
     from+=i;
     *buf=x ^ mask;
+    if (((uint32)*buf) >=  powers10[intg0x+1])
+      goto err;
     if (buf > to->buf || *buf != 0)
       buf++;
     else
@@ -1356,6 +1358,8 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale)
   {
     DBUG_ASSERT(sizeof(dec1) == 4);
     *buf=mi_sint4korr(from) ^ mask;
+    if (((uint32)*buf) > DIG_MAX)
+      goto err;
     if (buf > to->buf || *buf != 0)
       buf++;
     else
@@ -1366,6 +1370,8 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale)
   {
     DBUG_ASSERT(sizeof(dec1) == 4);
     *buf=mi_sint4korr(from) ^ mask;
+    if (((uint32)*buf) > DIG_MAX)
+      goto err;
     buf++;
   }
   if (frac0x)
@@ -1381,10 +1387,17 @@ int bin2decimal(char *from, decimal_t *to, int precision, int scale)
       default: DBUG_ASSERT(0);
     }
     *buf=(x ^ mask) * powers10[DIG_PER_DEC1 - frac0x];
+    if (((uint32)*buf) > DIG_MAX)
+      goto err;
     buf++;
   }
   my_afree(d_copy);
   return error;
+
+err:
+  my_afree(d_copy);
+  decimal_make_zero(((decimal_t*) to));
+  return(E_DEC_BAD_NUM);
 }
 
 /*

From ddbf62ca89aeafefe958de28799d60522118ebe4 Mon Sep 17 00:00:00 2001
From: unknown <evgen@moonbone.local>
Date: Tue, 28 Feb 2006 19:30:30 +0300
Subject: [PATCH 077/103] Fixed bug#14169: type of group_concat() result
 changed to blob if tmp_table was used

In a simple queries a result of the GROUP_CONCAT() function was always of
varchar type.
But if length of GROUP_CONCAT() result is greater than 512 chars and temporary
table is used during select then the result is converted to blob, due to
policy to not to store fields longer than 512 chars in tmp table as varchar
fields.

In order to provide consistent behaviour, result of GROUP_CONCAT() now
will always be converted to blob if it is longer than 512 chars.
Item_func_group_concat::field_type() is modified accordingly.


sql/item_sum.h:
  Fixed bug#14169: type of group_concat() result changed to blob if tmp_table was
  used
  The Item_func_group_concat::field_type() now returns FIELD_TYPE_BLOB if the result is longer than 512 chars.
tests/mysql_client_test.c:
  Added test case for bug#14169: type of group_concat() result changed to blob if tmp_table was used
---
 sql/item_sum.h            |  7 +++++++
 tests/mysql_client_test.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/sql/item_sum.h b/sql/item_sum.h
index a8242d76287..a38530a502c 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1116,6 +1116,13 @@ public:
   enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
   const char *func_name() const { return "group_concat"; }
   virtual Item_result result_type () const { return STRING_RESULT; }
+  enum_field_types field_type() const
+  {
+    if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB)
+      return FIELD_TYPE_BLOB;
+    else
+      return MYSQL_TYPE_VARCHAR;
+  }
   void clear();
   bool add();
   void reset_field() { DBUG_ASSERT(0); }        // not used
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index c265375a263..8ec5bcd6f0c 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -14841,6 +14841,40 @@ static void test_bug15613()
 }
 
 /*
+  Bug#14169: type of group_concat() result changed to blob if tmp_table was used
+*/
+static void test_bug14169()
+{
+  MYSQL_STMT *stmt;
+  const char *stmt_text;
+  MYSQL_RES *res;
+  MYSQL_FIELD *field;
+  int rc;
+
+  myheader("test_bug14169");
+
+  rc= mysql_query(mysql, "drop table if exists t1");
+  myquery(rc);
+  rc= mysql_query(mysql, "set session group_concat_max_len=1024");
+  myquery(rc);
+  rc= mysql_query(mysql, "create table t1 (f1 int unsigned, f2 varchar(255))");
+  myquery(rc);
+  rc= mysql_query(mysql, "insert into t1 values (1,repeat('a',255)),"
+                         "(2,repeat('b',255))");
+  myquery(rc);
+  stmt= mysql_stmt_init(mysql);
+  stmt_text= "select f2,group_concat(f1) from t1 group by f2";
+  rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
+  myquery(rc);
+  res= mysql_stmt_result_metadata(stmt);
+  field= mysql_fetch_fields(res);
+  if (!opt_silent)
+    printf("GROUP_CONCAT() result type %i", field[1].type);
+  DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB);
+
+  rc= mysql_query(mysql, "drop table t1");
+  myquery(rc);
+}/*
   Read and parse arguments and MySQL options from my.cnf
 */
 
@@ -15105,6 +15139,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug16143", test_bug16143 },
   { "test_bug16144", test_bug16144 },
   { "test_bug15613", test_bug15613 },
+  { "test_bug14169", test_bug14169 },
   { 0, 0 }
 };
 

From 46c82ab153f5b19a5c55ef214bd60fb5ba76829a Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 12:01:24 -0600
Subject: [PATCH 078/103] mysqltest.c:   Fix typos.

client/mysqltest.c:
  Fix typos.
---
 client/mysqltest.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 613c4e12763..805c9330c6a 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -115,8 +115,8 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
   The list of error codes to --error are stored in an internal array of
   structs. This struct can hold numeric SQL error codes or SQLSTATE codes
   as strings. The element next to the last active element in the list is
-  set to type ERR_EMPTY. When an SQL statement return an error we use
-  this list to check if this  is an expected error.
+  set to type ERR_EMPTY. When an SQL statement returns an error, we use
+  this list to check if this is an expected error.
 */
  
 enum match_err_type
@@ -986,8 +986,8 @@ int do_source(struct st_query *query)
     *p++= 0;
   query->last_argument= p;
   /*
-     If this file has already been sourced, dont source it again.
-     It's already available in the q_lines cache
+     If this file has already been sourced, don't source it again.
+     It's already available in the q_lines cache.
   */
   if (parser.current_line < (parser.read_lines - 1))
     return 0;
@@ -2151,7 +2151,7 @@ my_bool end_of_query(int c)
     Normally that means it will read lines until it reaches the
     "delimiter" that marks end of query. Default delimiter is ';'
     The function should be smart enough not to detect delimiter's
-    found inside strings sorrounded with '"' and '\'' escaped strings.
+    found inside strings surrounded with '"' and '\'' escaped strings.
 
     If the first line in a query starts with '#' or '-' this line is treated
     as a comment. A comment is always terminated when end of line '\n' is
@@ -2485,7 +2485,7 @@ static struct my_option my_long_options[] =
   {"result-file", 'R', "Read/Store result from/in this file.",
    (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG,
    0, 0, 0, 0, 0, 0},
-  {"server-arg", 'A', "Send enbedded server this as a paramenter.",
+  {"server-arg", 'A', "Send option value to embedded server as a parameter.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
   {"server-file", 'F', "Read embedded server arguments from file.",
    0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -4074,8 +4074,8 @@ int main(int argc, char **argv)
     /*
       my_stat() successful on result file. Check if we have not run a
       single query, but we do have a result file that contains data.
-      Note that we don't care, if my_stat() fails. For example for
-      non-existing or non-readable file we assume it's fine to have
+      Note that we don't care, if my_stat() fails. For example, for a
+      non-existing or non-readable file, we assume it's fine to have
       no query output from the test file, e.g. regarded as no error.
     */
     if (res_info.st_size)

From 773c1e049ac90f28e25a721ca85da588f4ad0560 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 12:19:30 -0600
Subject: [PATCH 079/103] mysqltest.c:   Fix typos.

client/mysqltest.c:
  Fix typos.
---
 client/mysqltest.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 57bb907170e..0ee8486a31d 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1370,7 +1370,7 @@ int do_modify_var(struct st_query *query, const char *name,
     system <command>
 
     Eval the query to expand any $variables in the command.
-    Execute the command withe the "system" command.
+    Execute the command with the "system" command.
 
   NOTE
    If mysqltest is executed from cygwin shell, the command will be
@@ -2099,7 +2099,7 @@ int safe_connect(MYSQL* mysql, const char *host, const char *user,
 
 
 /*
-  Connect to a server and handle connection errors in case when they occur.
+  Connect to a server and handle connection errors in case they occur.
 
   SYNOPSIS
     connect_n_handle_errors()
@@ -2819,7 +2819,7 @@ static struct my_option my_long_options[] =
   {"compress", 'C', "Use the compressed server/client protocol.",
    (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0,
    0, 0, 0},
-  {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statment",
+  {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statements.",
    (gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0,
    GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
   {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0,

From 9099fb2d063b537f7a8c94d18dbe163d4945f955 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 14:00:17 -0600
Subject: [PATCH 080/103] mysqltest.c:   Correct/clarify comments.

client/mysqltest.c:
  Correct/clarify comments.
---
 client/mysqltest.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 805c9330c6a..83be283a050 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -320,13 +320,6 @@ const char *command_names[]=
   "connection",
   "query",
   "connect",
-  /* the difference between sleep and real_sleep is that sleep will use
-     the delay from command line (--sleep) if there is one.
-     real_sleep always uses delay from mysqltest's command line argument.
-     the logic is that sometimes delays are cpu-dependent (and --sleep
-     can be used to set this delay. real_sleep is used for cpu-independent
-     delays
-   */
   "sleep",
   "real_sleep",
   "inc",
@@ -1536,11 +1529,19 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
    do_sleep()
     q	       called command
     real_sleep  use the value from opt_sleep as number of seconds to sleep
+	            if real_sleep is false
 
   DESCRIPTION
     sleep <seconds>
-    real_sleep
+    real_sleep <seconds>
 
+  The difference between the sleep and real_sleep commands is that sleep
+  uses the delay from the --sleep command-line option if there is one.
+  (If the --sleep option is not given, the sleep command uses the delay
+  specified by its argument.) The real_sleep command always uses the
+  delay specified by its argument.  The logic is that sometimes delays are
+  cpu-dependent, and --sleep can be used to set this delay.  real_sleep is
+  used for cpu-independent delays.
 */
 
 int do_sleep(struct st_query *query, my_bool real_sleep)

From 046530d5bc1a91131bbebaaab043486d5cb03988 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 14:04:21 -0600
Subject: [PATCH 081/103] mysqltest.c:   Fix reference to incorrect
 (non-existent) options in comment.

client/mysqltest.c:
  Fix reference to incorrect (non-existent) options in comment.
---
 client/mysqltest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 3493a781875..1ddbe76700e 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -4316,7 +4316,7 @@ void get_query_type(struct st_query* q)
     q->type=(enum enum_commands) type;		/* Found command */
     /*
       If queries are disabled, only recognize
-      --enable-queries and --disable-queries
+      --enable_parsing and --disable_parsing
     */
     if (parsing_disabled && q->type != Q_ENABLE_PARSING &&
         q->type != Q_DISABLE_PARSING)

From 8d5f0fcddcb7b3c5dd7d2f79dd04ba95c61779e9 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 15:08:16 -0600
Subject: [PATCH 082/103] mysql-test-run.sh:   Fix URLs. README:   Fix URL.
 mysqltest.result:   Update test result for real_sleep error message.
 mysqltest.c:   Fix do_sleep() to print correct command name for real_sleep.

client/mysqltest.c:
  Fix do_sleep() to print correct command name for real_sleep.
mysql-test/r/mysqltest.result:
  Update test result for real_sleep error message.
mysql-test/README:
  Fix URL.
mysql-test/mysql-test-run.sh:
  Fix URLs.
---
 client/mysqltest.c            | 7 ++++---
 mysql-test/README             | 2 +-
 mysql-test/mysql-test-run.sh  | 4 ++--
 mysql-test/r/mysqltest.result | 2 ++
 4 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 83be283a050..a525adfd819 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1550,18 +1550,19 @@ int do_sleep(struct st_query *query, my_bool real_sleep)
   char *p= query->first_argument;
   char *sleep_start, *sleep_end= query->end;
   double sleep_val;
+  char *cmd = (real_sleep ? "real_sleep" : "sleep");
 
   while (my_isspace(charset_info, *p))
     p++;
   if (!*p)
-    die("Missing argument to sleep");
+    die("Missing argument to %s", cmd);
   sleep_start= p;
   /* Check that arg starts with a digit, not handled by my_strtod */
   if (!my_isdigit(charset_info, *sleep_start))
-    die("Invalid argument to sleep \"%s\"", query->first_argument);
+    die("Invalid argument to %s \"%s\"", cmd, query->first_argument);
   sleep_val= my_strtod(sleep_start, &sleep_end, &error);
   if (error)
-    die("Invalid argument to sleep \"%s\"", query->first_argument);
+    die("Invalid argument to %s \"%s\"", cmd, query->first_argument);
 
   /* Fixed sleep time selected by --sleep option */
   if (opt_sleep && !real_sleep)
diff --git a/mysql-test/README b/mysql-test/README
index 10d64784ed4..0e20ca884a3 100644
--- a/mysql-test/README
+++ b/mysql-test/README
@@ -21,7 +21,7 @@ conflict with it.
 All tests must pass. If one or more of them fail on your system, please
 read the following manual section of how to report the problem:
 
-http://dev.mysql.com/doc/mysql/en/MySQL_test_suite.html
+http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html
 
 
 You can create your own test cases. To create a test case:
diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 9fcdacb22cb..b9512f7dd79 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -789,7 +789,7 @@ show_failed_diff ()
     $DIFF -c $result_file $reject_file
     echo "-------------------------------------------------------"
     echo "Please follow the instructions outlined at"
-    echo "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html"
+    echo "http://dev.mysql.com/doc/mysql/en/reporting-mysqltest-bugs.html"
     echo "to find the reason to this problem and how to report this."
     echo ""
   fi
@@ -884,7 +884,7 @@ report_stats () {
         $ECHO "The log files in $MY_LOG_DIR may give you some hint"
 	$ECHO "of what when wrong."
 	$ECHO "If you want to report this error, please read first the documentation at"
-        $ECHO "http://www.mysql.com/doc/en/MySQL_test_suite.html"
+        $ECHO "http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html"
     fi
 
     if test -z "$USE_RUNNING_SERVER"
diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result
index 0e3d3812781..990f04e5ba9 100644
--- a/mysql-test/r/mysqltest.result
+++ b/mysql-test/r/mysqltest.result
@@ -280,7 +280,9 @@ here is the sourced script
 In loop
 here is the sourced script
 mysqltest: At line 1: Missing argument to sleep
+mysqltest: At line 1: Missing argument to real_sleep
 mysqltest: At line 1: Invalid argument to sleep "abc"
+mysqltest: At line 1: Invalid argument to real_sleep "abc"
 1
 2
 101

From 618bd0a5e5eab89206f93d7f459ebbccc8e8237f Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 15:11:44 -0600
Subject: [PATCH 083/103] mysqltest.c:   expand tab

client/mysqltest.c:
  expand tab
---
 client/mysqltest.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 5d97bb2e330..0558df7a568 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1626,7 +1626,7 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
    do_sleep()
     q	       called command
     real_sleep  use the value from opt_sleep as number of seconds to sleep
-	            if real_sleep is false
+                if real_sleep is false
 
   DESCRIPTION
     sleep <seconds>

From bf912125a39edbad5f66f8cd53950ae8c43c36fd Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Tue, 28 Feb 2006 17:54:11 -0600
Subject: [PATCH 084/103] mysqltest.test:   Add real_sleep tests.

mysql-test/t/mysqltest.test:
  Add real_sleep tests.
---
 mysql-test/t/mysqltest.test | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test
index 7ed204fc6d3..f5c6a7617c5 100644
--- a/mysql-test/t/mysqltest.test
+++ b/mysql-test/t/mysqltest.test
@@ -605,10 +605,14 @@ real_sleep 1;
 # Missing parameter
 --error 1
 --exec echo "sleep ;" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "real_sleep ;" | $MYSQL_TEST 2>&1
 
 # Illegal parameter
 --error 1
 --exec echo "sleep abc;" | $MYSQL_TEST 2>&1
+--error 1
+--exec echo "real_sleep abc;" | $MYSQL_TEST 2>&1
 
 # ----------------------------------------------------------------------------
 # Test inc

From 6e0d2e41cccb9223b50212dfecf56e43f19df11e Mon Sep 17 00:00:00 2001
From: unknown <joerg@mysql.com>
Date: Wed, 1 Mar 2006 12:21:44 +0100
Subject: [PATCH 085/103] mysql-test/mysql-test-run.sh  :  Add a
 "--comment=<string>" option, to get it logged when the test is run.

mysql-test/mysql-test-run.sh:
  Add a "--comment=<string>" option, to get it logged when the test is run.
  The purpose is to allow a better analysis when generating the status page
  ("gen-build-status-page").
  See "Do-compile" for how it is used.
---
 mysql-test/mysql-test-run.sh | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh
index 3488c308536..5853ffa201c 100644
--- a/mysql-test/mysql-test-run.sh
+++ b/mysql-test/mysql-test-run.sh
@@ -410,6 +410,13 @@ while test $# -gt 0; do
     --fast)
       FAST_START=1
       ;;
+    --comment=*)
+      TMP=`$ECHO "$1" | $SED -e "s;--comment=;;"`
+      echo
+      echo '############################################'
+      echo "# $TMP"
+      echo '############################################'
+      ;;
     -- )  shift; break ;;
     --* ) $ECHO "Unrecognized option: $1"; exit 1 ;;
     * ) break ;;

From b17bb278f760bdd646192eb6bff51ea5ad5c3975 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot@deer.(none)>
Date: Wed, 1 Mar 2006 15:50:15 +0400
Subject: [PATCH 086/103] bug #9088 (bigint WHERE fails)

mysql-test/r/bigint.result:
  test result
mysql-test/t/bigint.test:
  testcase
sql/item.h:
  unsigned_arg is a separate parameter now
sql/item_cmpfunc.cc:
  we can get unsigned field from the signed Item - from string
  like '1234'
---
 mysql-test/r/bigint.result | 9 +++++++++
 mysql-test/t/bigint.test   | 9 +++++++++
 sql/item.h                 | 5 +++--
 sql/item_cmpfunc.cc        | 3 ++-
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/bigint.result b/mysql-test/r/bigint.result
index 84779858b75..3cdf4b17027 100644
--- a/mysql-test/r/bigint.result
+++ b/mysql-test/r/bigint.result
@@ -332,3 +332,12 @@ SELECT * FROM t1;
 col1	col2	col3	col4	col5	col6	col7	col8	col9	col10	col11	col12	col13	col14	col15	col16	col17	col18	col19	col20	col21	col22	col23	col24	col25	col26	col27	col28	col29	col30	col31	col32	col33	col34	col35	col36	col37	col38	fix1	fix2	fix3	fix4	fix5	fix6	fix7	fix8	fix9	fix10	fix11	fix12	fix13	fix14	fix15	fix16	fix17	fix18	fix19	fix20	fix21	fix22	fix23	fix24	fix25	fix26	fix27	fix28	fix29	fix30
 9	99	999	9999	99999	999999	9999999	99999999	999999999	9999999999	99999999999	999999999999	9999999999999	99999999999999	999999999999999	9999999999999999	99999999999999999	999999999999999999	9999999999999999999	99999999999999999999	999999999999999999999	9999999999999999999999	99999999999999999999999	999999999999999999999999	9999999999999999999999999	99999999999999999999999999	999999999999999999999999999	9999999999999999999999999999	99999999999999999999999999999	999999999999999999999999999999	9999999999999999999999999999999	99999999999999999999999999999999	999999999999999999999999999999999	9999999999999999999999999999999999	99999999999999999999999999999999999	999999999999999999999999999999999999	9999999999999999999999999999999999999	99999999999999999999999999999999999999	9999999999999999999999999999999999999.9	999999999999999999999999999999999999.99	99999999999999999999999999999999999.999	9999999999999999999999999999999999.9999	999999999999999999999999999999999.99999	99999999999999999999999999999999.999999	9999999999999999999999999999999.9999999	999999999999999999999999999999.99999999	99999999999999999999999999999.999999999	9999999999999999999999999999.9999999999	999999999999999999999999999.99999999999	99999999999999999999999999.999999999999	9999999999999999999999999.9999999999999	999999999999999999999999.99999999999999	99999999999999999999999.999999999999999	9999999999999999999999.9999999999999999	999999999999999999999.99999999999999999	99999999999999999999.999999999999999999	9999999999999999999.9999999999999999999	999999999999999999.99999999999999999999	99999999999999999.999999999999999999999	9999999999999999.9999999999999999999999	999999999999999.99999999999999999999999	99999999999999.999999999999999999999999	9999999999999.9999999999999999999999999	999999999999.99999999999999999999999999	99999999999.999999999999999999999999999	9999999999.9999999999999999999999999999	999999999.99999999999999999999999999999	99999999.999999999999999999999999999999
 DROP TABLE t1;
+create table t1 (bigint_col bigint unsigned);
+insert into t1 values (17666000000000000000);
+select * from t1 where bigint_col=17666000000000000000;
+bigint_col
+17666000000000000000
+select * from t1 where bigint_col='17666000000000000000';
+bigint_col
+17666000000000000000
+drop table t1;
diff --git a/mysql-test/t/bigint.test b/mysql-test/t/bigint.test
index 7871b3647e3..35cda11646a 100644
--- a/mysql-test/t/bigint.test
+++ b/mysql-test/t/bigint.test
@@ -270,3 +270,12 @@ VALUES (9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999,
 
 SELECT * FROM t1;
 DROP TABLE t1;
+
+#bug #9088 BIGINT WHERE CLAUSE
+create table t1 (bigint_col bigint unsigned);
+insert into t1 values (17666000000000000000);
+select * from t1 where bigint_col=17666000000000000000;
+select * from t1 where bigint_col='17666000000000000000';
+drop table t1;
+
+
diff --git a/sql/item.h b/sql/item.h
index 2029658d476..a859b067632 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1887,9 +1887,10 @@ class Item_int_with_ref :public Item_int
 {
   Item *ref;
 public:
-  Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg)
+  Item_int_with_ref(longlong i, Item *ref_arg, my_bool unsigned_arg) :
+    Item_int(i), ref(ref_arg)
   {
-    unsigned_flag= ref_arg->unsigned_flag;
+    unsigned_flag= unsigned_arg;
   }
   int save_in_field(Field *field, bool no_conversions)
   {
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index d812ce913c5..7ba8a536ac7 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -216,7 +216,8 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
     field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES;
     if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
     {
-      Item *tmp=new Item_int_with_ref(field->val_int(), *item);
+      Item *tmp=new Item_int_with_ref(field->val_int(), *item,
+                                      test(field->flags & UNSIGNED_FLAG));
       field->table->in_use->variables.sql_mode= orig_sql_mode;
       if (tmp)
         thd->change_item_tree(item, tmp);

From ca3dd7f01aae783c2f8efea6adbf446e2c410c42 Mon Sep 17 00:00:00 2001
From: unknown <joerg@mysql.com>
Date: Wed, 1 Mar 2006 13:15:37 +0100
Subject: [PATCH 087/103] mysql-test/mysql-test-run.pl  :  Add a
 "--comment=<string>" option (backport from 5.1).

mysql-test/mysql-test-run.pl:
  Add a "--comment=<string>" option (backport from 5.1).
  Its sole purpose is to get logged, so that test evaluation gets easier.
  See "Do-compile" for how it is called, and "gen-build-status-page" for its effect.
---
 mysql-test/mysql-test-run.pl | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index addacab8f9a..09c3dff9749 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -184,6 +184,7 @@ our $opt_big_test= 0;            # Send --big-test to mysqltest
 
 our @opt_extra_mysqld_opt;
 
+our $opt_comment;
 our $opt_compress;
 our $opt_current_test;
 our $opt_ddd;
@@ -536,6 +537,7 @@ sub command_line_setup () {
 
              # Misc
              'big-test'                 => \$opt_big_test,
+             'comment=s'                => \$opt_comment,
              'compress'                 => \$opt_compress,
              'debug'                    => \$opt_debug,
              'fast'                     => \$opt_fast,
@@ -571,6 +573,14 @@ sub command_line_setup () {
     usage("");
   }
 
+  if ( $opt_comment )
+  {
+    print "\n";
+    print '#' x 78, "\n";
+    print "# $opt_comment\n";
+    print '#' x 78, "\n\n";
+  }
+
   foreach my $arg ( @ARGV )
   {
     if ( $arg =~ /^--skip-/ )
@@ -2398,6 +2408,7 @@ Misc options
 
   verbose               Verbose output from this script
   script-debug          Debug this script itself
+  comment=STR           Write STR to the output
   compress              Use the compressed protocol between client and server
   timer                 Show test case execution time
   start-and-exit        Only initiate and start the "mysqld" servers, use the startup

From 2281f754e2180762b157f1714adc45cc04654420 Mon Sep 17 00:00:00 2001
From: unknown <aivanov@mysql.com>
Date: Wed, 1 Mar 2006 16:21:01 +0300
Subject: [PATCH 088/103] Fixed BUG #16175: Memory leak in rpl_trigger.test  
 Allocating/freeing memory for the db member of THD   is wholy managed by
 slave thread.

---
 sql/sql_db.cc | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 357d2d5a21f..63a7b1df8f1 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1098,7 +1098,8 @@ err:
 bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
 {
   int length, db_length;
-  char *dbname=my_strdup((char*) name,MYF(MY_WME));
+  char *dbname= thd->slave_thread ? (char *) name :
+                                    my_strdup((char *) name, MYF(MY_WME));
   char	path[FN_REFLEN];
   HA_CREATE_INFO create;
   bool system_db= 0;
@@ -1118,7 +1119,8 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
       system_db= 1;
       goto end;
     }
-    x_free(dbname);				/* purecov: inspected */
+    if (!(thd->slave_thread))
+      x_free(dbname);				/* purecov: inspected */
     my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
                MYF(0));                         /* purecov: inspected */
     DBUG_RETURN(1);				/* purecov: inspected */
@@ -1126,7 +1128,8 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
   if (check_db_name(dbname))
   {
     my_error(ER_WRONG_DB_NAME, MYF(0), dbname);
-    x_free(dbname);
+    if (!(thd->slave_thread))
+      x_free(dbname);
     DBUG_RETURN(1);
   }
   DBUG_PRINT("info",("Use database: %s", dbname));
@@ -1156,7 +1159,8 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
                dbname);
       mysql_log.write(thd, COM_INIT_DB, ER(ER_DBACCESS_DENIED_ERROR),
                       sctx->priv_user, sctx->priv_host, dbname);
-      my_free(dbname,MYF(0));
+      if (!(thd->slave_thread))
+        my_free(dbname,MYF(0));
       DBUG_RETURN(1);
     }
   }
@@ -1168,7 +1172,8 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check)
   if (my_access(path,F_OK))
   {
     my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
-    my_free(dbname,MYF(0));
+    if (!(thd->slave_thread))
+      my_free(dbname,MYF(0));
     DBUG_RETURN(1);
   }
 end:

From 69012c7524a376303924395e5713cf355145e4c6 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@shellback.(none)>
Date: Wed, 1 Mar 2006 15:21:03 +0100
Subject: [PATCH 089/103] Bug#2845 client fails to reconnect if using TCP/IP  -
 Change to use non blocking read to empty channel in case of too large sd
 number  - Don't check for too large socket number on Windows.

sql/net_serv.cc:
  Windows does not need protection from sd >= FD_SETSIZE, it uses an array to store the sd's it should read from.
  Change the handler for when "net_data_is_ready" returns -1 to perform nonblocking read to empty the net.
  Only include that handler if HAVE_POLL is not defined  and not windows
---
 sql/net_serv.cc | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index b3ee28607ad..c5794fb4d25 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -229,8 +229,12 @@ static int net_data_is_ready(my_socket sd)
   struct timeval tv;
   int res;
 
+#ifndef __WIN__
+  /* Windows uses an _array_ of 64 fd's as default, so it's safe */
   if (sd >= FD_SETSIZE)
     return -1;
+  #define NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
+#endif
 
   FD_ZERO(&sfds);
   FD_SET(sd, &sfds);
@@ -271,7 +275,7 @@ void net_clear(NET *net)
   int count, ready;
   DBUG_ENTER("net_clear");
 #if !defined(EMBEDDED_LIBRARY)
-  while((ready= net_data_is_ready(net->vio->sd)) != 0)
+  while((ready= net_data_is_ready(net->vio->sd)) > 0)
   {
     /* The socket is ready */
     if ((count= vio_read(net->vio, (char*) (net->buff),
@@ -286,15 +290,27 @@ void net_clear(NET *net)
     }
     else
     {
-      /* No data to read and 'net_data_is_ready' returned "don't know" */
-      if (ready == -1)
-        break;
-
       DBUG_PRINT("info",("socket ready but only EOF to read - disconnected"));
       net->error= 2;
       break;
     }
   }
+#ifdef NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
+  /* 'net_data_is_ready' returned "don't know" */
+  if (ready == -1)
+  {
+    /* Read unblocking to clear net */
+    my_bool old_mode;
+    if (!vio_blocking(net->vio, FALSE, &old_mode))
+    {
+      while ((count= vio_read(net->vio, (char*) (net->buff),
+                              (uint32) net->max_packet)) > 0)
+	DBUG_PRINT("info",("skipped %d bytes from file: %s",
+			   count, vio_description(net->vio)));
+      vio_blocking(net->vio, TRUE, &old_mode);
+    }
+  }
+#endif
 #endif
   net->pkt_nr=net->compress_pkt_nr=0;		/* Ready for new command */
   net->write_pos=net->buff;

From ab13e772d6ca83ae85941091391d6be6d78141d4 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@shellback.(none)>
Date: Wed, 1 Mar 2006 15:22:47 +0100
Subject: [PATCH 090/103] Dont' run the mysql_protocols on Windows

---
 mysql-test/t/mysql_protocols.test | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/mysql-test/t/mysql_protocols.test b/mysql-test/t/mysql_protocols.test
index 0253c2b5d17..5eba780420c 100644
--- a/mysql-test/t/mysql_protocols.test
+++ b/mysql-test/t/mysql_protocols.test
@@ -1,5 +1,7 @@
 # Embedded server doesn't support external clients
 --source include/not_embedded.inc
+# Windows does not have SOCKET, but will try to create a PIPE as well as MEMORY
+--source include/not_windows.inc
 
 # test for Bug #4998 "--protocol doesn't reject bad values"
 

From 7526342706bb18601e4a1e19c75fbbd95be210de Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Wed, 1 Mar 2006 17:37:07 -0600
Subject: [PATCH 091/103] README:   Revise mysql-test README.

mysql-test/README:
  Revise mysql-test README.
---
 mysql-test/README | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/mysql-test/README b/mysql-test/README
index 6ad97adbd2b..0e20ca884a3 100644
--- a/mysql-test/README
+++ b/mysql-test/README
@@ -1,6 +1,19 @@
 This directory contains a test suite for mysql daemon. To run
 the currently existing test cases, simply execute ./mysql-test-run in
 this directory. It will fire up the newly built mysqld and test it.
+
+If you want to run a test with a running MySQL server use the --extern
+option to mysql-test-run. Please note that in this mode the test suite
+expects user to specify test names to run. Otherwise it falls back to the
+normal "non-extern" behaviour. The reason is that some tests
+could not run with external server. Here is the sample command
+to test "alias" and "analyze" tests on external server:
+
+mysql-test-run --extern alias analyze
+
+To match your setup you might also need to provide --socket, --user and
+other relevant options.
+
 Note that you do not have to have to do make install, and you could
 actually have a co-existing MySQL installation - the tests will not
 conflict with it.
@@ -8,13 +21,12 @@ conflict with it.
 All tests must pass. If one or more of them fail on your system, please
 read the following manual section of how to report the problem:
 
-http://dev.mysql.com/doc/mysql/en/MySQL_test_suite.html
+http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html
 
 
 You can create your own test cases. To create a test case:
 
- cd t
- vi test_case_name.test
+ xemacs t/test_case_name.test
 
  in the file, put a set of SQL commands that will create some tables,
  load test data, run some queries to manipulate it.

From 79faaddce79e91d5ed1e88e05d3c337de77d4087 Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Wed, 1 Mar 2006 17:55:10 -0600
Subject: [PATCH 092/103] README.gcov:   Revise README.gcov.

mysql-test/README.gcov:
  Revise README.gcov.
---
 mysql-test/README.gcov | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/mysql-test/README.gcov b/mysql-test/README.gcov
index 83ddd6df2e1..6d2852e8ca0 100644
--- a/mysql-test/README.gcov
+++ b/mysql-test/README.gcov
@@ -1,11 +1,13 @@
 To be able to see the level of coverage with the current test suite,
 do the following:
 
-  - make sure gcov is installed
-  - compile with BUILD/compile-pentium-gcov ( if your machine is not pentium, hack
-this script, or just live with the pentium-specific stuff)
-  - ./mysql-test-run -gcov
-  - to see the level of coverage for a given source file:
+  - Make sure gcov is installed
+  - Compile the MySQL distribution with BUILD/compile-pentium-gcov (if your
+    machine does not have a pentium CPU, hack this script, or just live with
+	the pentium-specific stuff)
+  - In the mysql-test directory, run this command: ./mysql-test-run -gcov
+  - To see the level of coverage for a given source file:
      grep source_file_name /tmp/gcov.out
-  - to see which lines are not yet covered, look at source_file_name.gcov in the source tree. Then think hard about a test case that will cover those
-lines, and write one!
+  - To see which lines are not yet covered, look at source_file_name.gcov in
+    the source tree. Then think hard about a test case that will cover those
+    lines, and write one!

From aa9a497d7ad44dbeda7100b71916d3af9bfd5c0c Mon Sep 17 00:00:00 2001
From: unknown <paul@snake-hub.snake.net>
Date: Wed, 1 Mar 2006 18:37:41 -0600
Subject: [PATCH 093/103] README:   revise README.

mysql-test/README:
  revise README.
---
 mysql-test/README | 60 ++++++++++++++++++++++++++---------------------
 1 file changed, 33 insertions(+), 27 deletions(-)

diff --git a/mysql-test/README b/mysql-test/README
index 0e20ca884a3..77b398ebf39 100644
--- a/mysql-test/README
+++ b/mysql-test/README
@@ -1,45 +1,51 @@
-This directory contains a test suite for mysql daemon. To run
+This directory contains a test suite for the MySQL daemon. To run
 the currently existing test cases, simply execute ./mysql-test-run in
 this directory. It will fire up the newly built mysqld and test it.
 
-If you want to run a test with a running MySQL server use the --extern
-option to mysql-test-run. Please note that in this mode the test suite
-expects user to specify test names to run. Otherwise it falls back to the
-normal "non-extern" behaviour. The reason is that some tests
-could not run with external server. Here is the sample command
-to test "alias" and "analyze" tests on external server:
-
-mysql-test-run --extern alias analyze
-
-To match your setup you might also need to provide --socket, --user and
-other relevant options.
-
-Note that you do not have to have to do make install, and you could
-actually have a co-existing MySQL installation - the tests will not
+Note that you do not have to have to do "make install", and you could
+actually have a co-existing MySQL installation. The tests will not
 conflict with it.
 
 All tests must pass. If one or more of them fail on your system, please
-read the following manual section of how to report the problem:
+read the following manual section for instructions on how to report the
+problem:
 
 http://dev.mysql.com/doc/mysql/en/mysql-test-suite.html
 
+If you want to use an already running MySQL server for specific tests,
+use the --extern option to mysql-test-run. Please note that in this mode,
+the test suite expects you to provide the names of the tests to run.
+For example, here is the command to run the "alias" and "analyze" tests
+with an external server:
 
-You can create your own test cases. To create a test case:
+mysql-test-run --extern alias analyze
+
+To match your setup, you might also need to provide --socket, --user, and
+other relevant options.
+
+With no test cases named on the command line, mysql-test-run falls back
+to the normal "non-extern" behavior. The reason for this is that some
+tests cannot run with an external server.
+
+
+You can create your own test cases. To create a test case, create a new
+file in the t subdirectory using a text editor. The file should have a .test
+extension. For example:
 
  xemacs t/test_case_name.test
 
- in the file, put a set of SQL commands that will create some tables,
- load test data, run some queries to manipulate it.
+ In the file, put a set of SQL statements that create some tables,
+ load test data, and run some queries to manipulate it.
 
- We would appreciate if the test tables were called t1, t2, t3 ... (to not
+ We would appreciate it if you name your test tables t1, t2, t3 ... (to not
  conflict too much with existing tables).
 
  Your test should begin by dropping the tables you are going to create and
- end by dropping them again.  This will ensure that one can run the test
- over and over again.
+ end by dropping them again.  This ensures that you can run the test over
+ and over again.
  
  If you are using mysqltest commands (like result file names) in your
- test case you should do create the result file as follows:
+ test case, you should create the result file as follows:
 
  mysql-test-run --record test_case_name
 
@@ -47,8 +53,8 @@ You can create your own test cases. To create a test case:
 
  mysqltest --record < t/test_case_name.test
 
- If you only have a simple test cases consistent of SQL commands and comments
- you can create the test case one of the following ways:
+ If you only have a simple test cases consisting of SQL statements and
+ comments, you can create the test case in one of the following ways:
 
  mysql-test-run --record test_case_name
 
@@ -57,11 +63,11 @@ You can create your own test cases. To create a test case:
  mysqltest --record --record-file=r/test_case_name.result < t/test_case_name.test
 
  When this is done, take a look at r/test_case_name.result
- - If the result is wrong, you have found a bug;  In this case you should
+ - If the result is incorrect, you have found a bug. In this case, you should
    edit the test result to the correct results so that we can verify
    that the bug is corrected in future releases.
 
 To submit your test case, put your .test file and .result file(s) into
 a tar.gz archive, add a README that explains the problem, ftp the 
-archive to ftp://support.mysql.com/pub/mysql/secret/ and send  a mail
+archive to ftp://support.mysql.com/pub/mysql/secret/ and send a mail
 to bugs@lists.mysql.com

From 92ead72dc7c1413749d47c3bf65ee9d25af40f51 Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 2 Mar 2006 10:55:55 +0100
Subject: [PATCH 094/103] Make the define start at "start of line"

---
 sql/net_serv.cc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index c5794fb4d25..c80bb8bad9a 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -233,7 +233,7 @@ static int net_data_is_ready(my_socket sd)
   /* Windows uses an _array_ of 64 fd's as default, so it's safe */
   if (sd >= FD_SETSIZE)
     return -1;
-  #define NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
+#define NET_DATA_IS_READY_CAN_RETURN_MINUS_ONE
 #endif
 
   FD_ZERO(&sfds);

From d5a27fd86fd1cada16d427fd9ffecc08314f4b7e Mon Sep 17 00:00:00 2001
From: unknown <msvensson@neptunus.(none)>
Date: Thu, 2 Mar 2006 11:01:58 +0100
Subject: [PATCH 095/103] Bug#17279 user with no global privs and with create
 priv in db can create database  - Fix test case for systems with "lowercase
 names"

mysql-test/r/grant2.result:
  Fix for system with "lowercase names", allow error 1007 to be returned
mysql-test/t/grant2.test:
  Fix for system with "lowercase names", allow error 1007 to be returned
---
 mysql-test/r/grant2.result | 2 +-
 mysql-test/t/grant2.test   | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result
index 9ddd6d4281e..a42ad0d79a5 100644
--- a/mysql-test/r/grant2.result
+++ b/mysql-test/r/grant2.result
@@ -349,7 +349,7 @@ Warnings:
 Warning	1265	Data truncated for column 'Alter_routine_priv' at row 1
 FLUSH PRIVILEGES;
 create database TEStdb;
-ERROR 42000: Access denied for user 'mysqltest_1'@'%' to database 'TEStdb'
+Got one of the listed errors
 delete from mysql.user;
 delete from mysql.db where host='%' and user='mysqltest_1' and db='TESTDB';
 insert into mysql.user select * from t1;
diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test
index 32861d1b184..2c62d2f1bd3 100644
--- a/mysql-test/t/grant2.test
+++ b/mysql-test/t/grant2.test
@@ -452,7 +452,8 @@ connect (con1,localhost,mysqltest_1,password,TESTDB);
 
 # The user mysqltest_1 should only be allowed access to
 # database TESTDB, not TEStdb
---error 1044
+# On system with "lowercase names" we get error "1007: Can't create db..."
+--error 1044, 1007
 create database TEStdb;
 
 # Clean-up

From 6ea2c3cd57e5be58bb84b94951b34dc055b178a6 Mon Sep 17 00:00:00 2001
From: unknown <ramil@mysql.com>
Date: Thu, 2 Mar 2006 15:05:55 +0400
Subject: [PATCH 096/103] Fix for bug #17615: invalid handling of function
 results in UPDATE...SET statement.

sql/item_func.cc:
  Fix for bug #17615: invalid handling of function results in UPDATE...SET statement.
  - set proper collation
---
 mysql-test/r/sp.result | 14 ++++++++++++++
 mysql-test/t/sp.test   | 23 +++++++++++++++++++++++
 sql/item_func.cc       |  2 ++
 3 files changed, 39 insertions(+)

diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index a4c920f8e15..0f874cd1ceb 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4768,4 +4768,18 @@ Handler
 Inner
 drop procedure bug15011|
 drop table t3|
+drop function if exists bug17615|
+create table t3 (a varchar(256) unicode)|
+create function bug17615() returns varchar(256) unicode
+begin
+declare tmp_res varchar(256) unicode;
+set tmp_res= 'foo string';
+return tmp_res;
+end|
+insert into t3 values(bug17615())|
+select * from t3|
+a
+foo string
+drop function bug17615|
+drop table t3|
 drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 243c1b413b7..fd79286dd0f 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -5615,6 +5615,29 @@ drop procedure bug15011|
 drop table t3|
 
 
+#
+# BUG#17615: problem with character set
+#
+--disable_warnings
+drop function if exists bug17615|
+--enable_warnings
+
+create table t3 (a varchar(256) unicode)|
+
+create function bug17615() returns varchar(256) unicode
+begin
+  declare tmp_res varchar(256) unicode;
+  set tmp_res= 'foo string';
+  return tmp_res;
+end|
+
+insert into t3 values(bug17615())|
+select * from t3|
+
+drop function bug17615|
+drop table t3|
+
+
 #
 # BUG#NNNN: New bug synopsis
 #
diff --git a/sql/item_func.cc b/sql/item_func.cc
index a85f05c2e22..ccfb71e9d0c 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4881,6 +4881,7 @@ Item_func_sp::fix_length_and_dec()
   {
     decimals= result_field->decimals();
     max_length= result_field->field_length;
+    collation.set(result_field->charset());
     DBUG_VOID_RETURN;
   }
 
@@ -4891,6 +4892,7 @@ Item_func_sp::fix_length_and_dec()
   }
   decimals= field->decimals();
   max_length= field->field_length;
+  collation.set(field->charset());
   maybe_null= 1;
   delete field;
   DBUG_VOID_RETURN;

From 2ec1d015a94b1ab7c559421db2e43fc2d2ac25e6 Mon Sep 17 00:00:00 2001
From: unknown <bpontz@mysql.com>
Date: Thu, 2 Mar 2006 12:24:07 +0100
Subject: [PATCH 097/103] configure.in:   cloned

configure.in:
  cloned
---
 configure.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.in b/configure.in
index 7a571da7d77..4e630de13d2 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
 AC_CANONICAL_SYSTEM
 # The Docs Makefile.am parses this line!
 # remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.19)
+AM_INIT_AUTOMAKE(mysql, 5.0.20)
 AM_CONFIG_HEADER(config.h)
 
 PROTOCOL_VERSION=10
@@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
 # ndb version
 NDB_VERSION_MAJOR=5
 NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=19
+NDB_VERSION_BUILD=20
 NDB_VERSION_STATUS=""
 
 # Set all version vars based on $VERSION. How do we do this more elegant ?

From 7865ce6188cd45dfc9b5d074912a78ce6683a55e Mon Sep 17 00:00:00 2001
From: unknown <pem@mysql.com>
Date: Thu, 2 Mar 2006 14:54:04 +0100
Subject: [PATCH 098/103] Fixed BUG#17476: Stored procedure not returning data
 when it is called first                  time per connection   Removed
 const_string() method from Item_string (it was only used in one   place, in a
 bad way). Defer possible SP variable, and access data directly   instead, in
 date_format item.

mysql-test/r/sp.result:
  Updated results for new test (BUG#17476).
mysql-test/t/sp.test:
  New test case (BUG#17476)
sql/item.h:
  Removed const_string() from Item_string.
  It was only used in one place, and we can just use str_value in Item directly.
sql/item_timefunc.cc:
  Must defer a (possible) local SP variable to use max_length and str_value
  in Item_func_date_format::fix_length_and_dec(), and refer to str_value
  directly without the const_string() method (now removed); the cast didn't
  work in all cases anyway.
---
 mysql-test/r/sp.result | 19 +++++++++++++++++++
 mysql-test/t/sp.test   | 25 +++++++++++++++++++++++++
 sql/item.h             |  1 -
 sql/item_timefunc.cc   | 13 ++++++++++---
 4 files changed, 54 insertions(+), 4 deletions(-)

diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index a4c920f8e15..0029c79450b 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4768,4 +4768,23 @@ Handler
 Inner
 drop procedure bug15011|
 drop table t3|
+drop procedure if exists bug17476|
+create table t3 ( d date )|
+insert into t3 values
+( '2005-01-01' ), ( '2005-01-02' ), ( '2005-01-03' ),
+( '2005-01-04' ), ( '2005-02-01' ), ( '2005-02-02' )|
+create procedure bug17476(pDateFormat varchar(10))
+select date_format(t3.d, pDateFormat), count(*)
+from t3 
+group by date_format(t3.d, pDateFormat)|
+call bug17476('%Y-%m')|
+date_format(t3.d, pDateFormat)	count(*)
+2005-01	4
+2005-02	2
+call bug17476('%Y-%m')|
+date_format(t3.d, pDateFormat)	count(*)
+2005-01	4
+2005-02	2
+drop table t3|
+drop procedure bug17476|
 drop table t1,t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 243c1b413b7..12c1aebb265 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -5615,6 +5615,31 @@ drop procedure bug15011|
 drop table t3|
 
 
+#
+# BUG#17476: Stored procedure not returning data when it is called first
+#            time per connection
+#
+--disable_warnings
+drop procedure if exists bug17476|
+--enable_warnings
+
+create table t3 ( d date )|
+insert into t3 values
+  ( '2005-01-01' ), ( '2005-01-02' ), ( '2005-01-03' ),
+  ( '2005-01-04' ), ( '2005-02-01' ), ( '2005-02-02' )|
+
+create procedure bug17476(pDateFormat varchar(10))
+  select date_format(t3.d, pDateFormat), count(*)
+    from t3 
+    group by date_format(t3.d, pDateFormat)|
+
+call bug17476('%Y-%m')|
+call bug17476('%Y-%m')|
+
+drop table t3|
+drop procedure bug17476|
+
+
 #
 # BUG#NNNN: New bug synopsis
 #
diff --git a/sql/item.h b/sql/item.h
index a859b067632..2e3e0acc408 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -1585,7 +1585,6 @@ public:
     			   str_value.length(), collation.collation);
   }
   Item *safe_charset_converter(CHARSET_INFO *tocs);
-  String *const_string() { return &str_value; }
   inline void append(char *str, uint length) { str_value.append(str, length); }
   void print(String *str);
   // to prevent drop fixed flag (no need parent cleanup call)
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 17f25b49bcc..63a7f1f130b 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -1605,9 +1605,15 @@ longlong Item_func_sec_to_time::val_int()
 
 void Item_func_date_format::fix_length_and_dec()
 {
+  /*
+    Must use this_item() in case it's a local SP variable
+    (for ->max_length and ->str_value)
+  */
+  Item *arg1= args[1]->this_item();
+
   decimals=0;
   collation.set(&my_charset_bin);
-  if (args[1]->type() == STRING_ITEM)
+  if (arg1->type() == STRING_ITEM)
   {						// Optimize the normal case
     fixed_length=1;
 
@@ -1615,13 +1621,13 @@ void Item_func_date_format::fix_length_and_dec()
       The result is a binary string (no reason to use collation->mbmaxlen
       This is becasue make_date_time() only returns binary strings
     */
-    max_length= format_length(((Item_string*) args[1])->const_string());
+    max_length= format_length(&arg1->str_value);
   }
   else
   {
     fixed_length=0;
     /* The result is a binary string (no reason to use collation->mbmaxlen */
-    max_length=min(args[1]->max_length,MAX_BLOB_WIDTH) * 10;
+    max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10;
     set_if_smaller(max_length,MAX_BLOB_WIDTH);
   }
   maybe_null=1;					// If wrong date
@@ -1631,6 +1637,7 @@ void Item_func_date_format::fix_length_and_dec()
 bool Item_func_date_format::eq(const Item *item, bool binary_cmp) const
 {
   Item_func_date_format *item_func;
+
   if (item->type() != FUNC_ITEM)
     return 0;
   if (func_name() != ((Item_func*) item)->func_name())

From e2ba74b8252586bd27ace8603aab33c76b2b50cd Mon Sep 17 00:00:00 2001
From: unknown <cmiller@zippy.(none)>
Date: Thu, 2 Mar 2006 19:59:49 -0500
Subject: [PATCH 099/103] Expanding a binary field should result in 0x00-filled
 positions, not 0x20 (ASCII space).  For Bug#16857.

sql/field_conv.cc:
  Bug#16857:  Do not expand BINARY fields as if they are strings (which
  presumably /should/ be filled with spaces).  Instead, fill BINARY fields
  with 0x00 bytes.
---
 mysql-test/r/binary.result | 19 +++++++++++++++++++
 mysql-test/t/binary.test   | 12 ++++++++++++
 sql/field_conv.cc          | 18 +++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index a8d6c3bf411..c5673d1c00d 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -141,3 +141,22 @@ t1	CREATE TABLE `t1` (
   `a` binary(1) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+create table t1 (col1 binary(4));
+insert into t1 values ('a'),('a ');
+select hex(col1) from t1;
+hex(col1)
+61000000
+61200000
+alter table t1 modify col1 binary(10);
+select hex(col1) from t1;
+hex(col1)
+61000000000000000000
+61200000000000000000
+insert into t1 values ('b'),('b ');
+select hex(col1) from t1;
+hex(col1)
+61000000000000000000
+61200000000000000000
+62000000000000000000
+62200000000000000000
+drop table t1;
diff --git a/mysql-test/t/binary.test b/mysql-test/t/binary.test
index 1ac0cfebb28..4ab6ee9eaf1 100644
--- a/mysql-test/t/binary.test
+++ b/mysql-test/t/binary.test
@@ -89,3 +89,15 @@ show create table t1;
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug#16857
+#
+create table t1 (col1 binary(4));
+insert into t1 values ('a'),('a ');
+select hex(col1) from t1;
+alter table t1 modify col1 binary(10);
+select hex(col1) from t1;
+insert into t1 values ('b'),('b ');
+select hex(col1) from t1;
+drop table t1;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index bbe2dbe5e9f..895f022624c 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -379,6 +379,16 @@ static void do_cut_string_complex(Copy_field *copy)
 
 
 
+static void do_expand_binary(Copy_field *copy)
+{
+  CHARSET_INFO *cs= copy->from_field->charset();
+  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
+  cs->cset->fill(cs, copy->to_ptr+copy->from_length,
+                     copy->to_length-copy->from_length, '\0');
+}
+
+
+
 static void do_expand_string(Copy_field *copy)
 {
   CHARSET_INFO *cs= copy->from_field->charset();
@@ -583,7 +593,13 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
 	return (from->charset()->mbmaxlen == 1 ?
                 do_cut_string : do_cut_string_complex);
       else if (to_length > from_length)
-	return do_expand_string;
+      {
+        if ((to->flags & BINARY_FLAG) != 0)
+          return do_expand_binary;
+        else
+          return do_expand_string;
+      }
+
     }
     else if (to->real_type() != from->real_type() ||
 	     to_length != from_length ||

From a74939e2401a2af905292ecacbcae31997509123 Mon Sep 17 00:00:00 2001
From: unknown <kent@mysql.com>
Date: Fri, 3 Mar 2006 02:46:47 +0100
Subject: [PATCH 100/103] Makefile.am:   Use libtool convenience lib, to access
 get_password object correctly, bug#17155

server-tools/instance-manager/Makefile.am:
  Use libtool convenience lib, to access get_password object correctly, bug#17155
---
 server-tools/instance-manager/Makefile.am | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/server-tools/instance-manager/Makefile.am b/server-tools/instance-manager/Makefile.am
index 5b9690322aa..218eceebd12 100644
--- a/server-tools/instance-manager/Makefile.am
+++ b/server-tools/instance-manager/Makefile.am
@@ -24,9 +24,10 @@ DEFS= -DMYSQL_INSTANCE_MANAGER -DMYSQL_SERVER
 # default_options.h, generated from default_options.h.in)
 # See automake/autoconf docs for details
 
-noinst_LIBRARIES= liboptions.a libnet.a
+noinst_LTLIBRARIES= liboptions.la
+noinst_LIBRARIES=   libnet.a
 
-liboptions_a_CXXFLAGS= $(CXXFLAGS) \
+liboptions_la_CXXFLAGS= $(CXXFLAGS) \
 	-DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
 	-DDEFAULT_LOG_FILE_NAME="$(localstatedir)/mysqlmanager.log" \
 	-DDEFAULT_SOCKET_FILE_NAME="/tmp/mysqlmanager.sock" \
@@ -35,8 +36,8 @@ liboptions_a_CXXFLAGS= $(CXXFLAGS) \
 	-DDEFAULT_CONFIG_FILE="/etc/my.cnf" \
 	-DPROTOCOL_VERSION=@PROTOCOL_VERSION@
 
-liboptions_a_SOURCES= options.h options.cc priv.h priv.cc
-liboptions_a_LIBADD= $(top_builddir)/libmysql/get_password.$(OBJEXT)
+liboptions_la_SOURCES= options.h options.cc priv.h priv.cc
+liboptions_la_LIBADD= $(top_builddir)/libmysql/get_password.lo
 
 # MySQL sometimes uses symlinks to reuse code 
 # All symlinked files are grouped in libnet.a
@@ -77,7 +78,7 @@ mysqlmanager_SOURCES=	command.cc command.h mysqlmanager.cc \
                         mysql_manager_error.h \
                         portability.h
 
-mysqlmanager_LDADD=	liboptions.a \
+mysqlmanager_LDADD=	liboptions.la \
 			libnet.a \
 			$(top_builddir)/vio/libvio.a \
 			$(top_builddir)/mysys/libmysys.a \

From 25b3bb8bd711f0d2127f38a50c68dcc292064f82 Mon Sep 17 00:00:00 2001
From: unknown <cmiller@zippy.(none)>
Date: Thu, 2 Mar 2006 20:49:10 -0500
Subject: [PATCH 101/103] Expanding a binary field should result in 0x00-filled
 positions, not 0x20 (ASCII space).  For Bug#16857.

sql/field_conv.cc:
  Bug#16857:  Do not expand BINARY fields as if they are strings (which
  presumably /should/ be filled with spaces).  Instead, fill BINARY fields
  with 0x00 bytes.
---
 mysql-test/r/binary.result | 19 +++++++++++++++++++
 mysql-test/t/binary.test   | 12 ++++++++++++
 sql/field_conv.cc          | 18 +++++++++++++++++-
 3 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/mysql-test/r/binary.result b/mysql-test/r/binary.result
index a8d6c3bf411..c5673d1c00d 100644
--- a/mysql-test/r/binary.result
+++ b/mysql-test/r/binary.result
@@ -141,3 +141,22 @@ t1	CREATE TABLE `t1` (
   `a` binary(1) default NULL
 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
 drop table t1;
+create table t1 (col1 binary(4));
+insert into t1 values ('a'),('a ');
+select hex(col1) from t1;
+hex(col1)
+61000000
+61200000
+alter table t1 modify col1 binary(10);
+select hex(col1) from t1;
+hex(col1)
+61000000000000000000
+61200000000000000000
+insert into t1 values ('b'),('b ');
+select hex(col1) from t1;
+hex(col1)
+61000000000000000000
+61200000000000000000
+62000000000000000000
+62200000000000000000
+drop table t1;
diff --git a/mysql-test/t/binary.test b/mysql-test/t/binary.test
index 1ac0cfebb28..4ab6ee9eaf1 100644
--- a/mysql-test/t/binary.test
+++ b/mysql-test/t/binary.test
@@ -89,3 +89,15 @@ show create table t1;
 drop table t1;
 
 # End of 4.1 tests
+
+#
+# Bug#16857
+#
+create table t1 (col1 binary(4));
+insert into t1 values ('a'),('a ');
+select hex(col1) from t1;
+alter table t1 modify col1 binary(10);
+select hex(col1) from t1;
+insert into t1 values ('b'),('b ');
+select hex(col1) from t1;
+drop table t1;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index bbe2dbe5e9f..895f022624c 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -379,6 +379,16 @@ static void do_cut_string_complex(Copy_field *copy)
 
 
 
+static void do_expand_binary(Copy_field *copy)
+{
+  CHARSET_INFO *cs= copy->from_field->charset();
+  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
+  cs->cset->fill(cs, copy->to_ptr+copy->from_length,
+                     copy->to_length-copy->from_length, '\0');
+}
+
+
+
 static void do_expand_string(Copy_field *copy)
 {
   CHARSET_INFO *cs= copy->from_field->charset();
@@ -583,7 +593,13 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
 	return (from->charset()->mbmaxlen == 1 ?
                 do_cut_string : do_cut_string_complex);
       else if (to_length > from_length)
-	return do_expand_string;
+      {
+        if ((to->flags & BINARY_FLAG) != 0)
+          return do_expand_binary;
+        else
+          return do_expand_string;
+      }
+
     }
     else if (to->real_type() != from->real_type() ||
 	     to_length != from_length ||

From a91d0afdaa79b8e78571796079b8910dd8380fda Mon Sep 17 00:00:00 2001
From: unknown <kent@mysql.com>
Date: Fri, 3 Mar 2006 03:27:27 +0100
Subject: [PATCH 102/103] mysql.spec.sh:   Don't create empty embedded RPM,
 bug#15769

support-files/mysql.spec.sh:
  Don't create empty embedded RPM, bug#15769
---
 support-files/mysql.spec.sh | 44 ++++++++++++++++++++-----------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 613045e6ad5..599f397e351 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -204,24 +204,24 @@ the standard MySQL package.
 
 Please note that this is a dynamically linked binary!
 
-%package embedded
-Requires: %{name}-devel
-Summary: MySQL - embedded library
-Group: Applications/Databases
-Obsoletes: mysql-embedded
-
-%description embedded
-This package contains the MySQL server as an embedded library.
-
-The embedded MySQL server library makes it possible to run a
-full-featured MySQL server inside the client application.
-The main benefits are increased speed and more simple management
-for embedded applications.
-
-The API is identical for the embedded MySQL version and the
-client/server version.
-
-%{see_base}
+#%package embedded
+#Requires: %{name}-devel
+#Summary: MySQL - embedded library
+#Group: Applications/Databases
+#Obsoletes: mysql-embedded
+#
+#%description embedded
+#This package contains the MySQL server as an embedded library.
+#
+#The embedded MySQL server library makes it possible to run a
+#full-featured MySQL server inside the client application.
+#The main benefits are increased speed and more simple management
+#for embedded applications.
+#
+#The API is identical for the embedded MySQL version and the
+#client/server version.
+#
+#%{see_base}
 
 %prep
 %setup -n mysql-%{mysql_version}
@@ -712,14 +712,18 @@ fi
 %attr(755, root, root) %{_sbindir}/mysqld-max
 %attr(644, root, root) %{_libdir}/mysql/mysqld-max.sym
 
-%files embedded
-%defattr(-, root, root, 0755)
+#%files embedded
+#%defattr(-, root, root, 0755)
 # %attr(644, root, root) %{_libdir}/mysql/libmysqld.a
 
 # The spec file changelog only includes changes made to the spec file
 # itself - note that they must be ordered by date (important when
 # merging BK trees)
 %changelog 
+* Fri Mar 03 2006 Kent Boortz <kent@mysql.com>
+
+- Don't output an embedded package as it is empty
+
 * Fri Jan 10 2006 Joerg Bruehe <joerg@mysql.com>
 
 - Use "-i" on "make test-force";

From 500d6b851ca426ebbea8a36c7a24aa46beda1bab Mon Sep 17 00:00:00 2001
From: unknown <gluh@eagle.intranet.mysql.r18.ru>
Date: Fri, 3 Mar 2006 15:29:39 +0400
Subject: [PATCH 103/103] Fix for bug#17826 'type_decimal' fails with
 ps-protocol  removed unnecessary calculation of cache value  otherwise
 Join::preapre tries to calculate  undefined values(filed values)

mysql-test/r/type_decimal.result:
  Fix for bug#17826 'type_decimal' fails with ps-protocol
   test case, this test case reproduce the same bug but without PS protocol
mysql-test/t/type_decimal.test:
  Fix for bug#17826 'type_decimal' fails with ps-protocol
   test case, this test case reproduce the same bug but without PS protocol
---
 mysql-test/r/type_decimal.result | 7 +++++++
 mysql-test/t/type_decimal.test   | 8 ++++++++
 sql/item_cmpfunc.cc              | 6 ------
 3 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/mysql-test/r/type_decimal.result b/mysql-test/r/type_decimal.result
index d7f5f9fa328..8b2c08065e0 100644
--- a/mysql-test/r/type_decimal.result
+++ b/mysql-test/r/type_decimal.result
@@ -772,3 +772,10 @@ productid	zlevelprice
 003trans	39.98
 004trans	31.18
 drop table t1, t2;
+create table t1 (f1 decimal(5));
+insert into t1 values (40);
+flush tables;
+select f1 from t1 where f1 in (select f1 from t1);
+f1
+40
+drop table t1;
diff --git a/mysql-test/t/type_decimal.test b/mysql-test/t/type_decimal.test
index 07347322453..441d750004e 100644
--- a/mysql-test/t/type_decimal.test
+++ b/mysql-test/t/type_decimal.test
@@ -377,3 +377,11 @@ insert INTO t2 SELECT * FROM t1;
 select * from t2; 
 drop table t1, t2;
 
+#
+# Bug #17826 'type_decimal' fails with ps-protocol
+#
+create table t1 (f1 decimal(5));
+insert into t1 values (40);
+flush tables;
+select f1 from t1 where f1 in (select f1 from t1);
+drop table t1;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 7ba8a536ac7..304e9e8babe 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -698,12 +698,6 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref)
     return 1;
 
   cache->setup(args[0]);
-  /*
-    If it is preparation PS only then we do not know values of parameters =>
-    cant't get there values and do not need that values.
-  */
-  if (!thd->stmt_arena->is_stmt_prepare())
-    cache->store(args[0]);
   if (cache->cols() == 1)
   {
     if ((used_tables_cache= args[0]->used_tables()))