MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:holyfoot Date:November 17 2006 2:27pm
Subject:bk commit into 5.1 tree (holyfoot:1.2367)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of hf. When hf does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-11-17 18:27:28+04:00, holyfoot@deer.(none) +22 -0
  Merge mysql.com:/home/hf/work/mysql-5.0-mrg
  into  mysql.com:/home/hf/work/mysql-5.1-mrg
  MERGE: 1.1810.1698.187

  BitKeeper/deleted/.del-bdb-deadlock.test@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.9.1.2

  BitKeeper/deleted/.del-bdb-deadlock.test@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Merge rename: mysql-test/t/bdb-deadlock.test -> BitKeeper/deleted/.del-bdb-deadlock.test

  Makefile.am@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.68.1.19

  client/mysqltest.c@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.155.9.67

  include/mysql.h@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.154.1.11

  libmysql/libmysql.c@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.233.1.15

  libmysqld/lib_sql.cc@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.107.1.9

  mysql-test/include/deadlock.inc@stripped, 2006-11-17 18:20:24+04:00, holyfoot@deer.(none) +0 -0
    SCCS merged
    MERGE: 1.11.1.2

  mysql-test/include/deadlock.inc@stripped, 2006-11-17 17:59:25+04:00, holyfoot@deer.(none) +0 -0
    Merge rename: mysql-test/t/innodb-deadlock.test -> mysql-test/include/deadlock.inc

  mysql-test/r/order_by.result@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.55.1.1

  mysql-test/r/subselect.result@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.134.1.31

  mysql-test/t/disabled.def@stripped, 2006-11-17 18:24:49+04:00, holyfoot@deer.(none) +1 -0
    merging
    MERGE: 1.2.4.15

  mysql-test/t/lock_multi.test@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.13.1.6

  mysql-test/t/rename.test@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.15.1.3

  mysql-test/t/show_check.test@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.54.1.8

  mysql-test/t/status.test@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.15.1.1

  mysql-test/t/subselect.test@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.129.1.4

  sql-common/client.c@stripped, 2006-11-17 17:59:27+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.83.1.20

  sql/item.cc@stripped, 2006-11-17 18:27:19+04:00, holyfoot@deer.(none) +0 -2
    merging
    MERGE: 1.113.1.125

  sql/item_subselect.cc@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.113.1.22

  sql/item_subselect.h@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.77.1.2

  sql/protocol.cc@stripped, 2006-11-17 17:59:26+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.111.1.6

  sql/protocol.h@stripped, 2006-11-17 17:59:27+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.31.1.2

  sql/sql_class.h@stripped, 2006-11-17 17:59:27+04:00, holyfoot@deer.(none) +0 -0
    Auto merged
    MERGE: 1.230.1.79

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	holyfoot
# Host:	deer.(none)
# Root:	/home/hf/work/mysql-5.1-mrg/RESYNC

--- 1.217/sql/item.cc	2006-11-17 18:27:38 +04:00
+++ 1.218/sql/item.cc	2006-11-17 18:27:38 +04:00
@@ -3672,11 +3672,37 @@ bool Item_field::fix_fields(THD *thd, It
         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);
+          }
         }
       }
       if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)

--- 1.119/sql/protocol.cc	2006-11-17 18:27:38 +04:00
+++ 1.120/sql/protocol.cc	2006-11-17 18:27:38 +04:00
@@ -46,7 +46,7 @@ bool Protocol_prep::net_store_data(const
       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;
@@ -282,8 +282,8 @@ send_ok(THD *thd, ha_rows affected_rows,
   }
 
   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",
@@ -458,7 +458,7 @@ void net_send_error_packet(THD *thd, uin
   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)
@@ -481,7 +481,7 @@ char *net_store_length(char *pkg, uint l
 
 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;
 }
@@ -490,7 +490,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;
 }
