From d649efbb07af288b6b58b4bd01a04d34c7a7f467 Mon Sep 17 00:00:00 2001
From: unknown <igor@rurik.mysql.com>
Date: Thu, 19 Oct 2006 23:05:53 -0700
Subject: [PATCH 01/18] Fixed bug #23478. If elements a not top-level IN
 subquery were accessed by an index and the subquery result set included  a
 NULL value then the quantified predicate that contained the subquery was
 evaluated to NULL when it should return a non-null value.

mysql-test/r/subselect.result:
  Added a test case for bug #23478.
mysql-test/t/subselect.test:
  Added a test case for bug #23478.
---
 mysql-test/r/subselect.result | 15 +++++++++++++++
 mysql-test/t/subselect.test   | 17 +++++++++++++++++
 sql/item_subselect.cc         |  3 +++
 3 files changed, 35 insertions(+)

diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index ad847b5f156..28fbfc86657 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2982,3 +2982,18 @@ field1	field2
 1	1
 1	3
 DROP TABLE t1, t2;
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	t2	ALL	NULL	NULL	NULL	NULL	3	
+2	DEPENDENT SUBQUERY	t1	index_subquery	a	a	5	func	2	Using index
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+a	a IN (SELECT a FROM t1)
+1	1
+2	NULL
+3	1
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 6defa8b16a5..ac035c72d18 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1948,4 +1948,21 @@ SELECT field1, field2
 
 DROP TABLE t1, t2;
 
