From 0299df4b4f7d62197b0e490d65b94a47661cdeef Mon Sep 17 00:00:00 2001
From: unknown <heikki@hundin.mysql.fi>
Date: Wed, 7 May 2003 19:01:45 +0300
Subject: [PATCH] sql_select.cc, opt_sum.cc:   Fix bug: if MIN() or MAX()
 resulted in a deadlock or a lock wait timeout, MySQL did not return an error,
 but NULL as the function value

sql/opt_sum.cc:
  Fix bug: if MIN() or MAX() resulted in a deadlock or a lock wait timeout, MySQL did not return an error, but NULL as the function value
sql/sql_select.cc:
  Fix bug: if MIN() or MAX() resulted in a deadlock or a lock wait timeout, MySQL did not return an error, but NULL as the function value
---
 sql/opt_sum.cc    | 50 +++++++++++++++++++++++++++++++++++------------
 sql/sql_select.cc |  9 +++++++++
 2 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc
index 21296845c21..855813f1140 100644
--- a/sql/opt_sum.cc
+++ b/sql/opt_sum.cc
@@ -37,8 +37,10 @@ static bool find_range_key(TABLE_REF *ref, Field* field,COND *cond);
 
  RETURN VALUES
     0 No errors
-    1 if all items was resolved
-   -1 on impossible  conditions
+    1 if all items were resolved
+   -1 on impossible conditions
+    OR an error number from my_base.h HA_ERR_... if a deadlock or a lock
+       wait timeout happens, for example
 */
 
 int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
@@ -50,6 +52,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
   table_map where_tables= 0;
   Item *item;
   COND *org_conds= conds;
+  int error;
 
   if (conds)
     where_tables= conds->used_tables();
@@ -136,7 +139,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
 	    const_result=0;
 	    break;
 	  }
-	  bool error= table->file->index_init((uint) ref.key);
+	  error= table->file->index_init((uint) ref.key);
 	  enum ha_rkey_function find_flag= HA_READ_KEY_OR_NEXT; 
 	  uint prefix_len= ref.key_length;
 	  /*
@@ -150,12 +153,17 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
 	  }
 
 	  if (!ref.key_length)
-	    error=table->file->index_first(table->record[0]) !=0;
+	  {
+	    error=table->file->index_first(table->record[0]);
+	  }
 	  else
+	  {
 	    error=table->file->index_read(table->record[0],key_buff,
 					  ref.key_length,
-					  find_flag) ||
-	      key_cmp(table, key_buff, ref.key, prefix_len);
+					  find_flag);
+	    if (!error && key_cmp(table, key_buff, ref.key, prefix_len))
+	      error = HA_ERR_KEY_NOT_FOUND;
+	  }
 	  if (table->key_read)
 	  {
 	    table->key_read=0;
@@ -163,7 +171,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
 	  }
 	  table->file->index_end();
 	  if (error)
-	    return -1;				// No rows matching where
+          {
+	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
+	      return -1;		       // No rows matching WHERE
+
+	    table->file->print_error(error, MYF(0));
+            return(error);                     // HA_ERR_LOCK_DEADLOCK or
+					       // some other error
+	  }
 	  removed_tables|= table->map;
 	}
 	else if (!expr->const_item())		// This is VERY seldom false
@@ -202,16 +217,19 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
 	    const_result=0;
 	    break;
 	  }
-	  bool error=table->file->index_init((uint) ref.key);
+	  error=table->file->index_init((uint) ref.key);
 
 	  if (!ref.key_length)
-	    error=table->file->index_last(table->record[0]) !=0;
+	  {
+	    error=table->file->index_last(table->record[0]);
+	  }
 	  else
 	  {
-	    error = table->file->index_read(table->record[0], key_buff,
+	    error=table->file->index_read(table->record[0], key_buff,
 					  ref.key_length,
-					  HA_READ_PREFIX_LAST) ||
-	      key_cmp(table,key_buff,ref.key,ref.key_length);
+					  HA_READ_PREFIX_LAST);
+	    if (!error && key_cmp(table,key_buff,ref.key,ref.key_length))
+	      error = HA_ERR_KEY_NOT_FOUND;
 	  }
 	  if (table->key_read)
 	  {
@@ -220,7 +238,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
 	  }
 	  table->file->index_end();
 	  if (error)
-	    return -1;				// Impossible query
+	  {
+	    if (error == HA_ERR_KEY_NOT_FOUND || error == HA_ERR_END_OF_FILE)
+	      return -1;			// Impossible query
+
+	    table->file->print_error(error, MYF(0));
+	    return error;		        // Deadlock or some other error
+	  }
 	  removed_tables|= table->map;
 	}
 	else if (!expr->const_item())		// This is VERY seldom false
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 79ba13a3339..daf388c9ff3 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -391,8 +391,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds,
   if (tables && join.tmp_table_param.sum_func_count && ! group)
   {
     int res;
+    /*
+    opt_sum_query returns -1 if no rows match to the WHERE conditions,
+    or 1 if all items were resolved, or 0, or an error number HA_ERR_...
+    */
     if ((res=opt_sum_query(tables, all_fields, conds)))
     {
+      if (res > 1)
+      {
+	delete procedure;
+	DBUG_RETURN(-1);
+      }
       if (res < 0)
       {
 	error=return_zero_rows(&join, result, tables, fields, !group,
-- 
2.30.9