mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Fixed bug #18243.
The implementation of the method Item_func_reverse::val_str for the REVERSE function modified the argument of the function. This led to wrong results for expressions that contained REVERSE(ref) if ref occurred somewhere else in the expressions.
This commit is contained in:
parent
83bc48f38e
commit
0e3d2dafd6
4 changed files with 54 additions and 18 deletions
|
@ -1021,4 +1021,19 @@ select * from t1 where f1='test' and (f2= sha("TEST") or f2= sha("test"));
|
|||
f1 f2
|
||||
test a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a varchar(10));
|
||||
INSERT INTO t1 VALUES ('abc'), ('xyz');
|
||||
SELECT a, CONCAT(a,' ',a) AS c FROM t1
|
||||
HAVING LEFT(c,LENGTH(c)-INSTR(REVERSE(c)," ")) = a;
|
||||
a c
|
||||
abc abc abc
|
||||
xyz xyz xyz
|
||||
SELECT a, CONCAT(a,' ',a) AS c FROM t1
|
||||
HAVING LEFT(CONCAT(a,' ',a),
|
||||
LENGTH(CONCAT(a,' ',a))-
|
||||
INSTR(REVERSE(CONCAT(a,' ',a))," ")) = a;
|
||||
a c
|
||||
abc abc abc
|
||||
xyz xyz xyz
|
||||
DROP TABLE t1;
|
||||
End of 4.1 tests
|
||||
|
|
|
@ -681,4 +681,21 @@ select * from t1 where f1='test' and (f2= sha("test") or f2= sha("TEST"));
|
|||
select * from t1 where f1='test' and (f2= sha("TEST") or f2= sha("test"));
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Bug#18243: REVERSE changes its argument
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (a varchar(10));
|
||||
INSERT INTO t1 VALUES ('abc'), ('xyz');
|
||||
|
||||
SELECT a, CONCAT(a,' ',a) AS c FROM t1
|
||||
HAVING LEFT(c,LENGTH(c)-INSTR(REVERSE(c)," ")) = a;
|
||||
|
||||
SELECT a, CONCAT(a,' ',a) AS c FROM t1
|
||||
HAVING LEFT(CONCAT(a,' ',a),
|
||||
LENGTH(CONCAT(a,' ',a))-
|
||||
INSTR(REVERSE(CONCAT(a,' ',a))," ")) = a;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
|
|
@ -709,44 +709,47 @@ String *Item_func_reverse::val_str(String *str)
|
|||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
String *res = args[0]->val_str(str);
|
||||
char *ptr,*end;
|
||||
char *ptr, *end, *tmp;
|
||||
|
||||
if ((null_value=args[0]->null_value))
|
||||
return 0;
|
||||
/* An empty string is a special case as the string pointer may be null */
|
||||
if (!res->length())
|
||||
return &my_empty_string;
|
||||
res=copy_if_not_alloced(str,res,res->length());
|
||||
ptr = (char *) res->ptr();
|
||||
end=ptr+res->length();
|
||||
if (tmp_value.alloced_length() < res->length() &&
|
||||
tmp_value.realloc(res->length()))
|
||||
{
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
tmp_value.length(res->length());
|
||||
tmp_value.set_charset(res->charset());
|
||||
ptr= (char *) res->ptr();
|
||||
end= ptr + res->length();
|
||||
tmp= (char *) tmp_value.ptr() + tmp_value.length();
|
||||
#ifdef USE_MB
|
||||
if (use_mb(res->charset()))
|
||||
{
|
||||
String tmpstr;
|
||||
tmpstr.copy(*res);
|
||||
char *tmp = (char *) tmpstr.ptr() + tmpstr.length();
|
||||
register uint32 l;
|
||||
while (ptr < end)
|
||||
{
|
||||
if ((l=my_ismbchar(res->charset(), ptr,end)))
|
||||
tmp-=l, memcpy(tmp,ptr,l), ptr+=l;
|
||||
if ((l= my_ismbchar(res->charset(),ptr,end)))
|
||||
{
|
||||
tmp-= l;
|
||||
memcpy(tmp,ptr,l);
|
||||
ptr+= l;
|
||||
}
|
||||
else
|
||||
*--tmp=*ptr++;
|
||||
*--tmp= *ptr++;
|
||||
}
|
||||
memcpy((char *) res->ptr(),(char *) tmpstr.ptr(), res->length());
|
||||
}
|
||||
else
|
||||
#endif /* USE_MB */
|
||||
{
|
||||
char tmp;
|
||||
while (ptr < end)
|
||||
{
|
||||
tmp=*ptr;
|
||||
*ptr++=*--end;
|
||||
*end=tmp;
|
||||
}
|
||||
*--tmp= *ptr++;
|
||||
}
|
||||
return res;
|
||||
return &tmp_value;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ public:
|
|||
|
||||
class Item_func_reverse :public Item_str_func
|
||||
{
|
||||
String tmp_value;
|
||||
public:
|
||||
Item_func_reverse(Item *a) :Item_str_func(a) {}
|
||||
String *val_str(String *);
|
||||
|
|
Loading…
Reference in a new issue