+#
+# Bug #23478: not top-level IN subquery returning a non-empty result set
+#             with possible NULL values by index access from the outer query
+#
+
+CREATE TABLE t1(a int, INDEX (a));
+INSERT INTO t1 VALUES (1), (3), (5), (7);
+INSERT INTO t1 VALUES (NULL);
+
+CREATE TABLE t2(a int);
+INSERT INTO t2 VALUES (1),(2),(3);
+
+EXPLAIN SELECT a, a IN (SELECT a FROM t1) FROM t2;
+SELECT a, a IN (SELECT a FROM t1) FROM t2;
+
+DROP TABLE t1,t2;
+
 # End of 4.1 tests
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index f3be0663af8..1ab81d1862d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -610,6 +610,7 @@ double Item_in_subselect::val()
   */
   DBUG_ASSERT(0);
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();
@@ -625,6 +626,7 @@ double Item_in_subselect::val()
 longlong Item_in_subselect::val_int()
 {
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();
@@ -645,6 +647,7 @@ String *Item_in_subselect::val_str(String *str)
   */
   DBUG_ASSERT(0);
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();

From 4ddb48c619c5fb703a846f5dd2659a4854a8c0d7 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Mon, 23 Oct 2006 15:02:51 +0500
Subject: [PATCH 02/18] WL#3475 (Threads for the embedded server in mysqltest)

Necessary code added to mysqltest.c.
Disabled tests are available now.


client/mysqltest.c:
  do_send_query function implemented, so now 'send' command will be
  run in separate thread for the embedded server.
  Mutex and condition added to the 'connection' struct for syncronisation
  purposes. Yes it'd be easier if we had pthread_join() command
libmysql/libmysql.c:
  this isn't actually needed and causes problems in embedded server
mysql-test/t/bdb-deadlock.test:
  test is available for the embedded server now
mysql-test/t/flush.test:
  test is available for the embedded server now
mysql-test/t/flush_block_commit.test:
  test is available for the embedded server now
mysql-test/t/innodb-deadlock.test:
  test is available for the embedded server now
mysql-test/t/innodb-lock.test:
  test is available for the embedded server now
mysql-test/t/lock_multi.test:
  test is available for the embedded server now
mysql-test/t/rename.test:
  test is available for the embedded server now
mysql-test/t/show_check.test:
  test is available for the embedded server now
mysql-test/t/status.test:
  test is available for the embedded server now
---
 client/mysqltest.c                   | 102 +++++++++++++++++++++++----
 libmysql/libmysql.c                  |   7 --
 mysql-test/t/bdb-deadlock.test       |   8 ---
 mysql-test/t/flush.test              |   8 ---
 mysql-test/t/flush_block_commit.test |   3 -
 mysql-test/t/innodb-deadlock.test    |   2 -
 mysql-test/t/innodb-lock.test        |   2 -
 mysql-test/t/lock_multi.test         |   8 ---
 mysql-test/t/rename.test             |   4 --
 mysql-test/t/show_check.test         |   3 +-
 mysql-test/t/status.test             |   7 --
 11 files changed, 90 insertions(+), 64 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index ad0f9f857bb..6889ae1a84c 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -23,6 +23,7 @@
  *   Matt Wagner  <matt@mysql.com>
  *   Monty
  *   Jani
+ *   Holyfoot
  **/
 
 /**********************************************************************
@@ -215,6 +216,12 @@ struct connection
 {
   MYSQL mysql;
   char *name;
+
+  const char *cur_query;
+  int cur_query_len;
+  pthread_mutex_t mutex;
+  pthread_cond_t cond;
+  int query_done;
 };
 
 typedef struct
@@ -461,6 +468,57 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
 				      int len);
 static int handle_no_error(struct st_query *q);
 
+#ifdef EMBEDDED_LIBRARY
+/*
+  send_one_query executes query in separate thread what is
+  necessary in embedded library to run 'send' in proper way.
+  This implementation doesn't handle errors returned
+  by mysql_send_query. It's technically possible, though
+  i don't see where it is needed.
+*/
+pthread_handler_decl(send_one_query, arg)
+{
+  struct connection *cn= (struct connection*)arg;
+
+  mysql_thread_init();
+  VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
+
+  mysql_thread_end();
+  pthread_mutex_lock(&cn->mutex);
+  cn->query_done= 1;
+  VOID(pthread_cond_signal(&cn->cond));
+  pthread_mutex_unlock(&cn->mutex);
+  pthread_exit(0);
+  return 0;
+}
+
+static int do_send_query(struct connection *cn, const char *q, int q_len,
+                         int flags)
+{
+  pthread_t tid;
+
+  if (flags & QUERY_REAP)
+    return mysql_send_query(&cn->mysql, q, q_len);
+
+  if (pthread_mutex_init(&cn->mutex, NULL) ||
+      pthread_cond_init(&cn->cond, NULL))
+    die("Error in the thread library");
+
+  cn->cur_query= q;
+  cn->cur_query_len= q_len;
+  cn->query_done= 0;
+  if (pthread_create(&tid, NULL, send_one_query, (void*)cn))
+    die("Cannot start new thread for query");
+
+  return 0;
+}
+
+#else /*EMBEDDED_LIBRARY*/
+
+#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
+
+#endif /*EMBEDDED_LIBRARY*/
+
 static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
 {
   const char *p;
@@ -1849,7 +1907,7 @@ int close_connection(struct st_query *q)
 #ifndef EMBEDDED_LIBRARY
       if (q->type == Q_DIRTY_CLOSE)
       {
-	if (con->mysql.net.vio)
+	while (con->mysql.net.vio)
 	{
 	  vio_delete(con->mysql.net.vio);
 	  con->mysql.net.vio = 0;
@@ -2767,15 +2825,17 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
 * the result will be read - for regular query, both bits must be on
 */
 
-static int run_query_normal(MYSQL *mysql, struct st_query *q, int flags);
-static int run_query_stmt  (MYSQL *mysql, struct st_query *q, int flags);
+static int run_query_normal(struct connection *cn, struct st_query *q,
+                            int flags);
+static int run_query_stmt  (struct connection *cn, struct st_query *q,
+                            int flags);
 static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds);
 static int run_query_stmt_handle_error(char *query, struct st_query *q,
                                        MYSQL_STMT *stmt, DYNAMIC_STRING *ds);
 static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields,
                                        DYNAMIC_STRING *ds);
 
-static int run_query(MYSQL *mysql, struct st_query *q, int flags)
+static int run_query(struct connection *cn, struct st_query *q, int flags)
 {
 
   /*
@@ -2791,13 +2851,15 @@ static int run_query(MYSQL *mysql, struct st_query *q, int flags)
 
   if (ps_protocol_enabled && disable_info &&
       (flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query))
-    return run_query_stmt(mysql, q, flags);
-  return run_query_normal(mysql, q, flags);
+    return run_query_stmt(cn, q, flags);
+  return run_query_normal(cn, q, flags);
 }
 
 
-static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
+static int run_query_normal(struct connection *cn, struct st_query* q,
+                            int flags)
 {
+  MYSQL *mysql= &cn->mysql;
   MYSQL_RES* res= 0;
   uint i;
   int error= 0, err= 0, counter= 0;
@@ -2833,11 +2895,24 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
 
   if (flags & QUERY_SEND)
   {
-    got_error_on_send= mysql_send_query(mysql, query, query_len);
+    got_error_on_send= do_send_query(cn, query, query_len, flags);
     if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY)
       die("unable to send query '%s' (mysql_errno=%d , errno=%d)",
 	  query, mysql_errno(mysql), errno);
   }
+#ifdef EMBEDDED_LIBRARY
+  /*
+   Here we handle 'reap' command, so we need to check if the
+   query's thread was finished and probably wait
+  */
+  else if (flags & QUERY_REAP)
+  {
+    pthread_mutex_lock(&cn->mutex);
+    if (!cn->query_done)
+      pthread_cond_wait(&cn->cond, &cn->mutex);
+    pthread_mutex_unlock(&cn->mutex);
+  }
+#endif /*EMBEDDED_LIBRARY*/
 
   do
   {
@@ -3038,8 +3113,9 @@ end:
   complete SEND+REAP
 */
 
-static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
+static int run_query_stmt(struct connection *cn, struct st_query *q, int flags)
 {
+  MYSQL *mysql= &cn->mysql;
   int error= 0;             /* Function return code if "goto end;" */
   int err;                  /* Temporary storage of return code from calls */
   int query_len, got_error_on_execute;
@@ -3095,7 +3171,7 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
     C API.
   */
   if ((err= mysql_stmt_prepare(stmt, query, query_len)) == CR_NO_PREPARE_STMT)
-    return run_query_normal(mysql, q, flags);
+    return run_query_normal(cn, q, flags);
 
   if (err != 0)
   {
@@ -3922,7 +3998,7 @@ int main(int argc, char **argv)
 	  q->require_file=require_file;
 	  save_file[0]=0;
 	}
-	error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND);
+	error|= run_query(cur_con, q, QUERY_REAP|QUERY_SEND);
 	display_result_vertically= old_display_result_vertically;
         q->last_argument= q->end;
         query_executed= 1;
@@ -3949,7 +4025,7 @@ int main(int argc, char **argv)
 	  q->require_file=require_file;
 	  save_file[0]=0;
 	}
-	error |= run_query(&cur_con->mysql, q, flags);
+	error |= run_query(cur_con, q, flags);
 	query_executed= 1;
         q->last_argument= q->end;
 	break;
@@ -3970,7 +4046,7 @@ int main(int argc, char **argv)
 	  query and read the result some time later when reap instruction
 	  is given on this connection.
 	 */
-	error |= run_query(&cur_con->mysql, q, QUERY_SEND);
+	error |= run_query(cur_con, q, QUERY_SEND);
 	query_executed= 1;
         q->last_argument= q->end;
 	break;
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 91c0b6b8864..5577ecdb556 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -4395,13 +4395,6 @@ int STDCALL mysql_stmt_store_result(MYSQL_STMT *stmt)
     set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate);
     DBUG_RETURN(1);
   }
-  if (result->data)
-  {
-    free_root(&result->alloc, MYF(MY_KEEP_PREALLOC));
-    result->data= NULL;
-    result->rows= 0;
-    stmt->data_cursor= NULL;
-  }
 
   if (stmt->update_max_length && !stmt->bind_result_done)
   {
diff --git a/mysql-test/t/bdb-deadlock.test b/mysql-test/t/bdb-deadlock.test
index 88243cfc860..b48648e0fd0 100644
--- a/mysql-test/t/bdb-deadlock.test
+++ b/mysql-test/t/bdb-deadlock.test
@@ -1,11 +1,3 @@
-# This test doesn't work with the embedded version as this code
-# assumes that one query is running while we are doing queries on
-# a second connection.
-# This would work if mysqltest run would be threaded and handle each
-# connection in a separate thread.
-#
-
--- source include/not_embedded.inc
 -- source include/have_bdb.inc
 
 connect (con1,localhost,root,,);
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index aedf8e85b65..8fe62ecac01 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -1,11 +1,3 @@
-# This test doesn't work with the embedded version as this code
-# assumes that one query is running while we are doing queries on
-# a second connection.
-# This would work if mysqltest run would be threaded and handle each
-# connection in a separate thread.
-#
--- source include/not_embedded.inc
-
 connect (con1,localhost,root,,);
 connect (con2,localhost,root,,);
 connection con1;
diff --git a/mysql-test/t/flush_block_commit.test b/mysql-test/t/flush_block_commit.test
index 1e7ecd2548c..0c1d2b82df6 100644
--- a/mysql-test/t/flush_block_commit.test
+++ b/mysql-test/t/flush_block_commit.test
@@ -3,9 +3,6 @@
 # We verify that we did not introduce a deadlock.
 # This is intended to mimick how mysqldump and innobackup work.
 
-# This test doesn't work with the embedded server
--- source include/not_embedded.inc
-
 # And it requires InnoDB
 -- source include/have_innodb.inc
 
diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test
index 41741942963..81acfba5c93 100644
--- a/mysql-test/t/innodb-deadlock.test
+++ b/mysql-test/t/innodb-deadlock.test
@@ -1,6 +1,4 @@
 -- source include/have_innodb.inc
-# Can't test this with embedded server
--- source include/not_embedded.inc
 
 connect (con1,localhost,root,,);
 connect (con2,localhost,root,,);
diff --git a/mysql-test/t/innodb-lock.test b/mysql-test/t/innodb-lock.test
index 55a712fef9b..eacf7e562be 100644
--- a/mysql-test/t/innodb-lock.test
+++ b/mysql-test/t/innodb-lock.test
@@ -1,6 +1,4 @@
 -- source include/have_innodb.inc
-# Can't test this with embedded server
--- source include/not_embedded.inc
 
 #
 # Check and select innodb lock type
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 2e40aeaccb7..32e7f4234c4 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -1,11 +1,3 @@
-# This test doesn't work with the embedded version as this code
-# assumes that one query is running while we are doing queries on
-# a second connection.
-# This would work if mysqltest run would be threaded and handle each
-# connection in a separate thread.
-#
--- source include/not_embedded.inc
-
 --disable_warnings
 drop table if exists t1,t2;
 --enable_warnings
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 5caecef176e..ad9921d2cf0 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -2,10 +2,6 @@
 # Test of rename table
 #
 
-# Test requires concurrent connections, which can't be tested on embedded
-# server
--- source include/not_embedded.inc
-
 --disable_warnings
 drop table if exists t0,t1,t2,t3,t4;
 # Clear up from other tests (to ensure that SHOW TABLES below is right)
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index d70903adbc4..8be676d9a35 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -1,5 +1,4 @@
-# Requires use of multiple simultaneous connections, not supported with
-# embedded server testing
+# Uses GRANT commands that usually disabled in embedded server
 -- source include/not_embedded.inc
 
 #
diff --git a/mysql-test/t/status.test b/mysql-test/t/status.test
index 7fea51c9327..df8da26df57 100644
--- a/mysql-test/t/status.test
+++ b/mysql-test/t/status.test
@@ -1,10 +1,3 @@
-# This test doesn't work with the embedded version as this code
-# assumes that one query is running while we are doing queries on
-# a second connection.
-# This would work if mysqltest run would be threaded and handle each
-# connection in a separate thread.
-#
---source include/not_embedded.inc
 # PS causes different statistics
 --disable_ps_protocol
 

From 7e2336925fa6dd1bab052f9b3bc5594f2d22f25b Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Tue, 24 Oct 2006 12:35:32 +0500
Subject: [PATCH 03/18] merging fix

client/mysqltest.c:
  wrong 'while' was added instead of 'if'
---
 client/mysqltest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index 6889ae1a84c..3294612f7cc 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -1907,7 +1907,7 @@ int close_connection(struct st_query *q)
 #ifndef EMBEDDED_LIBRARY
       if (q->type == Q_DIRTY_CLOSE)
       {
-	while (con->mysql.net.vio)
+	if (con->mysql.net.vio)
 	{
 	  vio_delete(con->mysql.net.vio);
 	  con->mysql.net.vio = 0;
@@ -2908,7 +2908,7 @@ static int run_query_normal(struct connection *cn, struct st_query* q,
   else if (flags & QUERY_REAP)
   {
     pthread_mutex_lock(&cn->mutex);
-    if (!cn->query_done)
+    while (!cn->query_done)
       pthread_cond_wait(&cn->cond, &cn->mutex);
     pthread_mutex_unlock(&cn->mutex);
   }

From 6c4aa883ce15b6b5193d34caf72025548da56175 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Tue, 24 Oct 2006 17:19:02 +0500
Subject: [PATCH 04/18] Bug #23427 (incompatible ABI change)

the incompatibility was caused by current_stmt member added to the MYSQL
structure.
It's possible to move it to THD structure instead which saves ABI


include/mysql.h:
  member moved to the THD structure
libmysqld/lib_sql.cc:
  now we use THD member here
sql/sql_class.h:
  current_stmt member added for the embedded server
---
 include/mysql.h      |  6 ------
 libmysqld/lib_sql.cc | 10 +++++-----
 sql/sql_class.h      |  6 ++++++
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/mysql.h b/include/mysql.h
index 143f6752c46..89e861864df 100644
--- a/include/mysql.h
+++ b/include/mysql.h
@@ -270,12 +270,6 @@ typedef struct st_mysql
     from mysql_stmt_close if close had to cancel result set of this object.
   */
   my_bool *unbuffered_fetch_owner;
-  /*
-    In embedded server it points to the statement that is processed
-    in the current query. We store some results directly in statement
-    fields then.
-  */
-  struct st_mysql_stmt *current_stmt;
 } MYSQL;
 
 typedef struct st_mysql_res {
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 1a3e10f08a8..64bc37fb40d 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -94,7 +94,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
   mysql->affected_rows= ~(my_ulonglong) 0;
   mysql->field_count= 0;
   net->last_errno= 0;
-  mysql->current_stmt= stmt;
+  thd->current_stmt= stmt;
 
   thd->store_globals();				// Fix if more than one connect
   /* 
@@ -644,8 +644,8 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
     DBUG_RETURN(0);
 
   field_count= list->elements;
-  field_alloc= mysql->current_stmt ? &mysql->current_stmt->mem_root :
-                                     &mysql->field_alloc;
+  field_alloc= thd->current_stmt ? &thd->current_stmt->mem_root :
+                                   &mysql->field_alloc;
   if (!(client_field= mysql->fields= 
 	(MYSQL_FIELD *)alloc_root(field_alloc, 
 				  sizeof(MYSQL_FIELD) * field_count)))
@@ -751,8 +751,8 @@ bool Protocol_prep::write()
   {
     MYSQL *mysql= thd->mysql;
 
-    if (mysql->current_stmt)
-      data= &mysql->current_stmt->result;
+    if (thd->current_stmt)
+      data= &thd->current_stmt->result;
     else
     {
       if (!(data= (MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA),
diff --git a/sql/sql_class.h b/sql/sql_class.h
index cc90de2a6ea..ed161de55de 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -686,6 +686,12 @@ public:
   char *extra_data;
   ulong extra_length;
   String query_rest;
+  /*
+    In embedded server it points to the statement that is processed
+    in the current query. We store some results directly in statement
+    fields then.
+  */
+  struct st_mysql_stmt *current_stmt;
 #endif
   NET	  net;				// client connection descriptor
   MEM_ROOT warn_root;			// For warnings and errors

From c095f98ff7d18e2e5de1adf629147f2b199fbfaf Mon Sep 17 00:00:00 2001
From: unknown <gkodinov/kgeorge@macbook.gmz>
Date: Fri, 3 Nov 2006 18:48:16 +0200
Subject: [PATCH 05/18] Bug #22457: Column alias in ORDER BY works, but not if
 in an expression  The parser is allocating Item_field for references by name
 in ORDER BY  expressions. Such expressions however may point not only to
 Item_field  in the select list (or to a table column) but also to an
 arbitrary Item.  This causes Item_field::fix_fields to throw an error about
 missing  column.  The fix substitutes Item_field for the reference with an
 Item_ref when  not pointing to Item_field.

mysql-test/r/order_by.result:
  Bug #22457: Column alias in ORDER BY works, but not if in an expression
   - test case
mysql-test/t/order_by.test:
  Bug #22457: Column alias in ORDER BY works, but not if in an expression
   - test case
sql/item.cc:
  Bug #22457: Column alias in ORDER BY works, but not if in an expression
   - transform the Item_field made by the parser into Item_ref if it
     doesn't point to Item_field and it is in allowed context
---
 mysql-test/r/order_by.result | 27 +++++++++++++++++++++++++++
 mysql-test/t/order_by.test   | 16 ++++++++++++++++
 sql/item.cc                  | 33 ++++++++++++++++++++++++++++++---
 3 files changed, 73 insertions(+), 3 deletions(-)

diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result
index 8126e223f55..320bb89b62e 100644
--- a/mysql-test/r/order_by.result
+++ b/mysql-test/r/order_by.result
@@ -820,3 +820,30 @@ b	a
 20	1
 10	2
 DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1),(2);
+SELECT a + 1 AS num FROM t1 ORDER BY 30 - num;
+num
+3
+2
+SELECT CONCAT('test', a) AS str FROM t1 ORDER BY UPPER(str);
+str
+test1
+test2
+SELECT a + 1 AS num FROM t1 GROUP BY 30 - num;
+num
+3
+2
+SELECT a + 1 AS num FROM t1 HAVING 30 - num;
+num
+2
+3
+SELECT a + 1 AS num, num + 1 FROM t1;
+ERROR 42S22: Unknown column 'num' in 'field list'
+SELECT a + 1 AS num, (select num + 2 FROM t1 LIMIT 1) FROM t1;
+num	(select num + 2 FROM t1 LIMIT 1)
+2	4
+3	5
+SELECT a.a + 1 AS num FROM t1 a JOIN t1 b ON num = b.a;
+ERROR 42S22: Unknown column 'num' in 'on clause'
+DROP TABLE t1;
diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test
index 1664afc70f9..a8024be7032 100644
--- a/mysql-test/t/order_by.test
+++ b/mysql-test/t/order_by.test
@@ -559,4 +559,20 @@ INSERT INTO t1 VALUES (1,30), (2,20), (1,10), (2,30), (1,20), (2,10);
 
 DROP TABLE t1;
 
+#
+# Bug #22457: Column alias in ORDER BY works, but not if in an expression
+#
+
+CREATE TABLE t1 (a INT); INSERT INTO t1 VALUES (1),(2);
+SELECT a + 1 AS num FROM t1 ORDER BY 30 - num;
+SELECT CONCAT('test', a) AS str FROM t1 ORDER BY UPPER(str);
+SELECT a + 1 AS num FROM t1 GROUP BY 30 - num;
+SELECT a + 1 AS num FROM t1 HAVING 30 - num;
+--error 1054
+SELECT a + 1 AS num, num + 1 FROM t1;
+SELECT a + 1 AS num, (select num + 2 FROM t1 LIMIT 1) FROM t1;
+--error 1054
+SELECT a.a + 1 AS num FROM t1 a JOIN t1 b ON num = b.a;
+DROP TABLE t1;
+
 # End of 4.1 tests
diff --git a/sql/item.cc b/sql/item.cc
index 94f0a24fcc3..45d7856b2c1 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1761,10 +1761,37 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
         Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
                                       &counter, REPORT_EXCEPT_NOT_FOUND,
                                       &not_used);
-        if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM)
+        if (res != (Item **)not_found_item)
         {
-          set_field((*((Item_field**)res))->field);
-          return 0;
+          if ((*res)->type() == Item::FIELD_ITEM)
+          {
+            /*
+             It's an Item_field referencing another Item_field in the select
+             list.
+             use the field from the Item_field in the select list and leave
+             the Item_field instance in place.
+            */
+            set_field((*((Item_field**)res))->field);
+            return 0;
+          }
+          else
+          {
+            /*
+              It's not an Item_field in the select list so we must make a new
+              Item_ref to point to the Item in the select list and replace the
+              Item_field created by the parser with the new Item_ref.
+            */
+            Item_ref *rf= new Item_ref(db_name,table_name,field_name);
+            if (!rf)
+              return 1;
+            thd->change_item_tree(ref, rf);
+            /*
+              Because Item_ref never substitutes itself with other items 
+              in Item_ref::fix_fields(), we can safely use the original 
+              pointer to it even after fix_fields()
+             */
+            return rf->fix_fields(thd, tables, ref) ||  rf->check_cols(1);
+          }
         }
       }
 

From 5af4fd256321748a5ac7c8d4407f8ce977345e04 Mon Sep 17 00:00:00 2001
From: unknown <gkodinov/kgeorge@macbook.gmz>
Date: Tue, 7 Nov 2006 18:16:17 +0200
Subject: [PATCH 06/18] Bug #11032: getObject() returns a String for a
 sub-query of type datetime  - When returning metadata for scalar subqueries
 the actual type of the    column was calculated based on the value type,
 which limits the actual    type of a scalar subselect to the set of
 (currently) 3 basic types :    integer, double precision or string. This is
 the reason that columns    of types other then the basic ones (e.g.
 date/time) are reported as    being of the corresponding basic type.    Fixed
 by storing/returning information for the column type in addition    to the
 result type.

mysql-test/r/subselect.result:
  Bug #11032: getObject() returns a String for a sub-query of type datetime
   - test case
mysql-test/t/subselect.test:
  Bug #11032: getObject() returns a String for a sub-query of type datetime
   - test case
sql/item_subselect.cc:
  Bug #11032: getObject() returns a String for a sub-query of type datetime
   - store and return the field type as well in addition to result type for
     single row subqueries
sql/item_subselect.h:
  Bug #11032: getObject() returns a String for a sub-query of type datetime
   - store and return the field type as well in addition to result type for
     single row subqueries
---
 mysql-test/r/subselect.result | 17 +++++++++++++++++
 mysql-test/t/subselect.test   | 16 ++++++++++++++++
 sql/item_subselect.cc         | 34 ++++++++++++++++++++++++----------
 sql/item_subselect.h          |  7 +++++++
 4 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 28fbfc86657..a3d1bafcb0d 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -2997,3 +2997,20 @@ a	a IN (SELECT a FROM t1)
 2	NULL
 3	1
 DROP TABLE t1,t2;
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+CREATE TABLE t2 AS SELECT 
+(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a 
+FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `sub_a` datetime default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01');
+SHOW CREATE TABLE t3;
+Table	Create Table
+t3	CREATE TABLE `t3` (
+  `a` datetime default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1,t2,t3;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index ac035c72d18..11b7fcc4d8f 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -1965,4 +1965,20 @@ SELECT a, a IN (SELECT a FROM t1) FROM t2;
 
 DROP TABLE t1,t2;
 
+#
+# Bug #11302: getObject() returns a String for a sub-query of type datetime
+#
+CREATE TABLE t1 (a DATETIME);
+INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
+
+CREATE TABLE t2 AS SELECT 
+  (SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a 
+   FROM t1 WHERE a > '2000-01-01';
+SHOW CREATE TABLE t2;
+
+CREATE TABLE t3 AS (SELECT a FROM t1 WHERE a < '2000-01-01') UNION (SELECT a FROM t1 WHERE a > '2000-01-01'); 
+SHOW CREATE TABLE t3;
+
+DROP TABLE t1,t2,t3;
+
 # End of 4.1 tests
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 1ab81d1862d..cd1f8f83821 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -391,6 +391,15 @@ enum Item_result Item_singlerow_subselect::result_type() const
   return engine->type();
 }
 
+/* 
+ Don't rely on the result type to calculate field type. 
+ Ask the engine instead.
+*/
+enum_field_types Item_singlerow_subselect::field_type() const
+{
+  return engine->field_type();
+}
+
 void Item_singlerow_subselect::fix_length_and_dec()
 {
   if ((max_columns= engine->cols()) == 1)
@@ -1357,31 +1366,35 @@ int subselect_uniquesubquery_engine::prepare()
   return 1;
 }
 
-static Item_result set_row(List<Item> &item_list, Item *item,
-			   Item_cache **row, bool *maybe_null)
+/* 
+ makes storage for the output values for the subquery and calcuates 
+ their data and column types and their nullability.
+*/ 
+void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
 {
-  Item_result res_type= STRING_RESULT;
   Item *sel_item;
   List_iterator_fast<Item> li(item_list);
+  res_type= STRING_RESULT;
+  res_field_type= FIELD_TYPE_VAR_STRING;
   for (uint i= 0; (sel_item= li++); i++)
   {
     item->max_length= sel_item->max_length;
     res_type= sel_item->result_type();
+    res_field_type= sel_item->field_type();
     item->decimals= sel_item->decimals;
-    *maybe_null= sel_item->maybe_null;
+    maybe_null= sel_item->maybe_null;
     if (!(row[i]= Item_cache::get_cache(res_type)))
-      return STRING_RESULT; // we should return something
+      return;
     row[i]->setup(sel_item);
   }
   if (item_list.elements > 1)
     res_type= ROW_RESULT;
-  return res_type;
 }
 
 void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
 {
   DBUG_ASSERT(row || select_lex->item_list.elements==1);
-  res_type= set_row(select_lex->item_list, item, row, &maybe_null);
+  set_row(select_lex->item_list, row);
   item->collation.set(row[0]->collation);
   if (cols() != 1)
     maybe_null= 0;
@@ -1393,13 +1406,14 @@ void subselect_union_engine::fix_length_and_dec(Item_cache **row)
 
   if (unit->first_select()->item_list.elements == 1)
   {
-    res_type= set_row(unit->types, item, row, &maybe_null);
+    set_row(unit->types, row);
     item->collation.set(row[0]->collation);
   }
   else
   {
-    bool fake= 0;
-    res_type= set_row(unit->types, item, row, &fake);
+    bool maybe_null_saved= maybe_null;
+    set_row(unit->types, row);
+    maybe_null= maybe_null_saved;
   }
 }
 
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 93171ad64a1..7b064bfe92c 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -142,6 +142,7 @@ public:
   longlong val_int ();
   String *val_str (String *);
   enum Item_result result_type() const;
+  enum_field_types field_type() const;
   void fix_length_and_dec();
 
   uint cols();
@@ -273,6 +274,7 @@ protected:
   THD *thd; /* pointer to current THD */
   Item_subselect *item; /* item, that use this engine */
   enum Item_result res_type; /* type of results */
+  enum_field_types res_field_type; /* column type of the results */
   bool maybe_null; /* may be null (first item in select) */
 public:
 
@@ -282,6 +284,7 @@ public:
     result= res;
     item= si;
     res_type= STRING_RESULT;
+    res_field_type= FIELD_TYPE_VAR_STRING;
     maybe_null= 0;
   }
   virtual ~subselect_engine() {}; // to satisfy compiler
@@ -296,6 +299,7 @@ public:
   virtual uint cols()= 0; /* return number of columnss in select */
   virtual uint8 uncacheable()= 0; /* query is uncacheable */
   enum Item_result type() { return res_type; }
+  enum_field_types field_type() { return res_field_type; }
   virtual void exclude()= 0;
   bool may_be_null() { return maybe_null; };
   virtual table_map upper_select_const_tables()= 0;
@@ -303,6 +307,9 @@ public:
   virtual void print(String *str)= 0;
   virtual int change_item(Item_subselect *si, select_subselect *result)= 0;
   virtual bool no_tables()= 0;
+
+protected:
+  void set_row(List<Item> &item_list, Item_cache **row);
 };
 
 

From 93b36e8e0524a931809927ab48723bf148a29e1c Mon Sep 17 00:00:00 2001
From: unknown <gkodinov/kgeorge@macbook.gmz>
Date: Wed, 8 Nov 2006 15:15:56 +0200
Subject: [PATCH 07/18] Make a new test target for autopush.pl to run memory
 based tests

---
 Makefile.am | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 2aefbd05283..48f84269313 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -124,3 +124,10 @@ test-force-pl:
 	cd mysql-test; \
 	./mysql-test-run.pl --force && \
 	./mysql-test-run.pl --ps-protocol --force
+
+#used by autopush.pl to run memory based tests
+test-force-mem:
+	cd mysql-test; \
+	./mysql-test-run.pl --force --mem && \
+	./mysql-test-run.pl --ps-protocol --force --mem
+

From f53af7b8e5a8913af0625031304eb824b6330e4b Mon Sep 17 00:00:00 2001
From: unknown <gkodinov/kgeorge@macbook.gmz>
Date: Mon, 13 Nov 2006 12:28:55 +0200
Subject: [PATCH 08/18] Bug #19216: Client crashes on long SELECT  The server
 sends a number of columns to the client.  It uses a limited "fast" function
 for that instead of the  general one. This fast function cannot send numbers
 larger  than 2 bytes.  This causes the client to expect smaller number of
 columns.  The client writes outside of the allocated memory buffer  as a
 result.  Fixed the server to use the general function to send column  count. 
 Fixed the client to check the column count before writing  column data.

mysql-test/t/mysql_client.test:
  Bug #19216: Client crashes on long SELECT
   - test case
sql/protocol.cc:
  Bug #19216: Client crashes on long SELECT
   - renamed the function for bether comprehention
     and made it local
   - used the right (non-local) function to transfer
     the column count in Protocol::send_fields
sql/protocol.h:
  Bug #19216: Client crashes on long SELECT
   - made optimized net_store_length local
sql-common/client.c:
  Bug #19216: Client crashes on long SELECT
   - fixed the client to check for older servers (without the fix).
---
 mysql-test/t/mysql_client.test | 18 ++++++++++++++++++
 sql-common/client.c            |  2 ++
 sql/protocol.cc                | 18 +++++++++---------
 sql/protocol.h                 |  1 -
 4 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/mysql-test/t/mysql_client.test b/mysql-test/t/mysql_client.test
index b382357dacf..7bd7c762c5c 100644
--- a/mysql-test/t/mysql_client.test
+++ b/mysql-test/t/mysql_client.test
@@ -33,3 +33,21 @@
 #
 --exec echo 'help' | $MYSQL   >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
 --exec echo 'help ' | $MYSQL  >  $MYSQLTEST_VARDIR/tmp/bug20328.tmp
+
+#
+# Bug #19216: Client crashes on long SELECT
+#
+--exec echo "select" > $MYSQLTEST_VARDIR/tmp/b19216.tmp
+# 3400 * 20 makes 68000 columns that is more than the max number that can fit 
+# in a 16 bit number.
+let $i= 3400;
+while ($i)
+{
+  --exec echo "'a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a','a'," >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+  dec $i;
+}
+
+--exec echo "'b';" >> $MYSQLTEST_VARDIR/tmp/b19216.tmp
+--disable_query_log
+--exec $MYSQL < $MYSQLTEST_VARDIR/tmp/b19216.tmp >/dev/null
+--enable_query_log
diff --git a/sql-common/client.c b/sql-common/client.c
index ff5f1ef150a..fb32eea33c7 100644
--- a/sql-common/client.c
+++ b/sql-common/client.c
@@ -1173,6 +1173,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields,
     for (row=data->data; row ; row = row->next,field++)
     {
       uchar *pos;
+      /* fields count may be wrong */
+      DBUG_ASSERT ((field - result) < fields);
       cli_fetch_lengths(&lengths[0], row->data, default_value ? 8 : 7);
       field->catalog  = strdup_root(alloc,(char*) row->data[0]);
       field->db       = strdup_root(alloc,(char*) row->data[1]);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index a2287740f1e..7c7dfaf7bef 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -43,7 +43,7 @@ bool Protocol_prep::net_store_data(const char *from, uint length)
       packet->realloc(packet_length+9+length))
     return 1;
   char *to=(char*) net_store_length((char*) packet->ptr()+packet_length,
-				    (ulonglong) length);
+				    length);
   memcpy(to,from,length);
   packet->length((uint) (to+length-packet->ptr()));
   return 0;
