Commit 66367aee authored by unknown's avatar unknown

Fixed bug #36488: regexp returns false matches, concatenating

                  with previous rows.

The WHERE clause containing expression:
  CONCAT(empty_field1, empty_field2, ..., 'literal constant', ...)
    REGEXP 'regular expression'
may return wrong matches.

Optimization of the CONCAT function has been fixed.



mysql-test/r/func_concat.result:
  Added test case for bug #36488.
mysql-test/t/func_concat.test:
  Added test case for bug #36488.
sql/item_strfunc.cc:
  Fixed bug #36488.
  The Item_func_concat::val_str method is optimized to
  use first non-empty argument of the CONCAT function for in-place
  result accumulation. This optimization is acceptable if that
  first argument is not a constant.
  However, current implementation checks this condition only for
  the first actual argument of the CONCAT function.
  So, the Item_func_concat::val_str method can corrupt values
  of, for example, literal strings by appending random data.
  
  The Item_func_concat::val_str method has been modified to take
  into account the ability to be modified in-place for the first
  non-empty argument.
parent 65a310fe
...@@ -82,3 +82,10 @@ a ...@@ -82,3 +82,10 @@ a
1234562 1234562
x x
drop table t1; drop table t1;
CREATE TABLE t1 (c1 varchar(100), c2 varchar(100));
INSERT INTO t1 VALUES ('',''), ('','First'), ('Random','Random');
SELECT * FROM t1 WHERE CONCAT(c1,' ',c2) REGEXP 'First.*';
c1 c2
First
DROP TABLE t1;
# End of 5.0 tests
...@@ -68,3 +68,13 @@ create table t1(f1 varchar(6)) charset=utf8; ...@@ -68,3 +68,13 @@ create table t1(f1 varchar(6)) charset=utf8;
insert into t1 values ("123456"); insert into t1 values ("123456");
select concat(f1, 2) a from t1 union select 'x' a from t1; select concat(f1, 2) a from t1 union select 'x' a from t1;
drop table t1; drop table t1;
#
# Bug #36488: regexp returns false matches, concatenating with previous rows
#
CREATE TABLE t1 (c1 varchar(100), c2 varchar(100));
INSERT INTO t1 VALUES ('',''), ('','First'), ('Random','Random');
SELECT * FROM t1 WHERE CONCAT(c1,' ',c2) REGEXP 'First.*';
DROP TABLE t1;
--echo # End of 5.0 tests
...@@ -294,6 +294,12 @@ String *Item_func_concat::val_str(String *str) ...@@ -294,6 +294,12 @@ String *Item_func_concat::val_str(String *str)
{ {
if (!(res=args[i]->val_str(str))) if (!(res=args[i]->val_str(str)))
goto null; goto null;
/*
CONCAT accumulates its result in the result of its the first
non-empty argument. Because of this we need is_const to be
evaluated only for it.
*/
is_const= args[i]->const_item() || !args[i]->used_tables();
} }
else else
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment