From 66367aeea83a0cd7f583a0194651a235b63975a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 May 2008 20:27:46 +0500 Subject: [PATCH] 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. --- mysql-test/r/func_concat.result | 7 +++++++ mysql-test/t/func_concat.test | 10 ++++++++++ sql/item_strfunc.cc | 6 ++++++ 3 files changed, 23 insertions(+) diff --git a/mysql-test/r/func_concat.result b/mysql-test/r/func_concat.result index 66808afd4e9..7e7c163716e 100644 --- a/mysql-test/r/func_concat.result +++ b/mysql-test/r/func_concat.result @@ -82,3 +82,10 @@ a 1234562 x 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 diff --git a/mysql-test/t/func_concat.test b/mysql-test/t/func_concat.test index 5487ad9c56b..f2aa0d004e5 100644 --- a/mysql-test/t/func_concat.test +++ b/mysql-test/t/func_concat.test @@ -68,3 +68,13 @@ create table t1(f1 varchar(6)) charset=utf8; insert into t1 values ("123456"); select concat(f1, 2) a from t1 union select 'x' a from 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 diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 4e72f117869..c443364ce52 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -294,6 +294,12 @@ String *Item_func_concat::val_str(String *str) { if (!(res=args[i]->val_str(str))) 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 {