mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed that NULL and 0 returns 0 instead of NULL
This is coded to not cause a speed impact on top level AND expressions where we don't care if an AND expression returns 0 or NULL mysql-test/r/bdb.result: Fix results after serges last patch mysql-test/r/innodb.result: Fix results after serges last patch mysql-test/r/null.result: Update for new AND handling of NULL scripts/mysqld_safe.sh: Fix 'isroot' test to work even if user is not root sql/item.h: Fixed that NULL and 0 returns 0 instead of NULL sql/item_cmpfunc.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/item_cmpfunc.h: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_base.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_parse.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_select.cc: Fixed that NULL and 0 returns 0 instead of NULL sql/sql_yacc.yy: Fixed that NULL and 0 returns 0 instead of NULL
This commit is contained in:
@ -26,8 +26,8 @@
|
||||
|
||||
/*
|
||||
Test functions
|
||||
These returns 0LL if false and 1LL if true and null if some arg is null
|
||||
'AND' and 'OR' never return null
|
||||
Most of these returns 0LL if false and 1LL if true and
|
||||
NULL if some arg is NULL.
|
||||
*/
|
||||
|
||||
longlong Item_func_not::val_int()
|
||||
@ -533,6 +533,7 @@ Item_func_if::fix_length_and_dec()
|
||||
else
|
||||
cached_result_type=arg1_type; // Should be INT_RESULT
|
||||
}
|
||||
args[0]->top_level_item();
|
||||
}
|
||||
|
||||
|
||||
@ -1128,6 +1129,8 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
|
||||
const_item_cache&=item->const_item();
|
||||
if (item->maybe_null)
|
||||
maybe_null=1;
|
||||
if (abort_on_null)
|
||||
item->top_level_item();
|
||||
}
|
||||
if (thd)
|
||||
thd->cond_count+=list.elements;
|
||||
@ -1196,28 +1199,41 @@ void Item_cond::print(String *str)
|
||||
str->append(')');
|
||||
}
|
||||
|
||||
/*
|
||||
Evalution of AND(expr, expr, expr ...)
|
||||
|
||||
NOTES:
|
||||
abort_if_null is set for AND expressions for which we don't care if the
|
||||
result is NULL or 0. This is set for:
|
||||
- WHERE clause
|
||||
- HAVING clause
|
||||
- IF(expression)
|
||||
|
||||
RETURN VALUES
|
||||
1 If all expressions are true
|
||||
0 If all expressions are false or if we find a NULL expression and
|
||||
'abort_on_null' is set.
|
||||
NULL if all expression are either 1 or NULL
|
||||
*/
|
||||
|
||||
|
||||
longlong Item_cond_and::val_int()
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
Item *item;
|
||||
null_value= 0;
|
||||
while ((item=li++))
|
||||
{
|
||||
if (item->val_int() == 0)
|
||||
{
|
||||
/*
|
||||
TODO: In case of NULL, ANSI would require us to continue evaluation
|
||||
until we get a FALSE value or run out of values; This would
|
||||
require a lot of unnecessary evaluation, which we skip for now
|
||||
*/
|
||||
null_value=item->null_value;
|
||||
return 0;
|
||||
if (abort_on_null || !(null_value= item->null_value))
|
||||
return 0; // return FALSE
|
||||
}
|
||||
}
|
||||
null_value=0;
|
||||
return 1;
|
||||
return null_value ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
longlong Item_cond_or::val_int()
|
||||
{
|
||||
List_iterator_fast<Item> li(list);
|
||||
@ -1260,15 +1276,15 @@ longlong Item_cond_or::val_int()
|
||||
Item *and_expressions(Item *a, Item *b, Item **org_item)
|
||||
{
|
||||
if (!a)
|
||||
return (*org_item= (Item*) b);
|
||||
return (*org_item= b);
|
||||
if (a == *org_item)
|
||||
{
|
||||
Item_cond *res;
|
||||
if ((res= new Item_cond_and(a, (Item*) b)))
|
||||
if ((res= new Item_cond_and(a, b)))
|
||||
res->used_tables_cache= a->used_tables() | b->used_tables();
|
||||
return res;
|
||||
}
|
||||
if (((Item_cond_and*) a)->add((Item*) b))
|
||||
if (((Item_cond_and*) a)->add(b))
|
||||
return 0;
|
||||
((Item_cond_and*) a)->used_tables_cache|= b->used_tables();
|
||||
return a;
|
||||
|
Reference in New Issue
Block a user