diff options
author | Gleb Shchepa <gshchepa@mysql.com> | 2008-12-12 02:04:06 +0400 |
---|---|---|
committer | Gleb Shchepa <gshchepa@mysql.com> | 2008-12-12 02:04:06 +0400 |
commit | a4467c97981714631deef5685d6d2f790e877695 (patch) | |
tree | 98650421d126f96f69f50a07f1db1ce6b667b1e1 | |
parent | a633e0b98d0dbd5aab04901856dfd717b916a508 (diff) | |
parent | ffe23f0eb736609915d3c201c3f2556819698dc1 (diff) | |
download | mariadb-git-a4467c97981714631deef5685d6d2f790e877695.tar.gz |
manual merge 5.0-bugteam -> 5.1-bugteam (bug 40761)
-rw-r--r-- | mysql-test/r/func_if.result | 9 | ||||
-rw-r--r-- | mysql-test/t/func_if.test | 13 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 50 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/item_func.cc | 10 | ||||
-rw-r--r-- | sql/item_func.h | 2 |
6 files changed, 57 insertions, 29 deletions
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 62d34c5ce8f..955a784f04c 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -176,4 +176,13 @@ IF((ROUND(t1.a,2)=1), 2, IF((ROUND(t1.a,2)=1), 2, IF((R DROP TABLE t1; +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IF(1, CAST(c AS UNSIGNED), 0)) +12345678901234567890 +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +MAX(IFNULL(CAST(c AS UNSIGNED), 0)) +12345678901234567890 +DROP TABLE t1; End of 5.0 tests diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 8da10f36cbe..68728d6697e 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -150,4 +150,17 @@ FROM t1; DROP TABLE t1; +# +# Bug #40761: Assert on sum func on IF(..., CAST(longtext AS UNSIGNED), signed) +# (was: LEFT JOIN on inline view crashes server) +# + +CREATE TABLE t1 (c LONGTEXT); +INSERT INTO t1 VALUES(1), (2), (3), (4), ('12345678901234567890'); + +SELECT * FROM (SELECT MAX(IF(1, CAST(c AS UNSIGNED), 0)) FROM t1) AS te; +SELECT * FROM (SELECT MAX(IFNULL(CAST(c AS UNSIGNED), 0)) FROM t1) AS te; + +DROP TABLE t1; + --echo End of 5.0 tests diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c6b70440b41..70ad385c719 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2132,21 +2132,23 @@ Item_func_ifnull::fix_length_and_dec() { agg_result_type(&hybrid_type, args, 2); maybe_null=args[1]->maybe_null; - decimals= max(args[0]->decimals, args[1]->decimals); - unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag; if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT) { - int len0= args[0]->max_length - args[0]->decimals - - (args[0]->unsigned_flag ? 0 : 1); - - int len1= args[1]->max_length - args[1]->decimals - - (args[1]->unsigned_flag ? 0 : 1); - - max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1); + max_length= 0; + decimals= 0; + unsigned_flag= TRUE; + agg_num_lengths(args[0]); + agg_num_lengths(args[1]); + max_length= my_decimal_precision_to_length(max_length + decimals, decimals, + unsigned_flag); } else + { max_length= max(args[0]->max_length, args[1]->max_length); + decimals= max(args[0]->decimals, args[1]->decimals); + unsigned_flag=args[0]->unsigned_flag && args[1]->unsigned_flag; + } switch (hybrid_type) { case STRING_RESULT: @@ -2300,8 +2302,6 @@ void Item_func_if::fix_length_and_dec() { maybe_null=args[1]->maybe_null || args[2]->maybe_null; - decimals= max(args[1]->decimals, args[2]->decimals); - unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; enum Item_result arg1_type=args[1]->result_type(); enum Item_result arg2_type=args[2]->result_type(); @@ -2338,16 +2338,20 @@ Item_func_if::fix_length_and_dec() if ((cached_result_type == DECIMAL_RESULT ) || (cached_result_type == INT_RESULT)) { - int len1= args[1]->max_length - args[1]->decimals - - (args[1]->unsigned_flag ? 0 : 1); - - int len2= args[2]->max_length - args[2]->decimals - - (args[2]->unsigned_flag ? 0 : 1); - - max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1); + max_length= 0; + decimals= 0; + unsigned_flag= TRUE; + agg_num_lengths(args[1]); + agg_num_lengths(args[2]); + max_length= my_decimal_precision_to_length(max_length + decimals, decimals, + unsigned_flag); } else + { max_length= max(args[1]->max_length, args[2]->max_length); + decimals= max(args[1]->decimals, args[2]->decimals); + unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag; + } } @@ -2663,16 +2667,6 @@ void Item_func_case::agg_str_lengths(Item* arg) } -void Item_func_case::agg_num_lengths(Item *arg) -{ - uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, - arg->unsigned_flag) - arg->decimals; - set_if_bigger(max_length, len); - set_if_bigger(decimals, arg->decimals); - unsigned_flag= unsigned_flag && arg->unsigned_flag; -} - - void Item_func_case::fix_length_and_dec() { Item **agg; diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c2227fa04e0..4afa4f9d0ca 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -728,6 +728,7 @@ public: table_map not_null_tables() const { return 0; } bool is_null(); + void agg_str_lengths(Item *arg); }; @@ -1160,7 +1161,6 @@ public: CHARSET_INFO *compare_collation() { return cmp_collation.collation; } void cleanup(); void agg_str_lengths(Item *arg); - void agg_num_lengths(Item *arg); }; /* diff --git a/sql/item_func.cc b/sql/item_func.cc index 33b5f21774f..4f797b5f92b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6086,3 +6086,13 @@ longlong Item_func_uuid_short::val_int() pthread_mutex_unlock(&LOCK_uuid_generator); return (longlong) val; } + + +void Item_func::agg_num_lengths(Item *arg) +{ + uint len= my_decimal_length_to_precision(arg->max_length, arg->decimals, + arg->unsigned_flag) - arg->decimals; + set_if_bigger(max_length, len); + set_if_bigger(decimals, arg->decimals); + unsigned_flag= unsigned_flag && arg->unsigned_flag; +} diff --git a/sql/item_func.h b/sql/item_func.h index 3acda817d26..0c703d4b871 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -200,6 +200,8 @@ public: null_value=1; return 0.0; } +protected: + void agg_num_lengths(Item *arg); }; |