summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2015-09-23 13:04:28 +0400
committerAlexander Barkov <bar@mariadb.org>2015-09-23 13:04:28 +0400
commit212698b152609a7b17b45f9499fd650229985558 (patch)
tree5f1274679dc91f59cb177c8653d9a9f47db1ccbe
parent180c44e0f600dc9e220887e213679f0d60f29a68 (diff)
downloadmariadb-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.result13
-rw-r--r--mysql-test/r/ctype_ucs.result13
-rw-r--r--mysql-test/t/ctype_latin1.test10
-rw-r--r--mysql-test/t/ctype_ucs.test12
-rw-r--r--sql/item.cc20
-rw-r--r--sql/sql_string.cc10
-rw-r--r--sql/sql_string.h10
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)