diff options
author | Georgi Kodinov <kgeorge@mysql.com> | 2008-07-31 12:50:24 +0300 |
---|---|---|
committer | Georgi Kodinov <kgeorge@mysql.com> | 2008-07-31 12:50:24 +0300 |
commit | a3cd2e2dab67a8d4abbd3c13e2455296a3304c56 (patch) | |
tree | 2e7e23931eb91a7bab8ab8e7eb00c76c31801859 | |
parent | 686ced5367e6c76ecc8d874a5c8b2137b45e769a (diff) | |
parent | b19155258e5e9ae40735c71234277dfc05092ec4 (diff) | |
download | mariadb-git-a3cd2e2dab67a8d4abbd3c13e2455296a3304c56.tar.gz |
merged 34159 and 37662 5.0-bugteam->5.1-bugteam
-rw-r--r-- | mysql-test/r/func_if.result | 46 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 13 | ||||
-rw-r--r-- | mysql-test/t/func_if.test | 43 | ||||
-rw-r--r-- | mysql-test/t/subselect.test | 14 | ||||
-rw-r--r-- | sql/item.cc | 12 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 12 | ||||
-rw-r--r-- | sql/item_func.cc | 15 | ||||
-rw-r--r-- | sql/sql_select.cc | 6 |
8 files changed, 144 insertions, 17 deletions
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 42a2aa840ea..62d34c5ce8f 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -131,3 +131,49 @@ drop table t1; select if(0, 18446744073709551610, 18446744073709551610); if(0, 18446744073709551610, 18446744073709551610) 18446744073709551610 +CREATE TABLE t1(a DECIMAL(10,3)); +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; +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((R +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index da512cd0a4f..1d4a05539d4 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -4398,4 +4398,15 @@ INSERT INTO t1 VALUES (1), (3); SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10); a b DROP TABLE t1,t2; -End of 5.0 tests. +CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); +INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20); +CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a)); +INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100); +SELECT * FROM t1 +WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); +pk a +1 10 +3 30 +2 20 +DROP TABLE t1,t2; +End of 5.1 tests. 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 diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index d13f6230339..93b98090420 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -3299,4 +3299,16 @@ SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10); DROP TABLE t1,t2; ---echo End of 5.0 tests. +# +# Bug #38191: Server crash with subquery containing DISTINCT and ORDER BY +# + +CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); +INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20); +CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a)); +INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100); +SELECT * FROM t1 + WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); +DROP TABLE t1,t2; + +--echo End of 5.1 tests. diff --git a/sql/item.cc b/sql/item.cc index 5ee394fcbe0..48fcb232bab 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -437,8 +437,11 @@ uint Item::decimal_precision() const Item_result restype= result_type(); if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT)) - return min(my_decimal_length_to_precision(max_length, decimals, unsigned_flag), - DECIMAL_MAX_PRECISION); + { + uint prec= + my_decimal_length_to_precision(max_length, decimals, unsigned_flag); + return min(prec, DECIMAL_MAX_PRECISION); + } return min(max_length, DECIMAL_MAX_PRECISION); } @@ -6995,8 +6998,9 @@ bool Item_type_holder::join_types(THD *thd, Item *item) if (Field::result_merge_type(fld_type) == DECIMAL_RESULT) { decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE); - int precision= min(max(prev_decimal_int_part, item->decimal_int_part()) - + decimals, DECIMAL_MAX_PRECISION); + int item_int_part= item->decimal_int_part(); + int item_prec = max(prev_decimal_int_part, item_int_part) + decimals; + int precision= min(item_prec, DECIMAL_MAX_PRECISION); unsigned_flag&= item->unsigned_flag; max_length= my_decimal_precision_to_length(precision, decimals, unsigned_flag); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 28e55eef5bd..c76bbececef 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2163,8 +2163,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); } @@ -2345,8 +2348,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); } diff --git a/sql/item_func.cc b/sql/item_func.cc index a17c1eff5dd..8bb6bb30117 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1139,9 +1139,10 @@ my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value) void Item_func_additive_op::result_precision() { decimals= max(args[0]->decimals, args[1]->decimals); - int max_int_part= max(args[0]->decimal_precision() - args[0]->decimals, - args[1]->decimal_precision() - args[1]->decimals); - int precision= min(max_int_part + 1 + decimals, DECIMAL_MAX_PRECISION); + int arg1_int= args[0]->decimal_precision() - args[0]->decimals; + int arg2_int= args[1]->decimal_precision() - args[1]->decimals; + int est_prec= max(arg1_int, arg2_int) + 1 + decimals; + int precision= min(est_prec, DECIMAL_MAX_PRECISION); /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) @@ -1252,8 +1253,8 @@ void Item_func_mul::result_precision() else unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag; decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE); - int precision= min(args[0]->decimal_precision() + args[1]->decimal_precision(), - DECIMAL_MAX_PRECISION); + uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision(); + uint precision= min(est_prec, DECIMAL_MAX_PRECISION); max_length= my_decimal_precision_to_length(precision, decimals,unsigned_flag); } @@ -1300,8 +1301,8 @@ my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value) void Item_func_div::result_precision() { - uint precision=min(args[0]->decimal_precision() + prec_increment, - DECIMAL_MAX_PRECISION); + uint arg_prec= args[0]->decimal_precision() + prec_increment; + uint precision=min(arg_prec, DECIMAL_MAX_PRECISION); /* Integer operations keep unsigned_flag if one of arguments is unsigned */ if (result_type() == INT_RESULT) unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c5e8286409c..4d8dbfe287b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6754,6 +6754,12 @@ void JOIN::cleanup(bool full) if (tmp_join) tmp_table_param.copy_field= 0; group_fields.delete_elements(); + /* + Ensure that the above delete_elements() would not be called + twice for the same list. + */ + if (tmp_join && tmp_join != this) + tmp_join->group_fields= group_fields; /* We can't call delete_elements() on copy_funcs as this will cause problems in free_elements() as some of the elements are then deleted. |