mirror of
https://github.com/MariaDB/server.git
synced 2025-01-30 10:31:54 +01:00
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
This commit is contained in:
parent
23cb2a95f9
commit
ef6f91458d
2 changed files with 46 additions and 13 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
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,
|
||||||
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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue