summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Shchepa <gshchepa@mysql.com>2008-12-12 17:16:25 +0400
committerGleb Shchepa <gshchepa@mysql.com>2008-12-12 17:16:25 +0400
commitaf5cf536bc5246e49a4874a225931a838659cae0 (patch)
treef1b0ecac2c01c609c70fa1aea65a439f20771431
parent5ff1bcbc2a3cf3b28ce11673d89a1d2b3d8ad376 (diff)
downloadmariadb-git-af5cf536bc5246e49a4874a225931a838659cae0.tar.gz
Bug #40761: Assert on sum function on
IF(..., CAST(longtext AS UNSIGNED), signed_val) (was: LEFT JOIN on inline view crashes server) Select from a LONGTEXT column wrapped with an expression like "IF(..., CAST(longtext_column AS UNSIGNED), smth_signed)" failed an assertion or crashed the server. IFNULL function was affected too. LONGTEXT column item has a maximum length of 32^2-1 bytes, at the same time this is a maximum possible length of any MySQL item. CAST(longtext_column AS UNSIGNED) returns some unsigned numeric result of length 32^2-1, so the result of IF/IFNULL function of this number and some other signed number will have text length of (32^2-1)+1=32^2 (one byte for the minus sign) - there is integer overflow, and the length is equal to zero. That caused assert/crash. CAST AS UNSIGNED function has been modified to limit maximal length of resulting number to 67 (maximal length of DECIMAL and two characters for minus sign and dot). mysql-test/r/func_if.result: Added test case for bug #40761. mysql-test/t/func_if.test: Added test case for bug #40761. sql/item_func.h: Bug #40761: Assert on sum function on IF(..., CAST(longtext AS UNSIGNED), signed_val) CAST AS UNSIGNED function has been modified to limit maximal length of resulting number to 67 (maximal length of DECIMAL and two characters for minus sign and dot).
-rw-r--r--mysql-test/r/func_if.result9
-rw-r--r--mysql-test/t/func_if.test14
-rw-r--r--sql/item_func.h5
3 files changed, 27 insertions, 1 deletions
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index 7ffc957e285..16d6b435dc7 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..4efea8e195e 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -150,4 +150,18 @@ 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_func.h b/sql/item_func.h
index 6dcf32cba07..89c841abb75 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -351,7 +351,10 @@ public:
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
- { max_length=args[0]->max_length; unsigned_flag=1; }
+ {
+ max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
longlong val_int();
void print(String *str);
};