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.cc124
1 files changed, 70 insertions, 54 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2175787cbd7..62ac7bc4751 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -29,7 +29,7 @@
#include <m_ctype.h>
#include "sql_select.h"
-static bool convert_constant_item(THD *thd, Field *field, Item **item);
+static bool convert_constant_item(THD *, Item_field *, Item **);
static Item_result item_store_type(Item_result a, Item *item,
my_bool unsigned_flag)
@@ -378,13 +378,15 @@ longlong Item_func_nop_all::val_int()
table that has not been populated yet.
@retval
- 0 Can't convert item
+ 0 Can't convert item
@retval
- 1 Item was replaced with an integer version of the item
+ 1 Item was replaced with an integer version of the item
*/
-static bool convert_constant_item(THD *thd, Field *field, Item **item)
+static bool convert_constant_item(THD *thd, Item_field *field_item,
+ Item **item)
{
+ Field *field= field_item->field;
int result= 0;
if (!(*item)->with_subselect && (*item)->const_item())
@@ -394,9 +396,11 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
enum_check_fields orig_count_cuted_fields= thd->count_cuted_fields;
my_bitmap_map *old_write_map;
my_bitmap_map *old_read_map;
+ ulonglong orig_field_val; /* original field value if valid */
LINT_INIT(old_write_map);
LINT_INIT(old_read_map);
+ LINT_INIT(orig_field_val);
if (table)
{
@@ -407,7 +411,14 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
thd->variables.sql_mode= (orig_sql_mode & ~MODE_NO_ZERO_DATE) |
MODE_INVALID_DATES;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
- if (!(*item)->save_in_field(field, 1) && !((*item)->null_value))
+
+ /*
+ Store the value of the field if it references an outer field because
+ the call to save_in_field below overrides that value.
+ */
+ if (field_item->depended_from)
+ orig_field_val= field->val_int();
+ if (!(*item)->is_null() && !(*item)->save_in_field(field, 1))
{
Item *tmp= new Item_int_with_ref(field->val_int(), *item,
test(field->flags & UNSIGNED_FLAG));
@@ -415,6 +426,13 @@ static bool convert_constant_item(THD *thd, Field *field, Item **item)
thd->change_item_tree(item, tmp);
result= 1; // Item was replaced
}
+ /* Restore the original field value. */
+ if (field_item->depended_from)
+ {
+ result= field->store(orig_field_val, TRUE);
+ /* orig_field_val must be a valid value that can be restored back. */
+ DBUG_ASSERT(!result);
+ }
thd->variables.sql_mode= orig_sql_mode;
thd->count_cuted_fields= orig_count_cuted_fields;
if (table)
@@ -471,15 +489,14 @@ void Item_bool_func2::fix_length_and_dec()
thd= current_thd;
if (!thd->is_context_analysis_only())
{
- Item *arg_real_item= args[0]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[0]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[1]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[1]))
+ if (convert_constant_item(thd, field_item, &args[1]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -488,15 +505,14 @@ void Item_bool_func2::fix_length_and_dec()
}
}
}
- arg_real_item= args[1]->real_item();
- if (arg_real_item->type() == FIELD_ITEM)
+ if (args[1]->real_item()->type() == FIELD_ITEM)
{
- Field *field=((Item_field*) arg_real_item)->field;
- if (field->can_be_compared_as_longlong() &&
- !(arg_real_item->is_datetime() &&
+ Item_field *field_item= (Item_field*) (args[1]->real_item());
+ if (field_item->field->can_be_compared_as_longlong() &&
+ !(field_item->is_datetime() &&
args[0]->result_type() == STRING_RESULT))
{
- if (convert_constant_item(thd, field,&args[0]))
+ if (convert_constant_item(thd, field_item, &args[0]))
{
cmp.set_cmp_func(this, tmp_arg, tmp_arg+1,
INT_RESULT); // Works for all types.
@@ -1071,11 +1087,11 @@ int Arg_comparator::compare_string()
Compare strings byte by byte. End spaces are also compared.
@retval
- <0 *a < *b
+ <0 *a < *b
@retval
- 0 *b == *b
+ 0 *b == *b
@retval
- >0 *a > *b
+ >0 *a > *b
*/
int Arg_comparator::compare_binary_string()
@@ -1967,16 +1983,16 @@ void Item_func_between::fix_length_and_dec()
thd->lex->sql_command != SQLCOM_CREATE_VIEW &&
thd->lex->sql_command != SQLCOM_SHOW_CREATE)
{
- Field *field=((Item_field*) (args[0]->real_item()))->field;
- if (field->can_be_compared_as_longlong())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong())
{
/*
The following can't be recoded with || as convert_constant_item
changes the argument
*/
- if (convert_constant_item(thd, field,&args[1]))
+ if (convert_constant_item(thd, field_item, &args[1]))
cmp_type=INT_RESULT; // Works for all types.
- if (convert_constant_item(thd, field,&args[2]))
+ if (convert_constant_item(thd, field_item, &args[2]))
cmp_type=INT_RESULT; // Works for all types.
}
}
@@ -3609,13 +3625,13 @@ void Item_func_in::fix_length_and_dec()
thd->lex->sql_command != SQLCOM_SHOW_CREATE &&
cmp_type != INT_RESULT)
{
- Field *field= ((Item_field*) (args[0]->real_item()))->field;
- if (field->can_be_compared_as_longlong())
+ Item_field *field_item= (Item_field*) (args[0]->real_item());
+ if (field_item->field->can_be_compared_as_longlong())
{
bool all_converted= TRUE;
for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if (!convert_constant_item (thd, field, &arg[0]))
+ if (!convert_constant_item (thd, field_item, &arg[0]))
all_converted= FALSE;
}
if (all_converted)
@@ -3907,20 +3923,20 @@ bool Item_cond::walk(Item_processor processor, bool walk_subquery, uchar *arg)
/**
Transform an Item_cond object with a transformer callback function.
-
+
The function recursively applies the transform method to each
- member item of the condition list.
+ member item of the condition list.
If the call of the method for a member item returns a new item
the old item is substituted for a new one.
After this the transformer is applied to the root node
- of the Item_cond object.
-
+ of the Item_cond object.
+
@param transformer the transformer callback function to be applied to
the nodes of the tree of the object
@param arg parameter to be passed to the transformer
@return
- Item returned as the result of transformation of the root node
+ Item returned as the result of transformation of the root node
*/
Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
@@ -3951,7 +3967,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
/**
Compile Item_cond object with a processor and a transformer
callback functions.
-
+
First the function applies the analyzer to the root node of
the Item_func object. Then if the analyzer succeeeds (returns TRUE)
the function recursively applies the compile method to member
@@ -3960,7 +3976,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
the old item is substituted for a new one.
After this the transformer is applied to the root node
of the Item_cond object.
-
+
@param analyzer the analyzer callback function to be applied to the
nodes of the tree of the object
@param[in,out] arg_p parameter to be passed to the analyzer
@@ -3969,7 +3985,7 @@ Item *Item_cond::transform(Item_transformer transformer, uchar *arg)
@param arg_t parameter to be passed to the transformer
@return
- Item returned as the result of transformation of the root node
+ Item returned as the result of transformation of the root node
*/
Item *Item_cond::compile(Item_analyzer analyzer, uchar **arg_p,
@@ -4117,7 +4133,7 @@ void Item_cond::neg_arguments(THD *thd)
1 If all expressions are true
@retval
0 If all expressions are false or if we find a NULL expression and
- 'abort_on_null' is set.
+ 'abort_on_null' is set.
@retval
NULL if all expression are either 1 or NULL
*/
@@ -4166,8 +4182,8 @@ longlong Item_cond_or::val_int()
@param a expression or NULL
@param b expression.
@param org_item Don't modify a if a == *org_item.
- If a == NULL, org_item is set to point at b,
- to ensure that future calls will not modify b.
+ If a == NULL, org_item is set to point at b,
+ to ensure that future calls will not modify b.
@note
This will not modify item pointed to by org_item or b
@@ -4685,7 +4701,7 @@ void Item_func_like::turboBM_compute_good_suffix_shifts(int *suff)
/**
- Precomputation dependent on pattern_len.
+ Precomputation dependent on pattern_len.
*/
void Item_func_like::turboBM_compute_bad_character_shifts()
@@ -5043,7 +5059,7 @@ uint Item_equal::members()
@retval
1 if nultiple equality contains a reference to field
@retval
- 0 otherwise
+ 0 otherwise
*/
bool Item_equal::contains(Field *field)
@@ -5061,7 +5077,7 @@ bool Item_equal::contains(Field *field)
/**
Join members of another Item_equal object.
-
+
The function actually merges two multiple equalities.
After this operation the Item_equal object additionally contains
the field items of another item of the type Item_equal.
@@ -5090,15 +5106,15 @@ void Item_equal::merge(Item_equal *item)
/**
Order field items in multiple equality according to a sorting criteria.
- The function perform ordering of the field items in the Item_equal
- object according to the criteria determined by the cmp callback parameter.
- If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
- placed after item_fiel2.
+ The function perform ordering of the field items in the Item_equal
+ object according to the criteria determined by the cmp callback parameter.
+ If cmp(item_field1,item_field2,arg)<0 than item_field1 must be
+ placed after item_fiel2.
- The function sorts field items by the exchange sort algorithm.
- The list of field items is looked through and whenever two neighboring
- members follow in a wrong order they are swapped. This is performed
- again and again until we get all members in a right order.
+ The function sorts field items by the exchange sort algorithm.
+ The list of field items is looked through and whenever two neighboring
+ members follow in a wrong order they are swapped. This is performed
+ again and again until we get all members in a right order.
@param cmp function to compare field item
@param arg context extra parameter for the cmp function
@@ -5139,11 +5155,11 @@ void Item_equal::sort(Item_field_cmpfunc cmp, void *arg)
/**
Check appearance of new constant items in the multiple equality object.
- The function checks appearance of new constant items among
- the members of multiple equalities. Each new constant item is
- compared with the designated constant item if there is any in the
- multiple equality. If there is none the first new constant item
- becomes designated.
+ The function checks appearance of new constant items among
+ the members of multiple equalities. Each new constant item is
+ compared with the designated constant item if there is any in the
+ multiple equality. If there is none the first new constant item
+ becomes designated.
*/
void Item_equal::update_const()