diff options
author | Georgi Kodinov <kgeorge@mysql.com> | 2008-07-30 14:07:37 +0300 |
---|---|---|
committer | Georgi Kodinov <kgeorge@mysql.com> | 2008-07-30 14:07:37 +0300 |
commit | ae4a35fd5cba393f5e924241b21a7a59fc921b15 (patch) | |
tree | 9a3ca37f325646d96b550afd705ade75dc8b3d5e /sql/item_cmpfunc.cc | |
parent | 7f615b2c14d3c8d7b7fbd777faa0adeba9a35fdc (diff) | |
download | mariadb-git-ae4a35fd5cba393f5e924241b21a7a59fc921b15.tar.gz |
Bug#37662 nested if() inside sum() is parsed in exponential time
min() and max() functions are implemented in MySQL as macros.
This means that max(a,b) is expanded to: ((a) > (b) ? (a) : (b))
Note how 'a' is quoted two times.
Now imagine 'a' is a recursive function call that's several 10s of levels deep.
And the recursive function does max() with a function arg as well to dive into
recursion.
This means that simple function call can take most of the clock time.
Identified and fixed several such calls to max()/min() : including the IF()
sql function implementation.
mysql-test/r/func_if.result:
Bug#37662 test case
mysql-test/t/func_if.test:
Bug#37662 test case
sql/item.cc:
Bug#37662 don't call expensive functions as arguments to min/max
sql/item_cmpfunc.cc:
Bug#37662 don't call expensive functions as arguments to min/max
sql/item_func.cc:
Bug#37662 don't call expensive functions as arguments to min/max
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r-- | sql/item_cmpfunc.cc | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 16f3e51d615..1994f6bf1a5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2098,8 +2098,11 @@ Item_func_ifnull::fix_length_and_dec() uint Item_func_ifnull::decimal_precision() const { - int max_int_part=max(args[0]->decimal_int_part(),args[1]->decimal_int_part()); - return min(max_int_part + decimals, DECIMAL_MAX_PRECISION); + int arg0_int_part= args[0]->decimal_int_part(); + int arg1_int_part= args[1]->decimal_int_part(); + int max_int_part= max(arg0_int_part, arg1_int_part); + int precision= max_int_part + decimals; + return min(precision, DECIMAL_MAX_PRECISION); } @@ -2281,8 +2284,9 @@ Item_func_if::fix_length_and_dec() uint Item_func_if::decimal_precision() const { - int precision=(max(args[1]->decimal_int_part(),args[2]->decimal_int_part())+ - decimals); + int arg1_prec= args[1]->decimal_int_part(); + int arg2_prec= args[2]->decimal_int_part(); + int precision=max(arg1_prec,arg2_prec) + decimals; return min(precision, DECIMAL_MAX_PRECISION); } |