diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 3d4b79ea78dfee69deefc6cad5277d0c6027a4b3..f2572321d613c71dda29d3f6083916f14a89162f 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -68,6 +68,12 @@ t2	c	1
 t2	d	1
 t2	e	1
 t2	f	1
+(select a,b from t1 limit 2)  union all (select a,b from t2 order by a) limit 4;
+a	b
+1	a
+2	b
+3	c
+4	d
 explain select a,b from t1 union all select a,b from t2;
 table	type	possible_keys	key	key_len	ref	rows	Extra
 t1	ALL	NULL	NULL	NULL	NULL	4	
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 5c4a62d5c41fd62ef64acb4ba6c6af08ad6c894d..dc7e036e258297c6bf05f7368889b9c317a43aec 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -16,6 +16,9 @@ select 0,'#' union select a,b from t1 union all select a,b from t2 union select
 select a,b from t1 union select a,b from t1;
 select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 group by b;
 
+#test alternate syntax for unions 
+(select a,b from t1 limit 2)  union all (select a,b from t2 order by a) limit 4;
+
 # Test some error conditions with UNION
 explain select a,b from t1 union all select a,b from t2;
 
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index b8d4f00533e56429587ccd8da66fe629dd616b59..a712d4ca54c49e92d78b926c08912ac5bad7e241 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -455,11 +455,13 @@ int multi_delete::do_deletes (bool from_send_error)
 bool multi_delete::send_eof()
 {
   thd->proc_info="deleting from reference tables";  /* out: 1 if error, 0 if success */
+
+  /* Does deletes for the last n - 1 tables, returns 0 if ok */
   int error = do_deletes(false);   /* do_deletes returns 0 if success */
 
   /* reset used flags */
   delete_tables->table->no_keyread=0;
-
+  if (error == -1) error = 0;
   thd->proc_info="end";
   if (error)
   {
@@ -485,12 +487,10 @@ bool multi_delete::send_eof()
 	!some_table_is_not_transaction_safe(delete_tables))
       error=1;  /* Log write failed: roll back
 		   the SQL statement */
-    if (deleted) 
-    {
-      /* If autocommit is on we do a commit, in an error case we
-	 roll back the current SQL statement */
-      VOID(ha_autocommit_or_rollback(thd, error != 0));
-    }
+
+    /* Commit or rollback the current SQL statement */ 
+
+    VOID(ha_autocommit_or_rollback(thd,error > 0));
   }
 
   ::send_ok(&thd->net,deleted);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8d1835c7b90f7e898582941680ff92675e0fbd4d..f8bc02c9f19484aaad41883c81822f5ba6f458a9 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2406,6 +2406,7 @@ mysql_init_query(THD *thd)
   thd->fatal_error=0;				// Safety
   thd->last_insert_id_used=thd->query_start_used=thd->insert_id_used=0;
   thd->sent_row_count=thd->examined_row_count=0;