@@ -499,7 +499,7 @@ char *net_store_data(char *to,longlong f
 {
   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;
 }
@@ -563,7 +563,7 @@ bool Protocol::send_fields(List<Item> *l
 
   if (flags & SEND_NUM_ROWS)
   {				// 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));
   }
 

--- 1.326/sql/sql_class.h	2006-11-17 18:27:38 +04:00
+++ 1.327/sql/sql_class.h	2006-11-17 18:27:38 +04:00
@@ -838,6 +838,12 @@ public:
   struct st_mysql_data **data_tail;
   void clear_data_list();
   struct st_mysql_data *alloc_new_dataset();
+  /*
+    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

--- 1.155/mysql-test/r/subselect.result	2006-11-17 18:27:38 +04:00
+++ 1.156/mysql-test/r/subselect.result	2006-11-17 18:27:38 +04:00
@@ -3001,6 +3001,38 @@ 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;
+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;
 create table t1 (df decimal(5,1));
 insert into t1 values(1.1);
 insert into t1 values(2.2);

--- 1.133/mysql-test/t/subselect.test	2006-11-17 18:27:38 +04:00
+++ 1.134/mysql-test/t/subselect.test	2006-11-17 18:27:38 +04:00
@@ -1955,6 +1955,39 @@ 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;
+
+#
+# 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
 
 #

--- 1.131/sql/item_subselect.cc	2006-11-17 18:27:38 +04:00
+++ 1.132/sql/item_subselect.cc	2006-11-17 18:27:38 +04:00
@@ -434,6 +434,15 @@ enum Item_result Item_singlerow_subselec
   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)
@@ -710,6 +719,7 @@ double Item_in_subselect::val_real()
   */
   DBUG_ASSERT(0);
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();
@@ -730,6 +740,7 @@ longlong Item_in_subselect::val_int()
   */
   DBUG_ASSERT(0);
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();
@@ -750,6 +761,7 @@ String *Item_in_subselect::val_str(Strin
   */
   DBUG_ASSERT(0);
   DBUG_ASSERT(fixed == 1);
+  null_value= 0;
   if (exec())
   {
     reset();
@@ -1542,32 +1554,36 @@ int subselect_uniquesubquery_engine::pre
   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;
     item->unsigned_flag= sel_item->unsigned_flag;
     *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;
@@ -1579,13 +1595,14 @@ void subselect_union_engine::fix_length_
 
   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;
   }
 }
 

--- 1.79/sql/item_subselect.h	2006-11-17 18:27:38 +04:00
+++ 1.80/sql/item_subselect.h	2006-11-17 18:27:38 +04:00
@@ -156,6 +156,7 @@ public:
   my_decimal *val_decimal(my_decimal *);
   bool val_bool();
   enum Item_result result_type() const;
+  enum_field_types field_type() const;
   void fix_length_and_dec();
 
   uint cols();
@@ -292,6 +293,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:
 
@@ -301,6 +303,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
@@ -318,6 +321,7 @@ public:
   virtual uint cols()= 0; /* return number of columns 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;

--- 1.113/sql-common/client.c	2006-11-17 18:27:38 +04:00
+++ 1.114/sql-common/client.c	2006-11-17 18:27:38 +04:00
@@ -1186,6 +1186,8 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT 
     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]);

--- 1.56/mysql-test/r/order_by.result	2006-11-17 18:27:38 +04:00
+++ 1.57/mysql-test/r/order_by.result	2006-11-17 18:27:38 +04:00
@@ -854,6 +854,33 @@ 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;
 CREATE TABLE t1 (a int, b int, PRIMARY KEY  (a));
 INSERT INTO t1 VALUES (1,1), (2,2), (3,3);
 explain SELECT t1.b as a, t2.b as c FROM 

--- 1.18/mysql-test/t/rename.test	2006-11-17 18:27:38 +04:00
+++ 1.19/mysql-test/t/rename.test	2006-11-17 18:27:38 +04:00
@@ -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)

--- 1.69/mysql-test/t/show_check.test	2006-11-17 18:27:38 +04:00
+++ 1.70/mysql-test/t/show_check.test	2006-11-17 18:27:38 +04:00
@@ -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
 
 # check that CSV engine was compiled in, as the result of the test

--- 1.23/mysql-test/t/lock_multi.test	2006-11-17 18:27:38 +04:00
+++ 1.24/mysql-test/t/lock_multi.test	2006-11-17 18:27:38 +04:00
@@ -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

--- 1.11.1.1/mysql-test/t/innodb-deadlock.test	2006-11-17 18:27:38 +04:00
+++ 1.14/mysql-test/include/deadlock.inc	2006-11-17 18:27:38 +04:00
@@ -1,6 +1,18 @@
--- source include/have_innodb.inc
+# include/deadlock.inc
+#
+# The variable
+#     $engine_type       -- storage engine to be tested
+# has to be set before sourcing this script.
+#
+# Last update:
+# 2006-07-26 ML refactoring + print when connection is switched
+#               old name was t/innodb-deadlock.test
+#               main code went into include/deadlock.inc
+#
 
+--echo # Establish connection con1 (user=root)
 connect (con1,localhost,root,,);
+--echo # Establish connection con2 (user=root)
 connect (con2,localhost,root,,);
 
 --disable_warnings
@@ -11,29 +23,34 @@ drop table if exists t1,t2;
 # Testing of FOR UPDATE
 #
 
+--echo # Switch to connection con1
 connection con1;
-create table t1 (id integer, x integer) engine=INNODB;
+eval create table t1 (id integer, x integer) engine = $engine_type;
 insert into t1 values(0, 0);
 set autocommit=0;
 SELECT * from t1 where id = 0 FOR UPDATE;
 
+--echo # Switch to connection con2
 connection con2;
 set autocommit=0;
 
-# The following query should hang because con1 is locking the page
+# The following query should hang because con1 is locking the record
 --send
 update t1 set x=2 where id = 0;
 --sleep 2
 
+--echo # Switch to connection con1
 connection con1;
 update t1 set x=1 where id = 0;
 select * from t1;
 commit;
 
+--echo # Switch to connection con2
 connection con2;
 reap;
 commit;
 
+--echo # Switch to connection con1
 connection con1;
 select * from t1;
 commit;
@@ -43,9 +60,10 @@ drop table t1;
 # Testing of FOR UPDATE
 #
 
+--echo # Switch to connection con1
 connection con1;
-create table t1 (id integer, x integer) engine=INNODB;
-create table t2 (b integer, a integer) engine=INNODB;
+eval create table t1 (id integer, x integer) engine = $engine_type;
+eval create table t2 (b integer, a integer) engine = $engine_type;
 insert into t1 values(0, 0), (300, 300);
 insert into t2 values(0, 10), (1, 20), (2, 30);
 commit;
@@ -55,61 +73,75 @@ update t2 set a=100 where b=(SELECT x fr
 select * from t2;
 select * from t1;
 
+--echo # Switch to connection con2
 connection con2;
 set autocommit=0;
 
-# The following query should hang because con1 is locking the page
+# The following query should hang because con1 is locking the record
 --send
 update t1 set x=2 where id = 0;
 --sleep 2
 
+--echo # Switch to connection con1
 connection con1;
 update t1 set x=1 where id = 0;
 select * from t1;
 commit;
 
+--echo # Switch to connection con2
 connection con2;
 reap;
 commit;
 
+--echo # Switch to connection con1
 connection con1;
 select * from t1;
 commit;
 
 drop table t1, t2;
-create table t1 (id integer, x integer) engine=INNODB;
-create table t2 (b integer, a integer) engine=INNODB;
+eval create table t1 (id integer, x integer) engine = $engine_type;
+eval create table t2 (b integer, a integer) engine = $engine_type;
 insert into t1 values(0, 0), (300, 300);
 insert into t2 values(0, 0), (1, 20), (2, 30);
 commit;
 
+--echo # Switch to connection con1
 connection con1;
 select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
 select * from t2;
 select * from t1;
 
+--echo # Switch to connection con2
 connection con2;
 
-# The following query should hang because con1 is locking the page
+# The following query should hang because con1 is locking the record
 update t2 set a=2 where b = 0;
 select * from t2;
 --send
 update t1 set x=2 where id = 0;
 --sleep 2
 
+--echo # Switch to connection con1
 connection con1;
 update t1 set x=1 where id = 0;
 select * from t1;
 commit;
 
+--echo # Switch to connection con2
 connection con2;
 reap;
 commit;
 
+--echo # Switch to connection con1
 connection con1;
 select * from t1;
 commit;
 
+# Cleanup
+--echo # Switch to connection default + disconnect con1 and con2
+connection default;
+disconnect con1;
+disconnect con2;
 drop table t1, t2;
 
 # End of 4.1 tests

--- 1.33/sql/protocol.h	2006-11-17 18:27:38 +04:00
+++ 1.34/sql/protocol.h	2006-11-17 18:27:38 +04:00
@@ -166,7 +166,6 @@ void send_ok(THD *thd, ha_rows affected_
 	     const char *info=0);
 void send_eof(THD *thd);
 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);

--- 1.122/libmysqld/lib_sql.cc	2006-11-17 18:27:38 +04:00
+++ 1.123/libmysqld/lib_sql.cc	2006-11-17 18:27:38 +04:00
@@ -100,6 +100,7 @@ emb_advanced_command(MYSQL *mysql, enum 
   mysql->affected_rows= ~(my_ulonglong) 0;
   mysql->field_count= 0;
   net->last_errno= 0;
+  thd->current_stmt= stmt;
 
   thd->store_globals();				// Fix if more than one connect
   /* 

--- 1.246/client/mysqltest.c	2006-11-17 18:27:38 +04:00
+++ 1.247/client/mysqltest.c	2006-11-17 18:27:38 +04:00
@@ -29,6 +29,7 @@
   Matt Wagner  <matt@stripped>
   Monty
   Jani
+  Holyfoot
 */
 
 #define MTEST_VERSION "3.0"
@@ -220,6 +221,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;
@@ -458,7 +465,6 @@ void mysql_disable_rpl_parse(MYSQL* mysq
 int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; }
 my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
 #endif
-
 void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
                                int len);
 void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
@@ -470,6 +476,56 @@ void handle_error(struct st_command*,
 void handle_no_error(struct st_command*);
 
 
+#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 st_connection *cn= (struct st_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 st_connection *cn, const char *q, int q_len,
+                         int flags)
+{
+  pthread_t tid;
+
+  if (flags & QUERY_REAP_FLAG)
+    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*/
 
 void do_eval(DYNAMIC_STRING *query_eval, const char *query,
              const char *query_end, my_bool pass_through_escape_chars)
@@ -4498,7 +4554,6 @@ int append_warnings(DYNAMIC_STRING *ds, 
 }
 
 
-
 /*
   Run query using MySQL C API
 
@@ -4515,10 +4570,11 @@ int append_warnings(DYNAMIC_STRING *ds, 
   error - function will not return
 */
 
-void run_query_normal(MYSQL *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)
 {
+  MYSQL *mysql= &cn->mysql;
   MYSQL_RES *res= 0;
   int err= 0, counter= 0;
   DBUG_ENTER("run_query_normal");
@@ -4530,14 +4586,26 @@ void run_query_normal(MYSQL *mysql, stru
     /*
       Send the query
     */
-    if (mysql_send_query(mysql, query, query_len))
+    if (do_send_query(cn, query, query_len, flags))
     {
       handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 		   mysql_sqlstate(mysql), ds);
       goto end;
     }
   }
-
+#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_FLAG)
+  {
+    pthread_mutex_lock(&cn->mutex);
+    while (!cn->query_done)
+      pthread_cond_wait(&cn->cond, &cn->mutex);
+    pthread_mutex_unlock(&cn->mutex);
+  }
+#endif /*EMBEDDED_LIBRARY*/
   if (!(flags & QUERY_REAP_FLAG))
     DBUG_VOID_RETURN;
 
@@ -5028,8 +5096,9 @@ int util_query(MYSQL* org_mysql, const c
 
 */
 
-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;
@@ -5186,7 +5255,7 @@ void run_query(MYSQL *mysql, struct st_c
       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)
@@ -5651,7 +5720,7 @@ int main(int argc, char **argv)
 	  strmake(command->require_file, save_file, sizeof(save_file));
 	  save_file[0]= 0;
 	}
-	run_query(&cur_con->mysql, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG);
+	run_query(cur_con, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG);
 	display_result_vertically= old_display_result_vertically;
         command->last_argument= command->end;
         command_executed++;
@@ -5682,7 +5751,7 @@ int main(int argc, char **argv)
 	  strmake(command->require_file, save_file, sizeof(save_file));
 	  save_file[0]= 0;
 	}
-	run_query(&cur_con->mysql, command, flags);
+	run_query(cur_con, command, flags);
 	command_executed++;
         command->last_argument= command->end;
 	break;
@@ -5708,7 +5777,7 @@ int main(int argc, char **argv)
           the query and read the result some time later when reap instruction
 	  is given on this connection.
         */
-	run_query(&cur_con->mysql, command, QUERY_SEND_FLAG);
+	run_query(cur_con, command, QUERY_SEND_FLAG);
 	command_executed++;
         command->last_argument= command->end;
 	break;

--- 1.17/mysql-test/t/status.test	2006-11-17 18:27:38 +04:00
+++ 1.18/mysql-test/t/status.test	2006-11-17 18:27:38 +04:00
@@ -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
 
Thread
bk commit into 5.1 tree (holyfoot:1.2367)holyfoot17 Nov