@@ -297,8 +297,8 @@ send_ok(THD *thd, ha_rows affected_rows, ulonglong id, const char *message)
     DBUG_VOID_RETURN;
 
   buff[0]=0;					// No fields
-  pos=net_store_length(buff+1,(ulonglong) affected_rows);
-  pos=net_store_length(pos, (ulonglong) id);
+  pos=net_store_length(buff+1,affected_rows);
+  pos=net_store_length(pos, id);
   if (thd->client_capabilities & CLIENT_PROTOCOL_41)
   {
     DBUG_PRINT("info",
@@ -416,7 +416,7 @@ bool send_old_password_request(THD *thd)
   ulonglong for bigger numbers.
 */
 
-char *net_store_length(char *pkg, uint length)
+static char *net_store_length_fast(char *pkg, uint length)
 {
   uchar *packet=(uchar*) pkg;
   if (length < 251)
@@ -439,7 +439,7 @@ char *net_store_length(char *pkg, uint length)
 
 char *net_store_data(char *to,const char *from, uint length)
 {
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,from,length);
   return to+length;
 }
@@ -448,7 +448,7 @@ char *net_store_data(char *to,int32 from)
 {
   char buff[20];
   uint length=(uint) (int10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -457,7 +457,7 @@ char *net_store_data(char *to,longlong from)
 {
   char buff[22];
   uint length=(uint) (longlong10_to_str(from,buff,10)-buff);
-  to=net_store_length(to,length);
+  to=net_store_length_fast(to,length);
   memcpy(to,buff,length);
   return to+length;
 }
@@ -520,7 +520,7 @@ bool Protocol::send_fields(List<Item> *list, uint flag)
 
   if (flag & 1)
   {				// Packet with number of elements
-    char *pos=net_store_length(buff, (uint) list->elements);
+    char *pos=net_store_length(buff, list->elements);
     (void) my_net_write(&thd->net, buff,(uint) (pos-buff));
   }
 
@@ -648,7 +648,7 @@ bool Protocol::send_records_num(List<Item> *list, ulonglong records)
 {
   char *pos;
   char buff[20];
-  pos=net_store_length(buff, (uint) list->elements);
+  pos=net_store_length(buff, list->elements);
   pos=net_store_length(pos, records);
   return my_net_write(&thd->net, buff,(uint) (pos-buff));
 }
diff --git a/sql/protocol.h b/sql/protocol.h
index 32d6acccddf..ce3adb41df5 100644
--- a/sql/protocol.h
+++ b/sql/protocol.h
@@ -177,7 +177,6 @@ void send_ok(THD *thd, ha_rows affected_rows=0L, ulonglong id=0L,
 	     const char *info=0);
 void send_eof(THD *thd, bool no_flush=0);
 bool send_old_password_request(THD *thd);
-char *net_store_length(char *packet,uint length);
 char *net_store_data(char *to,const char *from, uint length);
 char *net_store_data(char *to,int32 from);
 char *net_store_data(char *to,longlong from);

From 5363ec5275b0087ecbbe86b5e9ae9e7cb0229795 Mon Sep 17 00:00:00 2001
From: unknown <joerg@trift2.>
Date: Wed, 15 Nov 2006 20:27:02 +0100
Subject: [PATCH 09/18] support-files/mysql.spec.sh  :  Use "report features"
 in the first test run.

support-files/mysql.spec.sh:
  Switch from "make test*" to explicit calls of the test suite, so that "report features" can be used.
---
 support-files/mysql.spec.sh | 15 +++++++++++++--
 1 file changed, 13 insertions(+), 2 deletions(-)

diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 1daac2d0e95..1547a5b578d 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -317,7 +317,10 @@ then
   cp -fp config.log "$MYSQL_MAXCONFLOG_DEST"
 fi
 
-make -i test-force || true
+( cd mysql-test
+  perl ./mysql-test-run.pl --force --report-features
+  perl ./mysql-test-run.pl --force --ps-protocol
+  true )
 
 # Save mysqld-max
 ./libtool --mode=execute cp sql/mysqld sql/mysqld-max
@@ -380,7 +383,10 @@ then
   cp -fp config.log "$MYSQL_CONFLOG_DEST"
 fi
 
-make -i test-force || true
+( cd mysql-test
+  perl ./mysql-test-run.pl --force --report-features
+  perl ./mysql-test-run.pl --force --ps-protocol
+  true )
 
 %install
 RBR=$RPM_BUILD_ROOT
@@ -716,6 +722,11 @@ fi
 # itself - note that they must be ordered by date (important when
 # merging BK trees)
 %changelog 
+* Wed Nov 15 2006 Joerg Bruehe <joerg@mysql.com>
+
+- Switch from "make test*" to explicit calls of the test suite,
+  so that "report features" can be used.
+
 * Tue Jun 27 2006 Joerg Bruehe <joerg@mysql.com>
 
 - move "mysqldumpslow" from the client RPM to the server RPM (bug#20216)

From aa13653a1c1ed4c23cbb5252448475b1213660e0 Mon Sep 17 00:00:00 2001
From: unknown <joerg@trift2.>
Date: Thu, 16 Nov 2006 14:01:31 +0100
Subject: [PATCH 10/18] support-files/mysql.spec.sh  :   Add an "Obsoletes"
 note relative to SuSE RPMs (bug#22081).

support-files/mysql.spec.sh:
  Explicitly note that the "MySQL-shared" RPMs (as built by MySQL AB) replace
  "mysql-shared" (as distributed by SuSE) to allow easy upgrading (bug#22081).
---
 support-files/mysql.spec.sh | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 1547a5b578d..b14ffd24894 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -170,6 +170,8 @@ necessary to develop MySQL client applications.
 %package shared
 Summary: MySQL - Shared libraries
 Group: Applications/Databases
+Provides: mysql-shared
+Obsoletes: mysql-shared
 
 %description shared
 This package contains the shared libraries (*.so*) which certain
@@ -722,6 +724,12 @@ fi
 # itself - note that they must be ordered by date (important when
 # merging BK trees)
 %changelog 
+* Thu Nov 16 2006 Joerg Bruehe <joerg@mysql.com>
+
+- Explicitly note that the "MySQL-shared" RPMs (as built by MySQL AB) 
+  replace "mysql-shared" (as distributed by SuSE) to allow easy upgrading
+  (bug#22081).
+
 * Wed Nov 15 2006 Joerg Bruehe <joerg@mysql.com>
 
 - Switch from "make test*" to explicit calls of the test suite,

From 83a7bbf730a0b274fa1050eda174a3f718b6007a Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Thu, 16 Nov 2006 21:23:34 +0400
Subject: [PATCH 11/18] merging

---
 client/mysqltest.c | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/client/mysqltest.c b/client/mysqltest.c
index f2f2dc85d72..b73ee831cf3 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -183,18 +183,6 @@ DYNAMIC_ARRAY q_lines;
 
 #include "sslopt-vars.h"
 
-struct connection
-{
-  MYSQL mysql;
-  char *name;
-
-  const char *cur_query;
-  int cur_query_len;
-  pthread_mutex_t mutex;
-  pthread_cond_t cond;
-  int query_done;
-};
-
 struct
 {
   int read_lines,current_line;
@@ -234,6 +222,12 @@ struct st_connection
   MYSQL* util_mysql;
   char *name;
   MYSQL_STMT* stmt;
+
+  const char *cur_query;
+  int cur_query_len;
+  pthread_mutex_t mutex;
+  pthread_cond_t cond;
+  int query_done;
 };
 struct st_connection connections[128];
 struct st_connection* cur_con, *next_con, *connections_end;
@@ -493,7 +487,7 @@ void handle_no_error(struct st_command*);
 */
 pthread_handler_decl(send_one_query, arg)
 {
-  struct connection *cn= (struct connection*)arg;
+  struct st_connection *cn= (struct st_connection*)arg;
 
   mysql_thread_init();
   VOID(mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len));
@@ -507,7 +501,7 @@ pthread_handler_decl(send_one_query, arg)
   return 0;
 }
 
-static int do_send_query(struct connection *cn, const char *q, int q_len,
+static int do_send_query(struct st_connection *cn, const char *q, int q_len,
                          int flags)
 {
   pthread_t tid;
@@ -4570,7 +4564,7 @@ int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
   error - function will not return
 */
 
-void run_query_normal(struct connection *cn, *mysql, struct st_command *command,
+void run_query_normal(struct st_connection *cn, struct st_command *command,
                       int flags, char *query, int query_len,
                       DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
 {
@@ -4598,7 +4592,7 @@ void run_query_normal(struct connection *cn, *mysql, struct st_command *command,
    Here we handle 'reap' command, so we need to check if the
    query's thread was finished and probably wait
   */
-  else if (flags & QUERY_REAP)
+  else if (flags & QUERY_REAP_FLAG)
   {
     pthread_mutex_lock(&cn->mutex);
     while (!cn->query_done)
@@ -5096,8 +5090,9 @@ int util_query(MYSQL* org_mysql, const char* query){
 
 */
 
-void run_query(MYSQL *mysql, struct st_command *command, int flags)
+void run_query(struct st_connection *cn, struct st_command *command, int flags)
 {
+  MYSQL *mysql= &cn->mysql;
   DYNAMIC_STRING *ds;
   DYNAMIC_STRING ds_result;
   DYNAMIC_STRING ds_warnings;
@@ -5254,7 +5249,7 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags)
       match_re(&ps_re, query))
     run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings);
   else
-    run_query_normal(mysql, command, flags, query, query_len,
+    run_query_normal(cn, command, flags, query, query_len,
 		     ds, &ds_warnings);
 
   if (sp_created)
@@ -5746,7 +5741,7 @@ int main(int argc, char **argv)
 	  strmake(command->require_file, save_file, sizeof(save_file));
 	  save_file[0]= 0;
 	}
-	run_query(cur, command, flags);
+	run_query(cur_con, command, flags);
 	command_executed++;
         command->last_argument= command->end;
 	break;

From e78fd1d14b7b151c4968702a28292d1d41b4f2ea Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Thu, 16 Nov 2006 23:00:48 +0400
Subject: [PATCH 12/18] merging

---
 Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile.am b/Makefile.am
index 48f84269313..12a867c1ad7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -126,7 +126,7 @@ test-force-pl:
 	./mysql-test-run.pl --ps-protocol --force
 
 #used by autopush.pl to run memory based tests
-test-force-mem:
+test-force-pl-mem:
 	cd mysql-test; \
 	./mysql-test-run.pl --force --mem && \
 	./mysql-test-run.pl --ps-protocol --force --mem

From a3d041559d2a466da9e0115c0f8f1044de98db70 Mon Sep 17 00:00:00 2001
From: unknown <holyfoot/hf@mysql.com/deer.(none)>
Date: Fri, 17 Nov 2006 14:30:08 +0400
Subject: [PATCH 13/18] ABI fix

include/mysql_h.ic:
  this one should actually be removed from the ABI
---
 include/mysql_h.ic | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/mysql_h.ic b/include/mysql_h.ic
index 30ef44a1ccb..44c36c84747 100644
--- a/include/mysql_h.ic
+++ b/include/mysql_h.ic
@@ -154,7 +154,6 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned
     struct st_mysql_methods const * methods;
     void * thd;
     my_bool * unbuffered_fetch_owner;
-    struct st_mysql_stmt * current_stmt;
   };
 # 571 "mysql.h"
 struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind

From c3d6927d58b32af1ec3bcd33bdad7b7b6d02ddd0 Mon Sep 17 00:00:00 2001
From: unknown <dfischer/df@kahlann.erinye.com>
Date: Fri, 17 Nov 2006 16:52:21 +0100
Subject: [PATCH 14/18] MTR_BUILD_THREAD=auto selects a value for
 MTR_BUILD_THREAD from a pool (WL#2690)

mysql-test/lib/mtr_unique.pl:
  Library file used by mysql-test-run.pl to determine unique test run identifiers.
---
 mysql-test/lib/mtr_unique.pl | 119 +++++++++++++++++++++++++++++++++++
 mysql-test/mysql-test-run.pl |  10 +++
 2 files changed, 129 insertions(+)
 create mode 100644 mysql-test/lib/mtr_unique.pl

diff --git a/mysql-test/lib/mtr_unique.pl b/mysql-test/lib/mtr_unique.pl
new file mode 100644
index 00000000000..9bf86e26f4f
--- /dev/null
+++ b/mysql-test/lib/mtr_unique.pl
@@ -0,0 +1,119 @@
+#
+# This file is used from mysql-test-run.pl when choosing
+# port numbers and directories to use for running mysqld.
+#
+
+use strict;
+use Fcntl ':flock';
+
+#
+# Requested IDs are stored in a hash and released upon END.
+#
+my %mtr_unique_assigned_ids = ();
+END { 
+	while(my ($id,$file) = each(%mtr_unique_assigned_ids)) {
+		print "Autoreleasing $file:$id\n";
+		mtr_release_unique_id($file, $id);
+	}
+}
+
+#
+# Require a unique, numerical ID, given a file name (where all
+# requested IDs are stored), a minimum and a maximum value.
+#
+# We use flock to implement locking for the ID file and ignore
+# possible problems arising from lack of support for it on 
+# some platforms (it should work on most, and the possible
+# race condition would occur rarely). The proper solution for
+# this is a daemon that manages IDs, of course.
+#
+# If no unique ID within the specified parameters can be 
+# obtained, return undef.
+#
+sub mtr_require_unique_id($$$) {
+	my $file = shift;
+	my $min = shift;
+	my $max = shift;
+	my $ret = undef;
+
+	chmod 0777, "$file.sem";
+	open SEM, ">", "$file.sem" or die "can't write to $file.sem";
+	flock SEM, LOCK_EX or die "can't lock $file.sem";
+	if(! -e $file) {
+		open FILE, ">", $file or die "can't create $file";
+		close FILE;
+	}
+	chmod 0777, $file;
+	open FILE, "+<", $file or die "can't open $file";
+	select undef,undef,undef,0.2;
+	seek FILE, 0, 0;
+	my %taken = ();
+	while(<FILE>) {
+		chomp;
+		my ($id, $pid) = split / /;
+		$taken{$id} = $pid;
+	}
+	seek FILE, 0, 2;
+	for(my $i=$min; $i<=$max; ++$i) {
+		if(! exists $taken{$i}) {
+			print FILE "$i $$\n";
+			$ret = $i;
+			last;
+		}
+	}
+	close FILE;
+	flock SEM, LOCK_UN or warn "can't unlock $file.sem";
+	close SEM;
+	$mtr_unique_assigned_ids{$ret} = $file if defined $ret;
+	return $ret;
+}
+
+#
+# Require a unique ID like above, but sleep if no ID can be
+# obtained immediately.
+#
+sub mtr_require_unique_id_and_wait($$$) {
+	my $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
+	while(! defined $ret) {
+		sleep 10;
+		$ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
+	}
+	return $ret;
+}
+
+#
+# Release a unique ID.
+#
+sub mtr_release_unique_id($$) {
+	my $file = shift;
+	my $myid = shift;
+
+	open SEM, ">", "$file.sem" or die "can't write to $file.sem";
+	flock SEM, LOCK_EX or die "can't lock $file.sem";
+	if(! -e $file) {
+		open FILE, ">", $file or die "can't create $file";
+		close FILE;
+	}
+	open FILE, "+<", $file or die "can't open $file";
+	select undef,undef,undef,0.2;
+	seek FILE, 0, 0;
+	my %taken = ();
+	while(<FILE>) {
+		chomp;
+		my ($id, $pid) = split / /;
+		$taken{$id} = $pid;
+	}
+	delete $taken{$myid};
+	seek FILE, 0, 0;
+	truncate FILE, 0 or die "can't truncate $file";
+	for my $k (keys %taken) {
+		print FILE $k . ' ' . $taken{$k} . "\n";
+	}
+	close FILE;
+	flock SEM, LOCK_UN or warn "can't unlock $file.sem";
+	close SEM;
+	delete $mtr_unique_assigned_ids{$myid};
+}
+
+1;
+
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index ce9fd4344ea..f3981dc7c70 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -85,6 +85,7 @@ require "lib/mtr_diff.pl";
 require "lib/mtr_match.pl";
 require "lib/mtr_misc.pl";
 require "lib/mtr_stress.pl";
+require "lib/mtr_unique.pl";
 
 $Devel::Trace::TRACE= 1;
 
@@ -449,6 +450,15 @@ sub initial_setup () {
   select(STDOUT);
   $| = 1;                       # Make unbuffered
 
+  # If so requested, we try to avail ourselves of a unique build thread number.
+  if ( $ENV{'MTR_BUILD_THREAD'} ) {
+    if ( lc($ENV{'MTR_BUILD_THREAD'}) eq 'auto' ) {
+      print "Requesting build thread... ";
+      $ENV{'MTR_BUILD_THREAD'} = mtr_require_unique_id_and_wait("/tmp/mysql-test-ports", 200, 299);
+      print "got ".$ENV{'MTR_BUILD_THREAD'}."\n";
+    }
+  }
+
   $glob_scriptname=  basename($0);
 
   # We require that we are in the "mysql-test" directory

From 6de6b97eeed6db587d1c856178262d7ead396a9b Mon Sep 17 00:00:00 2001
From: unknown <df@kahlann.erinye.com>
Date: Fri, 24 Nov 2006 15:36:04 +0100
Subject: [PATCH 15/18] fixes for mtr_unique.pl

mysql-test/lib/mtr_unique.pl:
  - add info message to mtr_require_unique_id_and_wait as suggested
  - fix for security issue
  - locks for pids of processes that don't exist anymore are reused, if ps is present and working as expected
---
 mysql-test/lib/mtr_unique.pl | 43 +++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)

diff --git a/mysql-test/lib/mtr_unique.pl b/mysql-test/lib/mtr_unique.pl
index 9bf86e26f4f..a8fb320c773 100644
--- a/mysql-test/lib/mtr_unique.pl
+++ b/mysql-test/lib/mtr_unique.pl
@@ -35,6 +35,13 @@ sub mtr_require_unique_id($$$) {
 	my $min = shift;
 	my $max = shift;
 	my $ret = undef;
+	my $changed = 0;
+
+	my $can_use_ps = `ps -e | grep '^[ ]*$$ '`;
+
+	if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
+		die 'lock file is a symbolic link';
+	}
 
 	chmod 0777, "$file.sem";
 	open SEM, ">", "$file.sem" or die "can't write to $file.sem";
@@ -43,6 +50,11 @@ sub mtr_require_unique_id($$$) {
 		open FILE, ">", $file or die "can't create $file";
 		close FILE;
 	}
+
+	if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
+		die 'lock file is a symbolic link';
+	}
+
 	chmod 0777, $file;
 	open FILE, "+<", $file or die "can't open $file";
 	select undef,undef,undef,0.2;
@@ -52,15 +64,30 @@ sub mtr_require_unique_id($$$) {
 		chomp;
 		my ($id, $pid) = split / /;
 		$taken{$id} = $pid;
+		if($can_use_ps) {
+			my $res = `ps -e | grep '^[ ]*$pid '`;
+			if(!$res) {
+				print "Ignoring slot $id used by missing process $pid.\n";
+				delete $taken{$id};
+				++$changed;
+			}
+		}
 	}
-	seek FILE, 0, 2;
 	for(my $i=$min; $i<=$max; ++$i) {
 		if(! exists $taken{$i}) {
-			print FILE "$i $$\n";
 			$ret = $i;
+			$taken{$i} = $$;
+			++$changed;
 			last;
 		}
 	}
+	if($changed) {
+		seek FILE, 0, 0;
+		truncate FILE, 0 or die "can't truncate $file";
+		for my $k (keys %taken) {
+			print FILE $k . ' ' . $taken{$k} . "\n";
+		}
+	}
 	close FILE;
 	flock SEM, LOCK_UN or warn "can't unlock $file.sem";
 	close SEM;
@@ -75,8 +102,9 @@ sub mtr_require_unique_id($$$) {
 sub mtr_require_unique_id_and_wait($$$) {
 	my $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
 	while(! defined $ret) {
-		sleep 10;
+		sleep 30;
 		$ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
+		print "Waiting for unique id to become available...\n" unless $ret;
 	}
 	return $ret;
 }
@@ -88,8 +116,17 @@ sub mtr_release_unique_id($$) {
 	my $file = shift;
 	my $myid = shift;
 
+	if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
+		die 'lock file is a symbolic link';
+	}
+
 	open SEM, ">", "$file.sem" or die "can't write to $file.sem";
 	flock SEM, LOCK_EX or die "can't lock $file.sem";
+
+	if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
+		die 'lock file is a symbolic link';
+	}
+
 	if(! -e $file) {
 		open FILE, ">", $file or die "can't create $file";
 		close FILE;

From 8d6f67f3269917f0353c94e387a04e629445f0ce Mon Sep 17 00:00:00 2001
From: unknown <kent@mysql.com/kent-amd64.(none)>
Date: Mon, 27 Nov 2006 18:29:50 +0100
Subject: [PATCH 16/18] gen_rec.awk:   Fix undefined behaviour. Many files:  
 Reenabled build outside ource tree

bdb/dist/gen_rec.awk:
  Fix undefined behaviour.
acinclude.m4:
  Reenabled build outside ource tree
configure.in:
  Reenabled build outside ource tree
libmysql_r/Makefile.am:
  Reenabled build outside ource tree
libmysqld/Makefile.am:
  Reenabled build outside ource tree
ndb/config/common.mk.am:
  Reenabled build outside ource tree
ndb/config/type_kernel.mk.am:
  Reenabled build outside ource tree
ndb/config/type_ndbapi.mk.am:
  Reenabled build outside ource tree
ndb/config/type_ndbapitest.mk.am:
  Reenabled build outside ource tree
ndb/config/type_ndbapitools.mk.am:
  Reenabled build outside ource tree
ndb/config/type_util.mk.am:
  Reenabled build outside ource tree
ndb/src/kernel/Makefile.am:
  Reenabled build outside ource tree
---
 acinclude.m4                      | 16 ++++++++--------
 bdb/dist/gen_rec.awk              |  2 +-
 configure.in                      |  6 ++++--
 libmysql_r/Makefile.am            | 10 +++++-----
 libmysqld/Makefile.am             | 24 +++++++++++++++++++-----
 ndb/config/common.mk.am           |  2 +-
 ndb/config/type_kernel.mk.am      |  5 ++++-
 ndb/config/type_ndbapi.mk.am      |  6 +++++-
 ndb/config/type_ndbapitest.mk.am  |  5 ++++-
 ndb/config/type_ndbapitools.mk.am |  5 ++++-
 ndb/config/type_util.mk.am        |  5 ++++-
 ndb/src/kernel/Makefile.am        | 30 +++++++++++++++---------------
 12 files changed, 74 insertions(+), 42 deletions(-)

diff --git a/acinclude.m4 b/acinclude.m4
index 0337b9de0cd..811e9c0b183 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -1448,20 +1448,20 @@ bdb_version_ok=yes
 ])
 
 AC_DEFUN([MYSQL_TOP_BUILDDIR], [
+  # Remove trailing "./" if any
+  [$1]=`echo $[$1] | sed -e 's,^\./,,'`
   case "$[$1]" in
-    /* ) ;;		# don't do anything with an absolute path
-    "$srcdir"/* )
+    "bdb" | "$srcdir/bdb" | "$top_srcdir/bdb" | "$abs_top_srcdir/bdb" )
       # If BDB is under the source directory, we need to look under the
       # build directory for bdb/build_unix.
-      # NOTE: I'm being lazy, and assuming the user did not specify
-      # something like --with-berkeley-db=bdb (it would be missing "./").
-      [$1]="\$(top_builddir)/"`echo "$[$1]" | sed -e "s,^$srcdir/,,"`
+      [$1]="\$(top_builddir)/bdb"
       ;;
+    /* ) ;;  # Other absolute path is assume to be external BDB directory
     * )
       AC_MSG_ERROR([The BDB directory must be directly under the MySQL source directory, or be specified using the full path. ('$srcdir'; '$[$1]')])
       ;;
   esac
-  if test X"$[$1]" != "/"
+  if test X"$[$1]" != X"/"
   then
     [$1]=`echo $[$1] | sed -e 's,/$,,'`
   fi
@@ -1493,7 +1493,7 @@ AC_DEFUN([MYSQL_CHECK_INNODB], [
       AC_MSG_RESULT([Using Innodb])
       AC_DEFINE([HAVE_INNOBASE_DB], [1], [Using Innobase DB])
       have_innodb="yes"
-      innodb_includes="-I../innobase/include"
+      innodb_includes="-I\$(top_builddir)/innobase/include -I\$(top_srcdir)/innobase/include"
       innodb_system_libs=""
 dnl Some libs are listed several times, in order for gcc to sort out
 dnl circular references.
@@ -1812,7 +1812,7 @@ AC_DEFUN([MYSQL_CHECK_NDBCLUSTER], [
       AC_MSG_RESULT([Using NDB Cluster])
       AC_DEFINE([HAVE_NDBCLUSTER_DB], [1], [Using Ndb Cluster DB])
       have_ndbcluster="yes"
-      ndbcluster_includes="-I../ndb/include -I../ndb/include/ndbapi"
+      ndbcluster_includes="-I\$(top_builddir)/ndb/include -I\$(top_srcdir)/ndb/include -I\$(top_srcdir)/ndb/include/ndbapi"
       ndbcluster_libs="\$(top_builddir)/ndb/src/.libs/libndbclient.a"
       ndbcluster_system_libs=""
       ndb_mgmclient_libs="\$(top_builddir)/ndb/src/mgmclient/libndbmgmclient.la"
diff --git a/bdb/dist/gen_rec.awk b/bdb/dist/gen_rec.awk
index 75f2e86ca9e..e1b75699027 100644
--- a/bdb/dist/gen_rec.awk
+++ b/bdb/dist/gen_rec.awk
@@ -180,7 +180,7 @@ BEGIN {
 		t = types[i];
 		if (modes[i] == "POINTER") {
 			ndx = index(t, "*");
-			t = substr(types[i], 0, ndx - 2);
+			t = substr(types[i], 1, ndx - 2);
 		}
 		printf("\t%s\t%s;\n", t, vars[i]) >> HFILE
 	}
diff --git a/configure.in b/configure.in
index a8eed676756..4ac0637e42c 100644
--- a/configure.in
+++ b/configure.in
@@ -46,12 +46,14 @@ do
   case $host_os in
     netware* | modesto*)
       echo "$i/errmsg.sys: $i/errmsg.txt
-	\$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ $i/errmsg.txt $i/errmsg.sys" \
+	mkdir -p $i
+	\$(top_builddir)/extra/comp_err.linux -C\$(srcdir)/charsets/ \$(srcdir)/$i/errmsg.txt $i/errmsg.sys" \
       >> $AVAILABLE_LANGUAGES_ERRORS_RULES
       ;;
     *)
   echo "$i/errmsg.sys: $i/errmsg.txt
-	\$(top_builddir)/extra/comp_err -C\$(srcdir)/charsets/ $i/errmsg.txt $i/errmsg.sys" \
+	mkdir -p $i
+	\$(top_builddir)/extra/comp_err -C\$(srcdir)/charsets/ \$(srcdir)/$i/errmsg.txt $i/errmsg.sys" \
     >> $AVAILABLE_LANGUAGES_ERRORS_RULES
       ;;
   esac
diff --git a/libmysql_r/Makefile.am b/libmysql_r/Makefile.am
index f7cf00321cb..31f6fdffd53 100644
--- a/libmysql_r/Makefile.am
+++ b/libmysql_r/Makefile.am
@@ -31,8 +31,6 @@ INCLUDES =	@MT_INCLUDES@ \
 ## automake barfs if you don't use $(srcdir) or $(top_srcdir) in include
 include $(top_srcdir)/libmysql/Makefile.shared
 
-libmysql_dir = $(top_srcdir)/libmysql
-
 libmysqlclient_r_la_SOURCES = $(target_sources)
 libmysqlclient_r_la_LIBADD = $(target_libadd)
 libmysqlclient_r_la_LDFLAGS = $(target_ldflags)
@@ -40,7 +38,9 @@ libmysqlclient_r_la_LDFLAGS = $(target_ldflags)
 # This is called from the toplevel makefile
 link_sources:
 	set -x; \
-	for f in `cd $(libmysql_dir) && echo *.[ch]`; do \
-	  rm -f $$f; \
-	  @LN_CP_F@ $(libmysql_dir)/$$f $$f; \
+	for d in $(top_srcdir)/libmysql $(top_builddir)/libmysql; do \
+	  for f in `cd $$d && echo *.[ch]`; do \
+	    rm -f $$f; \
+	    @LN_CP_F@ $$d/$$f $$f; \
+	  done; \
 	done
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index e121e4b8d6e..9582084ba5d 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -25,9 +25,11 @@ DEFS =			-DEMBEDDED_LIBRARY -DMYSQL_SERVER \
 			-DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
 			-DDATADIR="\"$(MYSQLDATAdir)\"" \
 			-DSHAREDIR="\"$(MYSQLSHAREdir)\""
-INCLUDES=		@MT_INCLUDES@ @bdb_includes@ \
+INCLUDES=		@MT_INCLUDES@ @bdb_includes@  @innodb_includes@ @ndbcluster_includes@ \
 			-I$(top_builddir)/include -I$(top_srcdir)/include \
-			-I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples -I$(top_srcdir)/regex \
+			-I$(top_builddir)/sql -I$(top_srcdir)/sql \
+			-I$(top_srcdir)/sql/examples \
+			-I$(top_srcdir)/regex \
 			$(openssl_includes) @ZLIB_INCLUDES@
 
 noinst_LIBRARIES =	libmysqld_int.a
@@ -118,16 +120,28 @@ endif
 #libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
 #CLEANFILES =		$(libmysqld_la_LIBADD) libmysqld.la
 
-# This is called from the toplevel makefile
+# This is called from the toplevel makefile. If we can link now
+# to an existing file in source, we do that, else we assume it
+# will show up in the build tree eventually (generated file).
 link_sources:
 	  set -x; \
 	  for f in $(sqlsources); do \
 	    rm -f $$f; \
-	    @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
+	    if test -e $(top_srcdir)/sql/$$f ; \
+            then \
+	      @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
+            else \
+	      @LN_CP_F@ $(top_builddir)/sql/$$f $$f; \
+            fi ; \
 	  done; \
 	  for f in $(libmysqlsources); do \
 	    rm -f $$f; \
-	    @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
+	    if test -e $(top_srcdir)/libmysql/$$f ; \
+	    then \
+	      @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
+	    else \
+	      @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \
+	    fi ; \
 	  done; \
 	  for f in $(sqlexamplessources); do \
 	    rm -f $$f; \
diff --git a/ndb/config/common.mk.am b/ndb/config/common.mk.am
index 4df1b0e289a..d0b7e753285 100644
--- a/ndb/config/common.mk.am
+++ b/ndb/config/common.mk.am
@@ -7,6 +7,6 @@ ndbapiincludedir = "$(pkgincludedir)/ndb/ndbapi"
 mgmapiincludedir = "$(pkgincludedir)/ndb/mgmapi"
 
 INCLUDES = $(INCLUDES_LOC)
-LDADD = $(LDADD_LOC) -L$(top_srcdir)/ndb/src/common/portlib -lmygcc
+LDADD = $(LDADD_LOC) -L$(top_builddir)/ndb/src/common/portlib -lmygcc
 DEFS = @DEFS@ @NDB_DEFS@ $(DEFS_LOC) $(NDB_EXTRA_FLAGS)
 NDB_CXXFLAGS=@ndb_cxxflags_fix@ $(NDB_CXXFLAGS_LOC) 
diff --git a/ndb/config/type_kernel.mk.am b/ndb/config/type_kernel.mk.am
index 703876ee2e9..ccb01709dfb 100644
--- a/ndb/config/type_kernel.mk.am
+++ b/ndb/config/type_kernel.mk.am
@@ -1,6 +1,9 @@
 
 INCLUDES += \
-        -I$(srcdir) -I$(top_srcdir)/include \
+        -I$(srcdir) \
+	-I$(top_builddir)/include \
+	-I$(top_builddir)/ndb/include \
+	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/ndb/include \
         -I$(top_srcdir)/ndb/src/kernel/vm \
         -I$(top_srcdir)/ndb/src/kernel/error \
diff --git a/ndb/config/type_ndbapi.mk.am b/ndb/config/type_ndbapi.mk.am
index ed648273aea..8b447bd693d 100644
--- a/ndb/config/type_ndbapi.mk.am
+++ b/ndb/config/type_ndbapi.mk.am
@@ -1,6 +1,10 @@
 
 INCLUDES += \
-        -I$(srcdir) -I$(top_srcdir)/include -I$(top_srcdir)/ndb/include \
+        -I$(srcdir) \
+	-I$(top_builddir)/include \
+	-I$(top_builddir)/ndb/include \
+	-I$(top_srcdir)/include \
+	-I$(top_srcdir)/ndb/include \
 	-I$(top_srcdir)/ndb/include/kernel \
 	-I$(top_srcdir)/ndb/include/transporter \
 	-I$(top_srcdir)/ndb/include/debugger \
diff --git a/ndb/config/type_ndbapitest.mk.am b/ndb/config/type_ndbapitest.mk.am
index 392c4e9fc70..e9a383eaad7 100644
--- a/ndb/config/type_ndbapitest.mk.am
+++ b/ndb/config/type_ndbapitest.mk.am
@@ -5,7 +5,10 @@ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
          $(top_builddir)/mysys/libmysys.a \
          $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
 
-INCLUDES += -I$(top_srcdir) -I$(top_srcdir)/include \
+INCLUDES += -I$(top_srcdir) \
+	-I$(top_builddir)/include \
+	-I$(top_builddir)/ndb/include \
+	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/ndb/include \
         -I$(top_srcdir)/ndb/include/ndbapi \
         -I$(top_srcdir)/ndb/include/util \
diff --git a/ndb/config/type_ndbapitools.mk.am b/ndb/config/type_ndbapitools.mk.am
index 679dac09f47..1f4d93af618 100644
--- a/ndb/config/type_ndbapitools.mk.am
+++ b/ndb/config/type_ndbapitools.mk.am
@@ -5,7 +5,10 @@ LDADD += \
          $(top_builddir)/mysys/libmysys.a \
          $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ -lmygcc
 
-INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \
+INCLUDES += -I$(srcdir) \
+	-I$(top_builddir)/include \
+	-I$(top_builddir)/ndb/include \
+	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/ndb/include \
         -I$(top_srcdir)/ndb/include/ndbapi \
         -I$(top_srcdir)/ndb/include/util \
diff --git a/ndb/config/type_util.mk.am b/ndb/config/type_util.mk.am
index 0dfa77b7a7c..b92501faee9 100644
--- a/ndb/config/type_util.mk.am
+++ b/ndb/config/type_util.mk.am
@@ -1,5 +1,8 @@
 
-INCLUDES += -I$(srcdir) -I$(top_srcdir)/include \
+INCLUDES += -I$(srcdir) \
+	-I$(top_builddir)/include \
+	-I$(top_builddir)/ndb/include \
+	-I$(top_srcdir)/include \
 	-I$(top_srcdir)/ndb/include \
         -I$(top_srcdir)/ndb/include/util \
         -I$(top_srcdir)/ndb/include/portlib \
diff --git a/ndb/src/kernel/Makefile.am b/ndb/src/kernel/Makefile.am
index 5b55238c262..c9e590835db 100644
--- a/ndb/src/kernel/Makefile.am
+++ b/ndb/src/kernel/Makefile.am
@@ -9,21 +9,21 @@ ndbd_SOURCES = main.cpp SimBlockList.cpp
 include $(top_srcdir)/ndb/config/type_kernel.mk.am
 
 INCLUDES += \
-              -Iblocks/cmvmi \
-              -Iblocks/dbacc \
-              -Iblocks/dbdict \
-              -Iblocks/dbdih \
-              -Iblocks/dblqh \
-              -Iblocks/dbtc \
-              -Iblocks/dbtup \
-              -Iblocks/ndbfs \
-              -Iblocks/ndbcntr \
-              -Iblocks/qmgr \
-              -Iblocks/trix \
-              -Iblocks/backup \
-              -Iblocks/dbutil \
-              -Iblocks/suma \
-              -Iblocks/dbtux
+	-I$(srcdir)/blocks/cmvmi \
+	-I$(srcdir)/blocks/dbacc \
+	-I$(srcdir)/blocks/dbdict \
+	-I$(srcdir)/blocks/dbdih \
+	-I$(srcdir)/blocks/dblqh \
+	-I$(srcdir)/blocks/dbtc \
+	-I$(srcdir)/blocks/dbtup \
+	-I$(srcdir)/blocks/ndbfs \
+	-I$(srcdir)/blocks/ndbcntr \
+	-I$(srcdir)/blocks/qmgr \
+	-I$(srcdir)/blocks/trix \
+	-I$(srcdir)/blocks/backup \
+	-I$(srcdir)/blocks/dbutil \
+	-I$(srcdir)/blocks/suma \
+	-I$(srcdir)/blocks/dbtux
 
 LDADD +=  \
               blocks/cmvmi/libcmvmi.a \

From f53733db5f7cc3fcab240d624ad09575064d2d2c Mon Sep 17 00:00:00 2001
From: unknown <kent@mysql.com/kent-amd64.(none)>
Date: Mon, 27 Nov 2006 19:04:57 +0100
Subject: [PATCH 17/18] Makefile.am:   BSD compatibility

Docs/Makefile.am:
  BSD compatibility
---
 Docs/Makefile.am | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index 685eaeef7d1..159dffddde8 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -40,22 +40,22 @@ CLEAN_FILES:		$(TXT_FILES)
 GT = $(srcdir)/Support/generate-text-files.pl
 
 ../INSTALL-SOURCE:	mysql.info $(GT)
-	perl -w $(GT) $< "installing-source" "windows-source-build" > $@
+	perl -w $(GT) $(srcdir)/mysql.info "installing-source" "windows-source-build" > $@
 
 ../INSTALL-WIN-SOURCE:	mysql.info $(GT)
-	perl -w $(GT) $< "windows-source-build" "post-installation" > $@
+	perl -w $(GT) $(srcdir)/mysql.info "windows-source-build" "post-installation" > $@
 
 # We put the description for the binary installation here so that
 # people who download source wont have to see it. It is moved up to
 # the toplevel by the script that makes the binary tar files.
 INSTALL-BINARY:	mysql.info $(GT)
-	perl -w $(GT) $< "installing-binary" "installing-source" > $@
+	perl -w $(GT) $(srcdir)/mysql.info "installing-binary" "installing-source" > $@
 
 ../EXCEPTIONS-CLIENT: mysql.info $(GT)
-	perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@
+	perl -w $(GT) $(srcdir)/mysql.info "mysql-floss-license-exception" "function-index" > $@
 
 ../support-files/MacOSX/ReadMe.txt:	mysql.info $(GT)
-	perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@
+	perl -w $(GT) $(srcdir)/mysql.info "mac-os-x-installation" "netware-installation" > $@
 
 # Don't update the files from bitkeeper
 %::SCCS/s.%

From 0fb7649940c849f4df4ceca7d01f5e8946ffbb0d Mon Sep 17 00:00:00 2001
From: unknown <kent@mysql.com/kent-amd64.(none)>
Date: Tue, 28 Nov 2006 18:04:10 +0100
Subject: [PATCH 18/18] Makefile.am:   If using \$(srcdir)/mysql.info in
 action, use same in rule.

Docs/Makefile.am:
  If using \$(srcdir)/mysql.info in action, use same in rule.
---
 Docs/Makefile.am | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/Docs/Makefile.am b/Docs/Makefile.am
index 159dffddde8..85a362133a1 100644
--- a/Docs/Makefile.am
+++ b/Docs/Makefile.am
@@ -26,7 +26,7 @@ all-local:		$(TXT_FILES)
 # make sure that "make install" installs the info page, too
 # automake only seems to take care of this automatically,
 # if we're building the info page from texi directly.
-install-data-hook:	mysql.info
+install-data-hook:	$(srcdir)/mysql.info
 	$(mkinstalldirs) $(DESTDIR)$(infodir)
 	$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir)
 
@@ -39,22 +39,22 @@ CLEAN_FILES:		$(TXT_FILES)
 
 GT = $(srcdir)/Support/generate-text-files.pl
 
-../INSTALL-SOURCE:	mysql.info $(GT)
+../INSTALL-SOURCE:	$(srcdir)/mysql.info $(GT)
 	perl -w $(GT) $(srcdir)/mysql.info "installing-source" "windows-source-build" > $@
 
-../INSTALL-WIN-SOURCE:	mysql.info $(GT)
+../INSTALL-WIN-SOURCE:	$(srcdir)/mysql.info $(GT)
 	perl -w $(GT) $(srcdir)/mysql.info "windows-source-build" "post-installation" > $@
 
 # We put the description for the binary installation here so that
 # people who download source wont have to see it. It is moved up to
 # the toplevel by the script that makes the binary tar files.
-INSTALL-BINARY:	mysql.info $(GT)
+INSTALL-BINARY:	$(srcdir)/mysql.info $(GT)
 	perl -w $(GT) $(srcdir)/mysql.info "installing-binary" "installing-source" > $@
 
-../EXCEPTIONS-CLIENT: mysql.info $(GT)
+../EXCEPTIONS-CLIENT: $(srcdir)/mysql.info $(GT)
 	perl -w $(GT) $(srcdir)/mysql.info "mysql-floss-license-exception" "function-index" > $@
 
-../support-files/MacOSX/ReadMe.txt:	mysql.info $(GT)
+../support-files/MacOSX/ReadMe.txt:	$(srcdir)/mysql.info $(GT)
 	perl -w $(GT) $(srcdir)/mysql.info "mac-os-x-installation" "netware-installation" > $@
 
 # Don't update the files from bitkeeper