+  thd->lex.sql_command=SQLCOM_SELECT;
   DBUG_VOID_RETURN;
 }
 
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 0d8a6dc4ed1107953004b7436bbcd7d3f5a95118..a6ea88d9adc2df3f4d6f286f8b6216a7640081be 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -27,7 +27,7 @@
 
 int mysql_union(THD *thd, LEX *lex,select_result *result)
 {
-  SELECT_LEX *sl, *last_sl, lex_sl;
+  SELECT_LEX *sl, *last_sl=(SELECT_LEX *)NULL, lex_sl;
   ORDER *order;
   List<Item> item_list;
   TABLE *table;
@@ -38,7 +38,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
   DBUG_ENTER("mysql_union");
 
   /* Fix tables 'to-be-unioned-from' list to point at opened tables */
-  for (sl=&lex->select_lex; sl && sl->linkage != NOT_A_SELECT; sl=sl->next)
+  for (sl=&lex->select_lex; sl && sl->linkage != NOT_A_SELECT; last_sl=sl, sl=sl->next)
   {
     for (TABLE_LIST *cursor= (TABLE_LIST *)sl->table_list.first;
 	 cursor;
@@ -50,6 +50,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
   {
     lex_sl=*sl;
     sl=(SELECT_LEX *)NULL;
+    if (last_sl) last_sl->next=sl;
   }
   else
     lex_sl.linkage=UNSPECIFIED_TYPE;
@@ -68,7 +69,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
 		       sl->item_list,
 		       sl->where,
 		       sl->ftfunc_list,
-		       (sl->braces) ? (ORDER*) 0 : (ORDER *) sl->order_list.first,
+		       (sl->braces) ? (ORDER *) sl->order_list.first : (ORDER *) 0,
 		       (ORDER*) sl->group_list.first,
 		       sl->having,
 		       (ORDER*) NULL,
@@ -79,7 +80,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
     DBUG_RETURN(0);
   }
 
-  order = (lex_sl.linkage == UNSPECIFIED_TYPE) ? (ORDER *) last_sl->order_list.first : (ORDER *) lex_sl.order_list.first;
+  order = (lex_sl.linkage == UNSPECIFIED_TYPE) ? ( (last_sl->braces) ? (ORDER *) 0 :  (ORDER *) last_sl->order_list.first) : (ORDER *) lex_sl.order_list.first;
 
   {
     Item *item;
@@ -127,7 +128,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result)
 		     sl->item_list,
 		     sl->where,
 		     sl->ftfunc_list,
-		     (sl->braces) ? (ORDER*) 0 : (ORDER *)sl->order_list.first,
+		     (sl->braces) ? (ORDER *)sl->order_list.first : (ORDER *) 0,
 		     (ORDER*) sl->group_list.first,
 		     sl->having,
 		     (ORDER*) NULL,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 4174e6ba34502d37be900f538a4979e4b1debaa8..cc79ef3e7cd6ad1fe672d434784124f58da26a0b 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1335,18 +1335,9 @@ table_to_table:
 
 
 select:
-	SELECT_SYM
-	{
-	  Lex->sql_command= SQLCOM_SELECT;
-	}
-	select_part2;
-        |
-	'(' SELECT_SYM
-	{
-	  Lex->sql_command= SQLCOM_SELECT;
-	}
-	select_part3;
-
+	SELECT_SYM select_part2  {Select->braces=false;} union
+	|
+	'(' SELECT_SYM 	select_part2 ')' {Select->braces=true;} union_opt
 
 select_part2:
 	{
@@ -1354,16 +1345,7 @@ select_part2:
 	  lex->lock_option=TL_READ;
 	   mysql_init_select(lex);
 	}
-	select_options select_item_list select_into select_lock_type union
-
-select_part3:
-	{
-	  LEX *lex=Lex;
-	  lex->lock_option=TL_READ;
-	   mysql_init_select(lex);
-	   Select->braces = true;
-	}
-	select_options select_item_list select_into select_lock_type ')' union
+	select_options select_item_list select_into select_lock_type
 
 select_into:
 	limit_clause {}
@@ -3496,11 +3478,7 @@ rollback:
 
 
 union:	
-  /* empty */ 
-  {
-    if (Lex->select->braces || Select->linkage == NOT_A_SELECT) 
-      YYABORT;
-  }
+  /* empty */ {}
   | union_list
 
 union_list:
@@ -3513,20 +3491,29 @@ union_list:
        net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO");
        YYABORT;
     } 
+    if (lex->select->linkage==NOT_A_SELECT)
+      YYABORT;
     mysql_new_select(lex);
     lex->select->linkage=UNION_TYPE;
   } 
-  SELECT_SYM select_part2
-  | '(' SELECT_SYM select_part3 optional_order_or_limit
+  select
+
+union_opt:
+  union {}
+  |  optional_order_or_limit {}
 
 optional_order_or_limit:
   /* emty */ {}
   |
   {
-    mysql_new_select(Lex);
-    Lex->select->linkage=NOT_A_SELECT;
+    LEX *lex=Lex;
+    if (!lex->select->braces)
+      YYABORT;
+    mysql_new_select(lex);
+    mysql_init_select(lex);
+    lex->select->linkage=NOT_A_SELECT;
   }
-  order_clause limit_clause
+  opt_order_clause limit_clause
 
 union_option:
   /* empty */ {}