diff options
author | Alexander Barkov <bar@mariadb.org> | 2015-09-23 13:04:28 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2015-09-23 13:04:28 +0400 |
commit | 212698b152609a7b17b45f9499fd650229985558 (patch) | |
tree | 5f1274679dc91f59cb177c8653d9a9f47db1ccbe | |
parent | 180c44e0f600dc9e220887e213679f0d60f29a68 (diff) | |
download | mariadb-git-212698b152609a7b17b45f9499fd650229985558.tar.gz |
MDEV-8253 EXPLAIN SELECT prints unexpected characters
Item_string::clone_item() creates a new Item_string that
points exactly to the same buffer that the original one does.
Later, Item_string::print() uses c_ptr() for the original Item_string,
which reallocs the original buffer, and the clone remain with
the old freed buffer.
Refactoring the code not to use c_ptr() in Item_string::print().
-rw-r--r-- | mysql-test/r/ctype_latin1.result | 13 | ||||
-rw-r--r-- | mysql-test/r/ctype_ucs.result | 13 | ||||
-rw-r--r-- | mysql-test/t/ctype_latin1.test | 10 | ||||
-rw-r--r-- | mysql-test/t/ctype_ucs.test | 12 | ||||
-rw-r--r-- | sql/item.cc | 20 | ||||
-rw-r--r-- | sql/sql_string.cc | 10 | ||||
-rw-r--r-- | sql/sql_string.h | 10 |
7 files changed, 68 insertions, 20 deletions
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index e518dbb07e0..48475923138 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -8168,5 +8168,18 @@ SELECT * FROM t1 WHERE a=_latin1'a' AND a=_latin1'A'; a DROP TABLE t1; # +# MDEV-8253 EXPLAIN SELECT prints unexpected characters +# +SET NAMES latin1; +CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10)); +INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3'); +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d` from `test`.`t1` where ((coalesce(`test`.`t1`.`c`,0) = '3 ') and (coalesce(`test`.`t1`.`d`,0) = '3 ')) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 22c149c95ba..97617f6c3df 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -5627,5 +5627,18 @@ a 1 DROP TABLE t1; # +# MDEV-8253 EXPLAIN SELECT prints unexpected characters +# +SET NAMES latin1, character_set_connection=ucs2; +CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10)); +INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3'); +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d` from `test`.`t1` where ((coalesce(`test`.`t1`.`c`,0) = '3 ') and (coalesce(`test`.`t1`.`d`,0) = '3 ')) +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/ctype_latin1.test b/mysql-test/t/ctype_latin1.test index 830fa075a39..a30c7ae9a5d 100644 --- a/mysql-test/t/ctype_latin1.test +++ b/mysql-test/t/ctype_latin1.test @@ -364,5 +364,15 @@ SELECT * FROM t1 WHERE a=_latin1'a' AND a=_latin1'A'; DROP TABLE t1; --echo # +--echo # MDEV-8253 EXPLAIN SELECT prints unexpected characters +--echo # +SET NAMES latin1; +CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10)); +INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3'); +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0); +DROP TABLE t1; + +--echo # --echo # End of 10.1 tests --echo # diff --git a/mysql-test/t/ctype_ucs.test b/mysql-test/t/ctype_ucs.test index 18fe32c526b..13f9f5c9b6d 100644 --- a/mysql-test/t/ctype_ucs.test +++ b/mysql-test/t/ctype_ucs.test @@ -934,6 +934,18 @@ INSERT INTO t1 VALUES ('1'); SELECT * FROM t1 WHERE a LIKE 1; DROP TABLE t1; + +--echo # +--echo # MDEV-8253 EXPLAIN SELECT prints unexpected characters +--echo # +SET NAMES latin1, character_set_connection=ucs2; +CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10)); +INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3'); +EXPLAIN EXTENDED +SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0); +DROP TABLE t1; + + --echo # --echo # End of 10.1 tests --echo # diff --git a/sql/item.cc b/sql/item.cc index c75e0562526..c17147bde01 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2939,25 +2939,7 @@ void Item_string::print(String *str, enum_query_type query_type) } else { - if (my_charset_same(str_value.charset(), system_charset_info)) - str_value.print(str); // already in system_charset_info - else // need to convert - { - THD *thd= current_thd; - LEX_STRING utf8_lex_str; - - thd->convert_string(&utf8_lex_str, - system_charset_info, - str_value.c_ptr_safe(), - str_value.length(), - str_value.charset()); - - String utf8_str(utf8_lex_str.str, - utf8_lex_str.length, - system_charset_info); - - utf8_str.print(str); - } + str_value.print(str, system_charset_info); } } else diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 379609ad6e7..b14c3afca4b 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -954,6 +954,16 @@ void String::print(String *str) const str->append_for_single_quote(Ptr, str_length); } + +void String::print_with_conversion(String *print, CHARSET_INFO *cs) const +{ + StringBuffer<256> tmp(cs); + uint errors= 0; + tmp.copy(this, cs, &errors); + tmp.print(print); +} + + /* Exchange state of this object and argument. diff --git a/sql/sql_string.h b/sql/sql_string.h index 99fe6b60d37..51a11c7a4ff 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -568,7 +568,15 @@ public: str_length+= arg_length; return FALSE; } - void print(String *print) const; + void print(String *to) const; + void print_with_conversion(String *to, CHARSET_INFO *cs) const; + void print(String *to, CHARSET_INFO *cs) const + { + if (my_charset_same(charset(), cs)) + print(to); + else + print_with_conversion(to, cs); + } bool append_for_single_quote(const char *st, uint len); bool append_for_single_quote(const String *s) |