From ae4a35fd5cba393f5e924241b21a7a59fc921b15 Mon Sep 17 00:00:00 2001 From: Georgi Kodinov Date: Wed, 30 Jul 2008 14:07:37 +0300 Subject: 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 --- mysql-test/t/func_if.test | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'mysql-test/t/func_if.test') diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 5373ca3fec6..8da10f36cbe 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -108,3 +108,46 @@ drop table t1; select if(0, 18446744073709551610, 18446744073709551610); +# +# Bug #37662: nested if() inside sum() is parsed in exponential time +# + +CREATE TABLE t1(a DECIMAL(10,3)); + +# check : should be fast. more than few secs means failure. +SELECT t1.a, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2, + IF((ROUND(t1.a,2)=1), 2,0)))))))))))))))))))))))))))))) + 1 +FROM t1; + +DROP TABLE t1; + +--echo End of 5.0 tests -- cgit v1.2.1