Skip to content

Commit 212698b

Browse files
author
Alexander Barkov
committed
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().
1 parent 180c44e commit 212698b

File tree

7 files changed

+68
-20
lines changed

7 files changed

+68
-20
lines changed

mysql-test/r/ctype_latin1.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8168,5 +8168,18 @@ SELECT * FROM t1 WHERE a=_latin1'a' AND a=_latin1'A';
81688168
a
81698169
DROP TABLE t1;
81708170
#
8171+
# MDEV-8253 EXPLAIN SELECT prints unexpected characters
8172+
#
8173+
SET NAMES latin1;
8174+
CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10));
8175+
INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3');
8176+
EXPLAIN EXTENDED
8177+
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
8178+
id select_type table type possible_keys key key_len ref rows filtered Extra
8179+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
8180+
Warnings:
8181+
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 '))
8182+
DROP TABLE t1;
8183+
#
81718184
# End of 10.1 tests
81728185
#

mysql-test/r/ctype_ucs.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5627,5 +5627,18 @@ a
56275627
1
56285628
DROP TABLE t1;
56295629
#
5630+
# MDEV-8253 EXPLAIN SELECT prints unexpected characters
5631+
#
5632+
SET NAMES latin1, character_set_connection=ucs2;
5633+
CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10));
5634+
INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3');
5635+
EXPLAIN EXTENDED
5636+
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
5637+
id select_type table type possible_keys key key_len ref rows filtered Extra
5638+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
5639+
Warnings:
5640+
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 '))
5641+
DROP TABLE t1;
5642+
#
56305643
# End of 10.1 tests
56315644
#

mysql-test/t/ctype_latin1.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,16 @@ SELECT * FROM t1 WHERE a=_latin1'A' AND a=_latin1'a';
363363
SELECT * FROM t1 WHERE a=_latin1'a' AND a=_latin1'A';
364364
DROP TABLE t1;
365365

366+
--echo #
367+
--echo # MDEV-8253 EXPLAIN SELECT prints unexpected characters
368+
--echo #
369+
SET NAMES latin1;
370+
CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10));
371+
INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3');
372+
EXPLAIN EXTENDED
373+
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
374+
DROP TABLE t1;
375+
366376
--echo #
367377
--echo # End of 10.1 tests
368378
--echo #

mysql-test/t/ctype_ucs.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,18 @@ INSERT INTO t1 VALUES ('1');
934934
SELECT * FROM t1 WHERE a LIKE 1;
935935
DROP TABLE t1;
936936

937+
938+
--echo #
939+
--echo # MDEV-8253 EXPLAIN SELECT prints unexpected characters
940+
--echo #
941+
SET NAMES latin1, character_set_connection=ucs2;
942+
CREATE TABLE t1 (a DECIMAL(10,1),b DECIMAL(10,1),c VARCHAR(10),d VARCHAR(10));
943+
INSERT INTO t1 VALUES (1.5,1.5,'1','1'),(3.5,3.5,'3','3');
944+
EXPLAIN EXTENDED
945+
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
946+
DROP TABLE t1;
947+
948+
937949
--echo #
938950
--echo # End of 10.1 tests
939951
--echo #

sql/item.cc

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,25 +2939,7 @@ void Item_string::print(String *str, enum_query_type query_type)
29392939
}
29402940
else
29412941
{
2942-
if (my_charset_same(str_value.charset(), system_charset_info))
2943-
str_value.print(str); // already in system_charset_info
2944-
else // need to convert
2945-
{
2946-
THD *thd= current_thd;
2947-
LEX_STRING utf8_lex_str;
2948-
2949-
thd->convert_string(&utf8_lex_str,
2950-
system_charset_info,
2951-
str_value.c_ptr_safe(),
2952-
str_value.length(),
2953-
str_value.charset());
2954-
2955-
String utf8_str(utf8_lex_str.str,
2956-
utf8_lex_str.length,
2957-
system_charset_info);
2958-
2959-
utf8_str.print(str);
2960-
}
2942+
str_value.print(str, system_charset_info);
29612943
}
29622944
}
29632945
else

sql/sql_string.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,16 @@ void String::print(String *str) const
954954
str->append_for_single_quote(Ptr, str_length);
955955
}
956956

957+
958+
void String::print_with_conversion(String *print, CHARSET_INFO *cs) const
959+
{
960+
StringBuffer<256> tmp(cs);
961+
uint errors= 0;
962+
tmp.copy(this, cs, &errors);
963+
tmp.print(print);
964+
}
965+
966+
957967
/*
958968
Exchange state of this object and argument.
959969

sql/sql_string.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,15 @@ class String
568568
str_length+= arg_length;
569569
return FALSE;
570570
}
571-
void print(String *print) const;
571+
void print(String *to) const;
572+
void print_with_conversion(String *to, CHARSET_INFO *cs) const;
573+
void print(String *to, CHARSET_INFO *cs) const
574+
{
575+
if (my_charset_same(charset(), cs))
576+
print(to);
577+
else
578+
print_with_conversion(to, cs);
579+
}
572580

573581
bool append_for_single_quote(const char *st, uint len);
574582
bool append_for_single_quote(const String *s)

0 commit comments

Comments
 (0)