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().
This commit is contained in:
Alexander Barkov 2018-07-19 09:55:19 +04:00
parent ada54101a7
commit ab58493db2
26 changed files with 433 additions and 48 deletions

View File

@ -0,0 +1,15 @@
--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;

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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
#

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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
#

View File

@ -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
# #

View File

@ -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
# #

View File

@ -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

View File

@ -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 #

View File

@ -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

View File

@ -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 #

View File

@ -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 #

View File

@ -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

View File

@ -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 #

View File

@ -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 #

View File

@ -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 #

View File

@ -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 #

View File

@ -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 #

View File

@ -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 #

View File

@ -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 #

View File

@ -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)
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)
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;
} }
} }
} }
@ -1857,13 +1863,16 @@ String *Item_func_substr_index::val_str(String *str)
{ // start counting from the beginning { // start counting from the beginning
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 {
if (!--count) str->copy(res->ptr(), res->length(), collation.collation);
{ return str; // not found, return the original string
tmp_value.set(*res,0,offset); }
break; if (!--count)
} {
str->copy(res->ptr(), offset, collation.collation);
return str;
}
} }
} }
else else
@ -1878,30 +1887,32 @@ String *Item_func_substr_index::val_str(String *str)
address space less than where the found substring is located address space less than where the found substring is located
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
*/ */
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
}
} }
} }
/* DBUG_ASSERT(0);
We always mark tmp_value as const so that if val_str() is called again return NULL;
on this object, we don't disrupt the contents of tmp_value when it was
derived from another String.
*/
tmp_value.mark_as_const();
return (&tmp_value);
} }
/* /*