Skip to content

Commit c57c5be

Browse files
author
Alexander Barkov
committed
MDEV-5745 analyze MySQL fix for bug#12368495
1 parent 01faff0 commit c57c5be

File tree

8 files changed

+138
-44
lines changed

8 files changed

+138
-44
lines changed

mysql-test/r/ctype_ucs.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4277,5 +4277,38 @@ COALESCE(c1)
42774277

42784278
DROP TABLE t1;
42794279
#
4280+
# MDEV-5745 analyze MySQL fix for bug#12368495
4281+
#
4282+
SELECT CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061));
4283+
CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061))
4284+
2
4285+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061));
4286+
CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061))
4287+
2
4288+
SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061));
4289+
CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061))
4290+
1
4291+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061));
4292+
CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061))
4293+
2
4294+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061));
4295+
CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061))
4296+
2
4297+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061));
4298+
CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061))
4299+
1
4300+
SELECT CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061));
4301+
CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061))
4302+
2
4303+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061));
4304+
CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061))
4305+
2
4306+
SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061));
4307+
CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061))
4308+
1
4309+
SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
4310+
CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061))
4311+
1
4312+
#
42804313
# End of 5.5 tests
42814314
#

mysql-test/r/ctype_utf32.result

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,5 +1237,38 @@ SELECT '2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)'))
12371237
'2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)')) hour_second
12381238
2010-10-10 10:10:10
12391239
#
1240+
# MDEV-5745 analyze MySQL fix for bug#12368495
1241+
#
1242+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061));
1243+
CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061))
1244+
4
1245+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061));
1246+
CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061))
1247+
4
1248+
SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061));
1249+
CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061))
1250+
1
1251+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061));
1252+
CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061))
1253+
4
1254+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061));
1255+
CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061))
1256+
4
1257+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061));
1258+
CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061))
1259+
3
1260+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061));
1261+
CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061))
1262+
4
1263+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061));
1264+
CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061))
1265+
4
1266+
SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061));
1267+
CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061))
1268+
3
1269+
SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061));
1270+
CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061))
1271+
1
1272+
#
12401273
# End of 5.5 tests
12411274
#

mysql-test/t/ctype_ucs.test

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -837,6 +837,23 @@ SELECT COALESCE(c1) FROM t1 ORDER BY 1;
837837
DROP TABLE t1;
838838

839839

840+
--echo #
841+
--echo # MDEV-5745 analyze MySQL fix for bug#12368495
842+
--echo #
843+
SELECT CHAR_LENGTH(TRIM(LEADING 0x000000 FROM _ucs2 0x0061));
844+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _ucs2 0x0061));
845+
SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _ucs2 0x0061));
846+
847+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x000000 FROM _ucs2 0x0061));
848+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _ucs2 0x0061));
849+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _ucs2 0x0061));
850+
851+
SELECT CHAR_LENGTH(TRIM(BOTH 0x000000 FROM _ucs2 0x0061));
852+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _ucs2 0x0061));
853+
SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _ucs2 0x0061));
854+
SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _ucs2 0x0061));
855+
856+
840857
--echo #
841858
--echo # End of 5.5 tests
842859
--echo #

mysql-test/t/ctype_utf32.test

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,22 @@ ORDER BY l DESC;
860860

861861
SELECT '2010-10-10 10:10:10' + INTERVAL GeometryType(GeomFromText('POINT(1 1)')) hour_second;
862862

863+
--echo #
864+
--echo # MDEV-5745 analyze MySQL fix for bug#12368495
865+
--echo #
866+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0000000000 FROM _utf32 0x00000061));
867+
SELECT CHAR_LENGTH(TRIM(LEADING 0x0001 FROM _utf32 0x00000061));
868+
SELECT CHAR_LENGTH(TRIM(LEADING 0x00 FROM _utf32 0x00000061));
869+
870+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0000000000 FROM _utf32 0x00000061));
871+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x0001 FROM _utf32 0x00000061));
872+
SELECT CHAR_LENGTH(TRIM(TRAILING 0x61 FROM _utf32 0x00000061));
873+
874+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0000000000 FROM _utf32 0x00000061));
875+
SELECT CHAR_LENGTH(TRIM(BOTH 0x0001 FROM _utf32 0x00000061));
876+
SELECT CHAR_LENGTH(TRIM(BOTH 0x61 FROM _utf32 0x00000061));
877+
SELECT CHAR_LENGTH(TRIM(BOTH 0x00 FROM _utf32 0x00000061));
878+
863879
--echo #
864880
--echo # End of 5.5 tests
865881
--echo #

