From e1c614134078b23934555bd76c6cdbd039d8bc28 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Dec 2005 15:52:10 +0400 Subject: [PATCH] Bug#15581: COALESCE function truncates mutli-byte TINYTEXT values field.cc: BLOB variations have number-in-bytes limit, unlike CHAR/VARCHAR which have number-of-characters limits. A tinyblob column can store up to 255 bytes. In the case of basic Latin letters (which use 1 byte per character) we can store up to 255 characters in a tinyblob column. When passing an utf8 tinyblob column as an argument into a function (e.g. COALESCE) we need to reserve 3*255 bytes. I.e. multiply length in bytes to mbcharlen for the character set. Although in reality a tinyblob column can never be 3*255 bytes long, we need to set max_length to multiply to make fix_length_and_dec() of the function-caller (e.g. COALESCE) calculate the correct max_length for the column being created. ctype_utf8.result, ctype_utf8.test: Adding test case. mysql-test/t/ctype_utf8.test: Adding test case. mysql-test/r/ctype_utf8.result: Adding test case. sql/field.cc: Bug#15581: COALESCE function truncates mutli-byte TINYTEXT values BLOB variations have byte limits, unlike CHAR/VARCHAR which have number-of-character limits. It means tinyblob can store up to 255 bytes. All of them can be basic latin letters which use 1 byte per character. I.e. we can store up to 255 characters in a tinyblob column. When passing a tinyblob column as an argument into a function (for example COALESCE or CONCAT) we need to reserve 3*255 bytes in the case of utf-8. I.e. multiply length in bytes to mbcharlen for the character set. --- mysql-test/r/ctype_utf8.result | 8 ++++++++ mysql-test/t/ctype_utf8.test | 10 ++++++++++ sql/field.cc | 6 +++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 03d3ab9f22e..cf9426e6b21 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1070,3 +1070,11 @@ char(a) 1 2 drop table t1; +CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES(REPEAT('a', 100)); +CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1; +SELECT LENGTH(bug) FROM t2; +LENGTH(bug) +100 +DROP TABLE t2; +DROP TABLE t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 8c0e03c0cd3..01bffe9492e 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -882,4 +882,14 @@ set names utf8; select distinct char(a) from t1; drop table t1; +# +# Bug#15581: COALESCE function truncates mutli-byte TINYTEXT values +# +CREATE TABLE t1 (t TINYTEXT CHARACTER SET utf8); +INSERT INTO t1 VALUES(REPEAT('a', 100)); +CREATE TEMPORARY TABLE t2 SELECT COALESCE(t) AS bug FROM t1; +SELECT LENGTH(bug) FROM t2; +DROP TABLE t2; +DROP TABLE t1; + # End of 4.1 tests diff --git a/sql/field.cc b/sql/field.cc index abb5297f458..b1d9167aee2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -6949,11 +6949,11 @@ uint32 Field_blob::max_length() switch (packlength) { case 1: - return 255; + return 255 * field_charset->mbmaxlen; case 2: - return 65535; + return 65535 * field_charset->mbmaxlen; case 3: - return 16777215; + return 16777215 * field_charset->mbmaxlen; case 4: return (uint32) 4294967295U; default: