summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc90
1 files changed, 77 insertions, 13 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 084688f7d3d..10215f406c3 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -38,19 +38,27 @@ longlong Item_func_not::val_int()
return !null_value && value == 0 ? 1 : 0;
}
+/*
+ Convert a constant expression or string to an integer.
+ This is done when comparing DATE's of different formats and
+ also when comparing bigint to strings (in which case the string
+ is converted once to a bigint).
+
+ RESULT VALUES
+ 0 Can't convert item
+ 1 Item was replaced with an integer version of the item
+*/
static bool convert_constant_item(Field *field, Item **item)
{
- if ((*item)->const_item())
+ if ((*item)->const_item() && (*item)->type() != Item::INT_ITEM)
{
- if ((*item)->save_in_field(field))
- return 0;
- if (!((*item)->null_value))
+ if (!(*item)->save_in_field(field) && !((*item)->null_value))
{
Item *tmp=new Item_int_with_ref(field->val_int(), *item);
if (tmp)
*item=tmp;
- return 1;
+ return 1; // Item was replaced
}
}
return 0;
@@ -59,7 +67,7 @@ static bool convert_constant_item(Field *field, Item **item)
void Item_bool_func2::fix_length_and_dec()
{
- max_length=1;
+ max_length=1; // Function returns 0 or 1
/*
As some compare functions are generated after sql_yacc,
@@ -488,6 +496,7 @@ Item_func_ifnull::val_str(String *str)
return res;
}
+
void
Item_func_if::fix_length_and_dec()
{
@@ -496,16 +505,32 @@ Item_func_if::fix_length_and_dec()
decimals=max(args[1]->decimals,args[2]->decimals);
enum Item_result arg1_type=args[1]->result_type();
enum Item_result arg2_type=args[2]->result_type();
- binary=1;
- if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
+ bool null1=args[1]->null_value;
+ bool null2=args[2]->null_value;
+
+ if (null1)
+ {
+ cached_result_type= arg2_type;
+ binary= args[2]->binary;
+ }
+ else if (null2)
+ {
+ cached_result_type= arg1_type;
+ binary= args[1]->binary;
+ }
+ else if (arg1_type == STRING_RESULT || arg2_type == STRING_RESULT)
{
cached_result_type = STRING_RESULT;
binary=args[1]->binary | args[2]->binary;
}
- else if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
- cached_result_type = REAL_RESULT;
else
- cached_result_type=arg1_type; // Should be INT_RESULT
+ {
+ binary=1; // Number
+ if (arg1_type == REAL_RESULT || arg2_type == REAL_RESULT)
+ cached_result_type = REAL_RESULT;
+ else
+ cached_result_type=arg1_type; // Should be INT_RESULT
+ }
}
@@ -551,7 +576,7 @@ Item_func_nullif::fix_length_and_dec()
}
/*
- nullif() returns NULL if arguments are different, else it returns the
+ nullif () returns NULL if arguments are different, else it returns the
first argument.
Note that we have to evaluate the first argument twice as the compare
may have been done with a different type than return value
@@ -1301,7 +1326,7 @@ bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
*last == wild_many)
{
const char* tmp = first + 1;
- for ( ; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
+ for (; *tmp != wild_many && *tmp != wild_one && *tmp != escape; tmp++) ;
canDoTurboBM = tmp == last;
}
@@ -1642,6 +1667,45 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const
}
}
+
+/*
+ Make a logical XOR of the arguments.
+
+ SYNOPSIS
+ val_int()
+
+ DESCRIPTION
+ If either operator is NULL, return NULL.
+
+ NOTE
+ As we don't do any index optimization on XOR this is not going to be
+ very fast to use.
+
+ TODO (low priority)
+ Change this to be optimized as:
+ A XOR B -> (A) == 1 AND (B) <> 1) OR (A <> 1 AND (B) == 1)
+ To be able to do this, we would however first have to extend the MySQL
+ range optimizer to handle OR better.
+*/
+
+longlong Item_cond_xor::val_int()
+{
+ List_iterator<Item> li(list);
+ Item *item;
+ int result=0;
+ null_value=0;
+ while ((item=li++))
+ {
+ result^= (item->val_int() != 0);
+ if (item->null_value)
+ {
+ null_value=1;
+ return 0;
+ }
+ }
+ return (longlong) result;
+}
+
/****************************************************************
Classes and functions for spatial relations
*****************************************************************/