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
parent 23cb2a95
...@@ -37,8 +37,10 @@ static bool find_range_key(TABLE_REF *ref, Field* field,COND *cond); ...@@ -37,8 +37,10 @@ static bool find_range_key(TABLE_REF *ref, Field* field,COND *cond);
RETURN VALUES RETURN VALUES
0 No errors 0 No errors
1 if all items was resolved 1 if all items were resolved
-1 on impossible conditions -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) 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) ...@@ -50,6 +52,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
table_map where_tables= 0; table_map where_tables= 0;
Item *item; Item *item;
COND *org_conds= conds; COND *org_conds= conds;
int error;
if (conds) if (conds)
where_tables= conds->used_tables(); where_tables= conds->used_tables();
...@@ -136,7 +139,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -136,7 +139,7 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result=0; const_result=0;
break; 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; enum ha_rkey_function find_flag= HA_READ_KEY_OR_NEXT;
uint prefix_len= ref.key_length; uint prefix_len= ref.key_length;
/* /*
...@@ -150,12 +153,17 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -150,12 +153,17 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
} }
if (!ref.key_length) if (!ref.key_length)
error=table->file->index_first(table->record[0]) !=0; {
error=table->file->index_first(table->record[0]);
}
else else
{
error=table->file->index_read(table->record[0],key_buff, error=table->file->index_read(table->record[0],key_buff,
ref.key_length, ref.key_length,
find_flag) || find_flag);
key_cmp(table, key_buff, ref.key, prefix_len); if (!error && key_cmp(table, key_buff, ref.key, prefix_len))
error = HA_ERR_KEY_NOT_FOUND;
}
if (table->key_read) if (table->key_read)
{ {
table->key_read=0; table->key_read=0;
...@@ -163,7 +171,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -163,7 +171,14 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
} }
table->file->index_end(); table->file->index_end();
if (error) 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; removed_tables|= table->map;
} }
else if (!expr->const_item()) // This is VERY seldom false 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) ...@@ -202,16 +217,19 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
const_result=0; const_result=0;
break; break;
} }
bool error=table->file->index_init((uint) ref.key); error=table->file->index_init((uint) ref.key);
if (!ref.key_length) if (!ref.key_length)
error=table->file->index_last(table->record[0]) !=0; {
error=table->file->index_last(table->record[0]);
}
else else
{ {
error = table->file->index_read(table->record[0], key_buff, error=table->file->index_read(table->record[0], key_buff,
ref.key_length, ref.key_length,
HA_READ_PREFIX_LAST) || HA_READ_PREFIX_LAST);
key_cmp(table,key_buff,ref.key,ref.key_length); if (!error && key_cmp(table,key_buff,ref.key,ref.key_length))
error = HA_ERR_KEY_NOT_FOUND;
} }
if (table->key_read) if (table->key_read)
{ {
...@@ -220,7 +238,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -220,7 +238,13 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
} }
table->file->index_end(); table->file->index_end();
if (error) 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; removed_tables|= table->map;
} }
else if (!expr->const_item()) // This is VERY seldom false else if (!expr->const_item()) // This is VERY seldom false
......
...@@ -391,8 +391,17 @@ mysql_select(THD *thd,TABLE_LIST *tables,List<Item> &fields,COND *conds, ...@@ -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) if (tables && join.tmp_table_param.sum_func_count && ! group)
{ {
int res; 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=opt_sum_query(tables, all_fields, conds)))
{ {
if (res > 1)
{
delete procedure;
DBUG_RETURN(-1);
}
if (res < 0) if (res < 0)
{ {
error=return_zero_rows(&join, result, tables, fields, !group, error=return_zero_rows(&join, result, tables, fields, !group,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment