summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorSergey Glukhov <sergey.glukhov@oracle.com>2010-12-21 14:34:11 +0300
committerSergey Glukhov <sergey.glukhov@oracle.com>2010-12-21 14:34:11 +0300
commitc4b2906939277302eea16e9653c226c97fe7e8be (patch)
treef5ef5d20bde3490e4a43f28f7b52f2cd24952564 /sql/item_sum.cc
parent16ca2deb90723d87309ab4c27208389db6754cfa (diff)
downloadmariadb-git-c4b2906939277302eea16e9653c226c97fe7e8be.tar.gz
Bug#58030 crash in Item_func_geometry_from_text::val_str
Item_sum_max/Item_sum_min incorrectly set null_value flag and attempt to get result in parent functions leads to crash. This happens due to double evaluation of the function argumet. First evaluation happens in the comparator and second one happens in Item_cache::cache_value(). The fix is to introduce new Item_cache object which holds result of the argument and use this cached value as an argument of the comparator.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc20
1 files changed, 11 insertions, 9 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index a60a6b3ef95..5493020b67b 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -666,8 +666,10 @@ void Item_sum_hybrid::setup_hybrid(Item *item, Item *value_arg)
value= Item_cache::get_cache(item);
value->setup(item);
value->store(value_arg);
+ arg_cache= Item_cache::get_cache(item);
+ arg_cache->setup(item);
cmp= new Arg_comparator();
- cmp->set_cmp_func(this, args, (Item**)&value, FALSE);
+ cmp->set_cmp_func(this, (Item**)&arg_cache, (Item**)&value, FALSE);
collation.set(item->collation);
}
@@ -1639,11 +1641,11 @@ Item *Item_sum_min::copy_or_same(THD* thd)
bool Item_sum_min::add()
{
/* args[0] < value */
- int res= cmp->compare();
- if (!args[0]->null_value &&
- (null_value || res < 0))
+ arg_cache->cache_value();
+ if (!arg_cache->null_value &&
+ (null_value || cmp->compare() < 0))
{
- value->store(args[0]);
+ value->store(arg_cache);
value->cache_value();
null_value= 0;
}
@@ -1662,11 +1664,11 @@ Item *Item_sum_max::copy_or_same(THD* thd)
bool Item_sum_max::add()
{
/* args[0] > value */
- int res= cmp->compare();
- if (!args[0]->null_value &&
- (null_value || res > 0))
+ arg_cache->cache_value();
+ if (!arg_cache->null_value &&
+ (null_value || cmp->compare() > 0))
{
- value->store(args[0]);
+ value->store(arg_cache);
value->cache_value();
null_value= 0;
}