diff options
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 31 |
1 files changed, 26 insertions, 5 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index d430d0d3c23..9443a2949d8 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -614,19 +614,38 @@ int Arg_comparator::compare_e_int_diff_signedness() int Arg_comparator::compare_row() { int res= 0; + bool was_null= 0; (*a)->bring_value(); (*b)->bring_value(); uint n= (*a)->cols(); for (uint i= 0; i<n; i++) { - if ((res= comparators[i].compare())) - return res; + res= comparators[i].compare(); if (owner->null_value) - return -1; + { + // NULL was compared + if (owner->abort_on_null) + return -1; // We do not need correct NULL returning + was_null= 1; + owner->null_value= 0; + res= 0; // continue comparison (maybe we will meet explicit difference) + } + else if (res) + return res; } - return res; + if (was_null) + { + /* + There was NULL(s) in comparison in some parts, but there was not + explicit difference in other parts, so we have to return NULL + */ + owner->null_value= 1; + return -1; + } + return 0; } + int Arg_comparator::compare_e_row() { (*a)->bring_value(); @@ -1903,6 +1922,8 @@ in_row::~in_row() byte *in_row::get_value(Item *item) { tmp.store_value(item); + if (item->is_null()) + return 0; return (byte *)&tmp; } @@ -2791,7 +2812,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) /* If we are on execution stage */ String *escape_str= escape_item->val_str(&tmp_value1); escape= escape_str ? *(escape_str->ptr()) : '\\'; - + /* We could also do boyer-more for non-const items, but as we would have to recompute the tables for each row it's not worth it. |