sql/item.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2074,7 +2074,7 @@ bool agg_item_collations(DTCollation &c, const char *fname,
20742074
bool unknown_cs= 0;
20752075

20762076
c.set(av[0]->collation);
2077-
for (i= 1, arg= &av[item_sep]; i < count; i++, arg++)
2077+
for (i= 1, arg= &av[item_sep]; i < count; i++, arg+= item_sep)
20782078
{
20792079
if (c.aggregate((*arg)->collation, flags))
20802080
{

sql/item_strfunc.cc

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1624,7 +1624,7 @@ String *Item_func_ltrim::val_str(String *str)
16241624

16251625
if ((remove_length= remove_str->length()) == 0 ||
16261626
remove_length > res->length())
1627-
return res;
1627+
return non_trimmed_value(res);
16281628

16291629
ptr= (char*) res->ptr();
16301630
end= ptr+res->length();
@@ -1643,9 +1643,8 @@ String *Item_func_ltrim::val_str(String *str)
16431643
end+=remove_length;
16441644
}
16451645
if (ptr == res->ptr())
1646-
return res;
1647-
tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
1648-
return &tmp_value;
1646+
return non_trimmed_value(res);
1647+
return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
16491648
}
16501649

16511650

@@ -1671,7 +1670,7 @@ String *Item_func_rtrim::val_str(String *str)
16711670

16721671
if ((remove_length= remove_str->length()) == 0 ||
16731672
remove_length > res->length())
1674-
return res;
1673+
return non_trimmed_value(res);
16751674

16761675
ptr= (char*) res->ptr();
16771676
end= ptr+res->length();
@@ -1683,11 +1682,11 @@ String *Item_func_rtrim::val_str(String *str)
16831682
{
16841683
char chr=(*remove_str)[0];
16851684
#ifdef USE_MB
1686-
if (use_mb(res->charset()))
1685+
if (use_mb(collation.collation))
16871686
{
16881687
while (ptr < end)
16891688
{
1690-
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
1689+
if ((l= my_ismbchar(collation.collation, ptr, end))) ptr+= l, p=ptr;
16911690
else ++ptr;
16921691
}
16931692
ptr=p;
@@ -1700,12 +1699,12 @@ String *Item_func_rtrim::val_str(String *str)
17001699
{
17011700
const char *r_ptr=remove_str->ptr();
17021701
#ifdef USE_MB
1703-
if (use_mb(res->charset()))
1702+
if (use_mb(collation.collation))
17041703
{
17051704
loop:
17061705
while (ptr + remove_length < end)
17071706
{
1708-
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
1707+
if ((l= my_ismbchar(collation.collation, ptr, end))) ptr+= l;
17091708
else ++ptr;
17101709
}
17111710
if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
@@ -1724,9 +1723,8 @@ String *Item_func_rtrim::val_str(String *str)
17241723
}
17251724
}
17261725
if (end == res->ptr()+res->length())
1727-
return res;
1728-
tmp_value.set(*res,0,(uint) (end-res->ptr()));
1729-
return &tmp_value;
1726+
return non_trimmed_value(res);
1727+
return trimmed_value(res, 0, (uint32) (end - res->ptr()));
17301728
}
17311729

17321730

@@ -1753,37 +1751,22 @@ String *Item_func_trim::val_str(String *str)
17531751

17541752
if ((remove_length= remove_str->length()) == 0 ||
17551753
remove_length > res->length())
1756-
return res;
1754+
return non_trimmed_value(res);
17571755

17581756
ptr= (char*) res->ptr();
17591757
end= ptr+res->length();
17601758
r_ptr= remove_str->ptr();
1759+
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
1760+
ptr+=remove_length;
17611761
#ifdef USE_MB
1762-
if (use_mb(res->charset()))
1762+
if (use_mb(collation.collation))
17631763
{
1764-
while (ptr + remove_length <= end)
1765-
{
1766-
uint num_bytes= 0;
1767-
while (num_bytes < remove_length)
1768-
{
1769-
uint len;
1770-
if ((len= my_ismbchar(res->charset(), ptr + num_bytes, end)))
1771-
num_bytes+= len;
1772-
else
1773-
++num_bytes;
1774-
}
1775-
if (num_bytes != remove_length)
1776-
break;
1777-
if (memcmp(ptr, r_ptr, remove_length))
1778-
break;
1779-
ptr+= remove_length;
1780-
}
17811764
char *p=ptr;
17821765
register uint32 l;
17831766
loop:
17841767
while (ptr + remove_length < end)
17851768
{
1786-
if ((l= my_ismbchar(res->charset(), ptr,end)))
1769+
if ((l= my_ismbchar(collation.collation, ptr, end)))
17871770
ptr+= l;
17881771
else
17891772
++ptr;
@@ -1799,16 +1782,13 @@ String *Item_func_trim::val_str(String *str)
17991782
else
18001783
#endif /* USE_MB */
18011784
{
1802-
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
1803-
ptr+=remove_length;
18041785
while (ptr + remove_length <= end &&
18051786
!memcmp(end-remove_length,r_ptr,remove_length))
18061787
end-=remove_length;
18071788
}
18081789
if (ptr == res->ptr() && end == ptr+res->length())
1809-
return res;
1810-
tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
1811-
return &tmp_value;
1790+
return non_trimmed_value(res);
1791+
return trimmed_value(res, (uint32) (ptr - res->ptr()), (uint32) (end - ptr));
18121792
}
18131793

18141794
void Item_func_trim::fix_length_and_dec()

sql/item_strfunc.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,21 @@ class Item_func_trim :public Item_str_func
270270
protected:
271271
String tmp_value;
272272
String remove;
273+
String *trimmed_value(String *res, uint32 offset, uint32 length)
274+
{
275+
tmp_value.set(*res, offset, length);
276+
/*
277+
Make sure to return correct charset and collation:
278+
TRIM(0x000000 FROM _ucs2 0x0061)
279+
should set charset to "binary" rather than to "ucs2".
280+
*/
281+
tmp_value.set_charset(collation.collation);
282+
return &tmp_value;
283+
}
284+
String *non_trimmed_value(String *res)
285+
{
286+
return trimmed_value(res, 0, res->length());
287+
}
273288
public:
274289
Item_func_trim(Item *a,Item *b) :Item_str_func(a,b) {}
275290
Item_func_trim(Item *a) :Item_str_func(a) {}

strings/ctype-ucs2.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1983,10 +1983,10 @@ my_strnxfrmlen_utf32(CHARSET_INFO *cs __attribute__((unused)), size_t len)
19831983

19841984
static uint
19851985
my_ismbchar_utf32(CHARSET_INFO *cs __attribute__((unused)),
1986-
const char *b __attribute__((unused)),
1987-
const char *e __attribute__((unused)))
1986+
const char *b,
1987+
const char *e)
19881988
{
1989-
return 4;
1989+
return b + 4 > e ? 0 : 4;
19901990
}
19911991

19921992

@@ -2895,10 +2895,10 @@ static int my_strnncollsp_ucs2(CHARSET_INFO *cs __attribute__((unused)),
28952895

28962896

28972897
static uint my_ismbchar_ucs2(CHARSET_INFO *cs __attribute__((unused)),
2898-
const char *b __attribute__((unused)),
2899-
const char *e __attribute__((unused)))
2898+
const char *b,
2899+
const char *e)
29002900
{
2901-
return 2;
2901+
return b + 2 > e ? 0 : 2;
29022902
}
29032903

29042904

0 commit comments

Comments
 (0)