summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorgi Kodinov <kgeorge@mysql.com>2008-07-31 12:50:24 +0300
committerGeorgi Kodinov <kgeorge@mysql.com>2008-07-31 12:50:24 +0300
commita3cd2e2dab67a8d4abbd3c13e2455296a3304c56 (patch)
tree2e7e23931eb91a7bab8ab8e7eb00c76c31801859
parent686ced5367e6c76ecc8d874a5c8b2137b45e769a (diff)
parentb19155258e5e9ae40735c71234277dfc05092ec4 (diff)
downloadmariadb-git-a3cd2e2dab67a8d4abbd3c13e2455296a3304c56.tar.gz
merged 34159 and 37662 5.0-bugteam->5.1-bugteam
-rw-r--r--mysql-test/r/func_if.result46
-rw-r--r--mysql-test/r/subselect.result13
-rw-r--r--mysql-test/t/func_if.test43
-rw-r--r--mysql-test/t/subselect.test14
-rw-r--r--sql/item.cc12
-rw-r--r--sql/item_cmpfunc.cc12
-rw-r--r--sql/item_func.cc15
-rw-r--r--sql/sql_select.cc6
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.