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;
SELECT _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
#
......@@ -33636,6 +33636,29 @@ HEX(a) CHAR_LENGTH(a)
DROP TABLE t1;
SELECT _eucjpms 0x8EA0;
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
#
......@@ -25274,3 +25274,32 @@ A1A1A1A1A1A120202020202020202020202020202020202020
#
# 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
E05B
DROP TABLE t1;
# 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
#
......
......@@ -7939,6 +7939,29 @@ a
0
DROP VIEW v1;
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
#
......@@ -5629,6 +5629,29 @@ c2
YWJjZGVmZ2hp-YWJjZGVmZ2hp
DROP TABLE t1;
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
#
......@@ -25942,6 +25942,29 @@ HEX(a) CHAR_LENGTH(a)
DROP TABLE t1;
SELECT _ujis 0x8EA0;
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
#
......@@ -2134,6 +2134,29 @@ EXECUTE stmt USING @arg00;
CONCAT(_utf16'a' COLLATE utf16_unicode_ci, ?)
aÿ
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
#
......@@ -2319,3 +2319,32 @@ DFFFFFDFFFFF9CFFFF9DFFFF9EFFFF
#
# 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;
CONCAT(_utf32'a' COLLATE utf32_unicode_ci, ?)
aÿ
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
#
......@@ -10127,6 +10127,29 @@ SELECT * FROM v1;
c
ß
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
#
......@@ -3427,6 +3427,29 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
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 tests
......
......@@ -24,6 +24,9 @@ SET NAMES binary;
--echo #
SELECT _binary 0x7E, _binary X'7E', _binary B'01111110';
SET NAMES utf8, character_set_connection=binary;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -536,6 +536,8 @@ DROP TABLE t1;
--error ER_INVALID_CHARACTER_STRING
SELECT _eucjpms 0x8EA0;
SET NAMES eucjpms;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
......
......@@ -197,3 +197,14 @@ set collation_connection=euckr_bin;
--echo # End of 5.6 tests
--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;
SET NAMES gbk;
--source include/ctype_E05C.inc
SET NAMES utf8, character_set_connection=gbk;
--source include/ctype_mdev13118.inc
--echo #
--echo # MDEV-9886 Illegal mix of collations with a view comparing a field to a binary constant
--echo #
......
......@@ -260,6 +260,9 @@ SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;
SET NAMES latin1;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
......
......@@ -984,6 +984,10 @@ DROP TABLE t1;
SET optimizer_switch=@save_optimizer_switch;
SET NAMES utf8, character_set_connection=ucs2;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -1366,6 +1366,10 @@ DROP TABLE t1;
SELECT _ujis 0x8EA0;
SET NAMES ujis;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -866,6 +866,11 @@ SET @arg00=_binary 0x00FF;
EXECUTE stmt USING @arg00;
DEALLOCATE PREPARE stmt;
SET NAMES utf8, character_set_connection=utf16;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -744,3 +744,16 @@ SET NAMES utf8, collation_connection=utf16le_bin;
--echo #
--echo # End of 5.6 tests
--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;
EXECUTE stmt USING @arg00;
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 # End of 10.0 tests
--echo #
......
......@@ -1880,6 +1880,13 @@ SELECT * FROM v1;
DROP VIEW v1;
#
# MDEV-13118 Wrong results with LOWER and UPPER and subquery
#
SET NAMES utf8;
--source include/ctype_mdev13118.inc
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -1913,6 +1913,14 @@ DROP TABLE t1;
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 #
......
......@@ -1566,32 +1566,27 @@ String *Item_str_conv::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String *res;
if (!(res=args[0]->val_str(str)))
{
null_value=1; /* purecov: inspected */
return 0; /* purecov: inspected */
}
null_value=0;
uint alloced_length, len;
if ((null_value= (!(res= args[0]->val_str(&tmp_value)) ||
str->alloc((alloced_length= res->length() * multiply)))))
return 0;
if (multiply == 1)
{
uint len;
res= copy_if_not_alloced(&tmp_value, res, res->length());
len= converter(collation.collation, (char*) res->ptr(), res->length(),
(char*) res->ptr(), res->length());
DBUG_ASSERT(len <= res->length());
res->length(len);
str->copy(*res); // Should not fail (it was alloced above)
len= converter(collation.collation, (char*) str->ptr(), str->length(),
(char*) str->ptr(), alloced_length);
}
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(),
(char*) tmp_value.ptr(), len);
tmp_value.length(len);
res= &tmp_value;
(char*) str->ptr(), alloced_length);
str->set_charset(collation.collation);
}
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);
char buff[MAX_FIELD_WIDTH];
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);
int32 count= (int32) args[2]->val_int();
uint offset;
......@@ -1832,20 +1827,31 @@ String *Item_func_substr_index::val_str(String *str)
if (pass == 0) /* count<0 */
{
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();
}
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 */
{
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 */
{
ptr+= delimiter_length;
tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
ptr+= delimiter_length;
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
for (offset=0; ; offset+= delimiter_length)
{
if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
return res; // Didn't find, return org string
if (!--count)
{
tmp_value.set(*res,0,offset);
break;
}
if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
{
str->copy(res->ptr(), res->length(), collation.collation);
return str; // not found, return the original string
}
if (!--count)
{
str->copy(res->ptr(), offset, collation.collation);
return str;
}
}
}
else
......@@ -1878,30 +1887,32 @@ String *Item_func_substr_index::val_str(String *str)
address space less than where the found substring is located
in res
*/
if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
return res; // Didn't find, return org string
if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
{
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
the number of times as supplied by the index value
*/
if (!++count)
{
offset+= delimiter_length;
tmp_value.set(*res,offset,res->length()- offset);
break;
}
if (!++count)
{
offset+= delimiter_length;
str->copy(res->ptr() + offset, res->length() - offset,
collation.collation);
return str;
}
}
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
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);
DBUG_ASSERT(0);
return NULL;
}
/*
......
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