From ce8ad64dd2ac2f28557020f5de07c56cc21ecaac Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 00:57:32 +0400 Subject: 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. The bug has been fixed by the same solution as in the CASE function implementation. --- mysql-test/r/func_if.result | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'mysql-test/r/func_if.result') 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 -- cgit v1.2.1 From 03f9b2cea60842e8b8e7e7e65bfdf96ca7e3fef8 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 14:59:10 +0400 Subject: rollback of bug #40761 fix --- mysql-test/r/func_if.result | 9 --------- 1 file changed, 9 deletions(-) (limited to 'mysql-test/r/func_if.result') diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 16d6b435dc7..7ffc957e285 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -176,13 +176,4 @@ 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 -- cgit v1.2.1 From c1bf0475cf23777a5a5c25e0b4ece4dfc3e4e398 Mon Sep 17 00:00:00 2001 From: Gleb Shchepa Date: Fri, 12 Dec 2008 17:16:25 +0400 Subject: 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 | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'mysql-test/r/func_if.result') 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 -- cgit v1.2.1