Commit ab58493d authored by Alexander Barkov's avatar Alexander Barkov

MDEV-13118 Wrong results with LOWER and UPPER and subquery

This problem is similar to MDEV-10306.

1. Fixing Item_str_conv::val_str(String *str) to return the result in "str",
   and to use tmp_value only as a temporary buffer for args[0]->val_str().
   The new code version now guarantees that the result is always returned in
   "str". The trick with copy_if_not_alloced() is not used any more.

2. The change #1 revealed the same problem in SUBSTRING_INDEX(),
   so some tests with combinations of UPPER()/LOWER() and SUBSTRING_INDEX()
   started to fail. Fixing Item_func_substr_index::val_str() the same way,
   to return the result in "str" and use tmp_value as a temporary buffer
   for args[0]->val_str().
parent ada54101
--echo #
--echo # MDEV-13118 Wrong results with LOWER and UPPER and subquery
--echo #
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
--sorted_result
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
--sorted_result
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
...@@ -3022,6 +3022,29 @@ DROP TABLE t1; ...@@ -3022,6 +3022,29 @@ DROP TABLE t1;
SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; SELECT _binary 0x7E, _binary X'7E', _binary B'01111110';
_binary 0x7E _binary X'7E' _binary B'01111110' _binary 0x7E _binary X'7E' _binary B'01111110'
~ ~ ~ ~ ~ ~
SET NAMES utf8, character_set_connection=binary;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varbinary(10) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
abcdefghi-abcdefghi
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -33636,6 +33636,29 @@ HEX(a) CHAR_LENGTH(a) ...@@ -33636,6 +33636,29 @@ HEX(a) CHAR_LENGTH(a)
DROP TABLE t1; DROP TABLE t1;
SELECT _eucjpms 0x8EA0; SELECT _eucjpms 0x8EA0;
ERROR HY000: Invalid eucjpms character string: '8EA0' ERROR HY000: Invalid eucjpms character string: '8EA0'
SET NAMES eucjpms;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET eucjpms NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -25274,3 +25274,32 @@ A1A1A1A1A1A120202020202020202020202020202020202020 ...@@ -25274,3 +25274,32 @@ A1A1A1A1A1A120202020202020202020202020202020202020
# #
# End of 5.6 tests # End of 5.6 tests
# #
#
# Start of 10.0 tests
#
SET NAMES utf8, character_set_connection=euckr;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET euckr NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
#
# End of 10.0 tests
#
...@@ -4943,6 +4943,29 @@ E05C5B ...@@ -4943,6 +4943,29 @@ E05C5B
E05B E05B
DROP TABLE t1; DROP TABLE t1;
# Start of ctype_E05C.inc # Start of ctype_E05C.inc
SET NAMES utf8, character_set_connection=gbk;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET gbk NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
# #
......
...@@ -7939,6 +7939,29 @@ a ...@@ -7939,6 +7939,29 @@ a
0 0
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
SET NAMES latin1;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -5629,6 +5629,29 @@ c2 ...@@ -5629,6 +5629,29 @@ c2
YWJjZGVmZ2hp-YWJjZGVmZ2hp YWJjZGVmZ2hp-YWJjZGVmZ2hp
DROP TABLE t1; DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch; SET optimizer_switch=@save_optimizer_switch;
SET NAMES utf8, character_set_connection=ucs2;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET ucs2 NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -25942,6 +25942,29 @@ HEX(a) CHAR_LENGTH(a) ...@@ -25942,6 +25942,29 @@ HEX(a) CHAR_LENGTH(a)
DROP TABLE t1; DROP TABLE t1;
SELECT _ujis 0x8EA0; SELECT _ujis 0x8EA0;
ERROR HY000: Invalid ujis character string: '8EA0' ERROR HY000: Invalid ujis character string: '8EA0'
SET NAMES ujis;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET ujis NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -2134,6 +2134,29 @@ EXECUTE stmt USING @arg00; ...@@ -2134,6 +2134,29 @@ EXECUTE stmt USING @arg00;
CONCAT(_utf16'a' COLLATE utf16_unicode_ci, ?) CONCAT(_utf16'a' COLLATE utf16_unicode_ci, ?)
aÿ aÿ
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
SET NAMES utf8, character_set_connection=utf16;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET utf16 NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -2319,3 +2319,32 @@ DFFFFFDFFFFF9CFFFF9DFFFF9EFFFF ...@@ -2319,3 +2319,32 @@ DFFFFFDFFFFF9CFFFF9DFFFF9EFFFF
# #
# End of 5.6 tests # End of 5.6 tests
# #
#
# Start of 10.0 tests
#
SET NAMES utf8, character_set_connection=utf16le;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET utf16le NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
#
# Start of 10.0 tests
#
...@@ -2231,6 +2231,29 @@ EXECUTE stmt USING @arg00; ...@@ -2231,6 +2231,29 @@ EXECUTE stmt USING @arg00;
CONCAT(_utf32'a' COLLATE utf32_unicode_ci, ?) CONCAT(_utf32'a' COLLATE utf32_unicode_ci, ?)
aÿ aÿ
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
SET NAMEs utf8, character_set_connection=utf32;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET utf32 NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -10127,6 +10127,29 @@ SELECT * FROM v1; ...@@ -10127,6 +10127,29 @@ SELECT * FROM v1;
c c
ß ß
DROP VIEW v1; DROP VIEW v1;
SET NAMES utf8;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET utf8 NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# #
# End of 10.0 tests # End of 10.0 tests
# #
...@@ -3427,6 +3427,29 @@ t1 CREATE TABLE `t1` ( ...@@ -3427,6 +3427,29 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1; DROP TABLE t1;
SET NAMES default; SET NAMES default;
SET NAMES utf8mb4;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET @save_optimizer_switch=@@optimizer_switch;
SET optimizer_switch=_latin1'derived_merge=on';
CREATE TABLE t1 AS SELECT REPEAT('a', 10) AS t LIMIT 0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`t` varchar(10) CHARACTER SET utf8mb4 NOT NULL DEFAULT ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
INSERT INTO t1 VALUES ('abcdefghi'),('ABCDEFGHI');
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT LOWER(t) t2 FROM t1) sub;
c2
abcdefghi-abcdefghi
abcdefghi-abcdefghi
SELECT CONCAT(t2,'-',t2) c2 FROM (SELECT UPPER(t) t2 FROM t1) sub;
c2
ABCDEFGHI-ABCDEFGHI
ABCDEFGHI-ABCDEFGHI
DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
# End of 10.0 tests # End of 10.0 tests
# #
# End of tests # End of tests
......
...@@ -24,6 +24,9 @@ SET NAMES binary; ...@@ -24,6 +24,9 @@ SET NAMES binary;
--echo # --echo #
SELECT _binary 0x7E, _binary X'7E', _binary B'01111110'; SELECT _binary 0x7E, _binary X'7E', _binary B'01111110';
SET NAMES utf8, character_set_connection=binary;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
...@@ -536,6 +536,8 @@ DROP TABLE t1; ...@@ -536,6 +536,8 @@ DROP TABLE t1;
--error ER_INVALID_CHARACTER_STRING --error ER_INVALID_CHARACTER_STRING
SELECT _eucjpms 0x8EA0; SELECT _eucjpms 0x8EA0;
SET NAMES eucjpms;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
......
...@@ -197,3 +197,14 @@ set collation_connection=euckr_bin; ...@@ -197,3 +197,14 @@ set collation_connection=euckr_bin;
--echo # End of 5.6 tests --echo # End of 5.6 tests
--echo # --echo #
--echo #
--echo # Start of 10.0 tests
--echo #
SET NAMES utf8, character_set_connection=euckr;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
...@@ -199,6 +199,9 @@ let $ctype_unescape_combinations=selected; ...@@ -199,6 +199,9 @@ let $ctype_unescape_combinations=selected;
SET NAMES gbk; SET NAMES gbk;
--source include/ctype_E05C.inc --source include/ctype_E05C.inc
SET NAMES utf8, character_set_connection=gbk;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant --echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
--echo # --echo #
......
...@@ -260,6 +260,9 @@ SELECT * FROM v1; ...@@ -260,6 +260,9 @@ SELECT * FROM v1;
DROP VIEW v1; DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
SET NAMES latin1;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
......
...@@ -984,6 +984,10 @@ DROP TABLE t1; ...@@ -984,6 +984,10 @@ DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch; SET optimizer_switch=@save_optimizer_switch;
SET NAMES utf8, character_set_connection=ucs2;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
...@@ -1366,6 +1366,10 @@ DROP TABLE t1; ...@@ -1366,6 +1366,10 @@ DROP TABLE t1;
SELECT _ujis 0x8EA0; SELECT _ujis 0x8EA0;
SET NAMES ujis;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
...@@ -866,6 +866,11 @@ SET @arg00=_binary 0x00FF; ...@@ -866,6 +866,11 @@ SET @arg00=_binary 0x00FF;
EXECUTE stmt USING @arg00; EXECUTE stmt USING @arg00;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
SET NAMES utf8, character_set_connection=utf16;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
...@@ -744,3 +744,16 @@ SET NAMES utf8, collation_connection=utf16le_bin; ...@@ -744,3 +744,16 @@ SET NAMES utf8, collation_connection=utf16le_bin;
--echo # --echo #
--echo # End of 5.6 tests --echo # End of 5.6 tests
--echo # --echo #
--echo #
--echo # Start of 10.0 tests
--echo #
SET NAMES utf8, character_set_connection=utf16le;
--source include/ctype_mdev13118.inc
--echo #
--echo # Start of 10.0 tests
--echo #
...@@ -979,6 +979,14 @@ SET @arg00=_binary 0x00FF; ...@@ -979,6 +979,14 @@ SET @arg00=_binary 0x00FF;
EXECUTE stmt USING @arg00; EXECUTE stmt USING @arg00;
DEALLOCATE PREPARE stmt; DEALLOCATE PREPARE stmt;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET NAMEs utf8, character_set_connection=utf32;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
......
...@@ -1880,6 +1880,13 @@ SELECT * FROM v1; ...@@ -1880,6 +1880,13 @@ SELECT * FROM v1;
DROP VIEW v1; DROP VIEW v1;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET NAMES utf8;
--source include/ctype_mdev13118.inc
--echo # --echo #
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
...@@ -1913,6 +1913,14 @@ DROP TABLE t1; ...@@ -1913,6 +1913,14 @@ DROP TABLE t1;
SET NAMES default; SET NAMES default;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET NAMES utf8mb4;
--source include/ctype_mdev13118.inc
--echo # End of 10.0 tests --echo # End of 10.0 tests
--echo # --echo #
......
...@@ -1566,32 +1566,27 @@ String *Item_str_conv::val_str(String *str) ...@@ -1566,32 +1566,27 @@ String *Item_str_conv::val_str(String *str)
{ {
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
String *res; String *res;
if (!(res=args[0]->val_str(str))) uint alloced_length, len;
{
null_value=1; /* purecov: inspected */ if ((null_value= (!(res= args[0]->val_str(&tmp_value)) ||
return 0; /* purecov: inspected */ str->alloc((alloced_length= res->length() * multiply)))))
} return 0;
null_value=0;
if (multiply == 1) if (multiply == 1)
{ {
uint len; str->copy(*res); // Should not fail (it was alloced above)
res= copy_if_not_alloced(&tmp_value, res, res->length()); len= converter(collation.collation, (char*) str->ptr(), str->length(),
len= converter(collation.collation, (char*) res->ptr(), res->length(), (char*) str->ptr(), alloced_length);
(char*) res->ptr(), res->length());
DBUG_ASSERT(len <= res->length());
res->length(len);
} }
else else
{ {
uint len= res->length() * multiply;
tmp_value.alloc(len);
tmp_value.set_charset(collation.collation);
len= converter(collation.collation, (char*) res->ptr(), res->length(), len= converter(collation.collation, (char*) res->ptr(), res->length(),
(char*) tmp_value.ptr(), len); (char*) str->ptr(), alloced_length);
tmp_value.length(len); str->set_charset(collation.collation);
res= &tmp_value;
} }
return res; DBUG_ASSERT(len <= alloced_length);
str->length(len);
return str;
} }
...@@ -1783,7 +1778,7 @@ String *Item_func_substr_index::val_str(String *str) ...@@ -1783,7 +1778,7 @@ String *Item_func_substr_index::val_str(String *str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
char buff[MAX_FIELD_WIDTH]; char buff[MAX_FIELD_WIDTH];
String tmp(buff,sizeof(buff),system_charset_info); String tmp(buff,sizeof(buff),system_charset_info);
String *res= args[0]->val_str(str); String *res= args[0]->val_str(&tmp_value);
String *delimiter= args[1]->val_str(&tmp); String *delimiter= args[1]->val_str(&tmp);
int32 count= (int32) args[2]->val_int(); int32 count= (int32) args[2]->val_int();
uint offset; uint offset;
...@@ -1832,20 +1827,31 @@ String *Item_func_substr_index::val_str(String *str) ...@@ -1832,20 +1827,31 @@ String *Item_func_substr_index::val_str(String *str)
if (pass == 0) /* count<0 */ if (pass == 0) /* count<0 */
{ {
c+=n+1; c+=n+1;
if (c<=0) return res; /* not found, return original string */ if (c<=0)
{
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
}
ptr=res->ptr(); ptr=res->ptr();
} }
else else
{ {
if (c) return res; /* Not found, return original string */ if (c)
{
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
}
if (count>0) /* return left part */ if (count>0) /* return left part */
{ {
tmp_value.set(*res,0,(ulong) (ptr-res->ptr())); str->copy(res->ptr(), (uint32) (ptr-res->ptr()), collation.collation);
return str;
} }
else /* return right part */ else /* return right part */
{ {
ptr+= delimiter_length; ptr+= delimiter_length;
tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr)); str->copy(res->ptr() + (ptr-res->ptr()), (uint32) (strend - ptr),
collation.collation);
return str;
} }
} }
} }
...@@ -1858,11 +1864,14 @@ String *Item_func_substr_index::val_str(String *str) ...@@ -1858,11 +1864,14 @@ String *Item_func_substr_index::val_str(String *str)
for (offset=0; ; offset+= delimiter_length) for (offset=0; ; offset+= delimiter_length)
{ {
if ((int) (offset= res->strstr(*delimiter, offset)) < 0) if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
return res; // Didn't find, return org string {
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
}
if (!--count) if (!--count)
{ {
tmp_value.set(*res,0,offset); str->copy(res->ptr(), offset, collation.collation);
break; return str;
} }
} }
} }
...@@ -1879,7 +1888,10 @@ String *Item_func_substr_index::val_str(String *str) ...@@ -1879,7 +1888,10 @@ String *Item_func_substr_index::val_str(String *str)
in res in res
*/ */
if ((int) (offset= res->strrstr(*delimiter, offset)) < 0) if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
return res; // Didn't find, return org string {
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
}
/* /*
At this point, we've searched for the substring At this point, we've searched for the substring
the number of times as supplied by the index value the number of times as supplied by the index value
...@@ -1887,21 +1899,20 @@ String *Item_func_substr_index::val_str(String *str) ...@@ -1887,21 +1899,20 @@ String *Item_func_substr_index::val_str(String *str)
if (!++count) if (!++count)
{ {
offset+= delimiter_length; offset+= delimiter_length;
tmp_value.set(*res,offset,res->length()- offset); str->copy(res->ptr() + offset, res->length() - offset,
break; collation.collation);
return str;
} }
} }
if (count) if (count)
return res; // Didn't find, return org string {
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
} }
} }
/* }
We always mark tmp_value as const so that if val_str() is called again DBUG_ASSERT(0);
on this object, we don't disrupt the contents of tmp_value when it was return NULL;
derived from another String.
*/
tmp_value.mark_as_const();
return (&tmp_value);
} }
/* /*
......
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