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.cc34
1 files changed, 30 insertions, 4 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index c0d3b14b71b..325e4ac219e 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2901,11 +2901,35 @@ void Item_func_case::agg_num_lengths(Item *arg)
}
+/**
+ Check if (*place) and new_value points to different Items and call
+ THD::change_item_tree() if needed.
+
+ This function is a workaround for implementation deficiency in
+ Item_func_case. The problem there is that the 'args' attribute contains
+ Items from different expressions.
+
+ The function must not be used elsewhere and will be remove eventually.
+*/
+
+static void change_item_tree_if_needed(THD *thd,
+ Item **place,
+ Item *new_value)
+{
+ if (*place == new_value)
+ return;
+
+ thd->change_item_tree(place, new_value);
+}
+
+
void Item_func_case::fix_length_and_dec()
{
Item **agg;
uint nagg;
uint found_types= 0;
+ THD *thd= current_thd;
+
if (!(agg= (Item**) sql_alloc(sizeof(Item*)*(ncases+1))))
return;
@@ -2930,9 +2954,10 @@ void Item_func_case::fix_length_and_dec()
Some of the items might have been changed to Item_func_conv_charset.
*/
for (nagg= 0 ; nagg < ncases / 2 ; nagg++)
- args[nagg * 2 + 1]= agg[nagg];
+ change_item_tree_if_needed(thd, &args[nagg * 2 + 1], agg[nagg]);
+
if (else_expr_num != -1)
- args[else_expr_num]= agg[nagg++];
+ change_item_tree_if_needed(thd, &args[else_expr_num], agg[nagg++]);
}
else
collation.set_numeric();
@@ -2992,9 +3017,10 @@ void Item_func_case::fix_length_and_dec()
arrray, because some of the items might have been changed to converters
(e.g. Item_func_conv_charset, or Item_string for constants).
*/
- args[first_expr_num]= agg[0];
+ change_item_tree_if_needed(thd, &args[first_expr_num], agg[0]);
+
for (nagg= 0; nagg < ncases / 2; nagg++)
- args[nagg * 2]= agg[nagg + 1];
+ change_item_tree_if_needed(thd, &args[nagg * 2], agg[nagg + 1]);
}
for (i= 0; i <= (uint)TIME_RESULT; i++)