@@ -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