Browse Source

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).
pull/374/head
Gleb Shchepa 17 years ago
parent
commit
af5cf536bc
  1. 9
      mysql-test/r/func_if.result
  2. 14
      mysql-test/t/func_if.test
  3. 5
      sql/item_func.h

9
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

14
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

5
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);
};

Loading…
Cancel
Save