Skip to content

Commit 752f93f

Browse files
author
Tor Didriksen
committed
merge 5.5 => 5.6
2 parents 834019e + 9ffebd7 commit 752f93f

File tree

1 file changed

+59
-31
lines changed

1 file changed

+59
-31
lines changed

sql/item_strfunc.cc

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1827,6 +1827,42 @@ String *Item_func_substr_index::val_str(String *str)
18271827
return (&tmp_value);
18281828
}
18291829

1830+
1831+
/**
1832+
A helper function for trim(leading ...) for multibyte charsets.
1833+
@param res Copy of 'res' in calling functions.
1834+
@param ptr Where to start trimming.
1835+
@param end End of string to be trimmed.
1836+
@param remove_str The string to be removed from [ptr .. end)
1837+
@return Pointer to left-trimmed string.
1838+
*/
1839+
static inline
1840+
char *trim_left_mb(String *res, char *ptr, char *end, String *remove_str)
1841+
{
1842+
const char * const r_ptr= remove_str->ptr();
1843+
const uint remove_length= remove_str->length();
1844+
1845+
while (ptr + remove_length <= end)
1846+
{
1847+
uint num_bytes= 0;
1848+
while (num_bytes < remove_length)
1849+
{
1850+
uint len;
1851+
if ((len= my_ismbchar(res->charset(), ptr + num_bytes, end)))
1852+
num_bytes+= len;
1853+
else
1854+
++num_bytes;
1855+
}
1856+
if (num_bytes != remove_length)
1857+
break;
1858+
if (memcmp(ptr, r_ptr, remove_length))
1859+
break;
1860+
ptr+= remove_length;
1861+
}
1862+
return ptr;
1863+
}
1864+
1865+
18301866
/*
18311867
** The trim functions are extension to ANSI SQL because they trim substrings
18321868
** They ltrim() and rtrim() functions are optimized for 1 byte strings
@@ -1861,19 +1897,28 @@ String *Item_func_ltrim::val_str(String *str)
18611897

18621898
ptr= (char*) res->ptr();
18631899
end= ptr+res->length();
1864-
if (remove_length == 1)
1900+
#ifdef USE_MB
1901+
if (use_mb(res->charset()))
18651902
{
1866-
char chr=(*remove_str)[0];
1867-
while (ptr != end && *ptr == chr)
1868-
ptr++;
1903+
ptr= trim_left_mb(res, ptr, end, remove_str);
18691904
}
18701905
else
1906+
#endif /* USE_MB */
18711907
{
1872-
const char *r_ptr=remove_str->ptr();
1873-
end-=remove_length;
1874-
while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
1875-
ptr+=remove_length;
1876-
end+=remove_length;
1908+
if (remove_length == 1)
1909+
{
1910+
char chr=(*remove_str)[0];
1911+
while (ptr != end && *ptr == chr)
1912+
ptr++;
1913+
}
1914+
else
1915+
{
1916+
const char *r_ptr=remove_str->ptr();
1917+
end-=remove_length;
1918+
while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
1919+
ptr+=remove_length;
1920+
end+=remove_length;
1921+
}
18771922
}
18781923
if (ptr == res->ptr())
18791924
return res;
@@ -1967,11 +2012,8 @@ String *Item_func_trim::val_str(String *str)
19672012
{
19682013
DBUG_ASSERT(fixed == 1);
19692014
char buff[MAX_FIELD_WIDTH], *ptr, *end;
1970-
const char *r_ptr;
19712015
String tmp(buff, sizeof(buff), system_charset_info);
19722016
String *res, *remove_str;
1973-
uint remove_length;
1974-
LINT_INIT(remove_length);
19752017

19762018
res= args[0]->val_str(str);
19772019
if ((null_value=args[0]->null_value))
@@ -1984,33 +2026,19 @@ String *Item_func_trim::val_str(String *str)
19842026
return 0;
19852027
}
19862028

1987-
if ((remove_length= remove_str->length()) == 0 ||
2029+
const uint remove_length= remove_str->length();
2030+
if (remove_length == 0 ||
19882031
remove_length > res->length())
19892032
return res;
19902033

19912034
ptr= (char*) res->ptr();
19922035
end= ptr+res->length();
1993-
r_ptr= remove_str->ptr();
2036+
const char * const r_ptr= remove_str->ptr();
19942037
#ifdef USE_MB
19952038
if (use_mb(res->charset()))
19962039
{
1997-
while (ptr + remove_length <= end)
1998-
{
1999-
uint num_bytes= 0;
2000-
while (num_bytes < remove_length)
2001-
{
2002-
uint len;
2003-
if ((len= my_ismbchar(res->charset(), ptr + num_bytes, end)))
2004-
num_bytes+= len;
2005-
else
2006-
++num_bytes;
2007-
}
2008-
if (num_bytes != remove_length)
2009-
break;
2010-
if (memcmp(ptr, r_ptr, remove_length))
2011-
break;
2012-
ptr+= remove_length;
2013-
}
2040+
ptr= trim_left_mb(res, ptr, end, remove_str);
2041+
20142042
char *p=ptr;
20152043
register uint32 l;
20162044
loop:

0 commit comments

Comments
 (0)