Skip to content

Commit

Permalink
Fix segmentation fault of SUBSTRING (#1903) (#1914)
Browse files Browse the repository at this point in the history
* cherry pick #1903 to release-4.0

Signed-off-by: ti-srebot <ti-srebot@pingcap.com>

* Fix test

Co-authored-by: Yu Lei <leiysky@outlook.com>
  • Loading branch information
ti-srebot and leiysky authored Jul 7, 2021
1 parent 3e1dd3c commit fc39209
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
15 changes: 12 additions & 3 deletions dbms/src/Functions/FunctionsString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,14 +481,14 @@ struct SubstringUTF8Impl
ColumnString::Offset bytes_start = 0;
ColumnString::Offset bytes_length = 0;
size_t start = 0;
if(original_start >= 0)
if (original_start >= 0)
start = original_start;
else
{
// set the start as string_length - abs(original_start) + 1
std::vector<ColumnString::Offset> start_offsets;
ColumnString::Offset current = prev_offset;
while (current < offsets[i] -1)
while (current < offsets[i] - 1)
{
start_offsets.push_back(current);
if (data[current] < 0xBF)
Expand All @@ -500,9 +500,18 @@ struct SubstringUTF8Impl
else
current += 1;
}
if (static_cast<size_t>(-original_start) > start_offsets.size())
{
// return empty string
res_data.resize(res_data.size() + 1);
res_data[res_offset] = 0;
res_offset++;
res_offsets[i] = res_offset;
continue;
}
start = start_offsets.size() + original_start + 1;
pos = start;
j = start_offsets[start-1];
j = start_offsets[start - 1];
}
while (j < offsets[i] - 1)
{
Expand Down
23 changes: 23 additions & 0 deletions tests/fullstack-test/expr/substring_utf8.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
mysql> drop table if exists test.t
mysql> create table test.t(a char(10))
mysql> insert into test.t values(''), ('abc')
mysql> alter table test.t set tiflash replica 1

func> wait_table test t

mysql> set session tidb_isolation_read_engines='tiflash'; select * from test.t where substring(a, -3, 4) = 'abc'
a
abc

mysql> set session tidb_isolation_read_engines='tiflash'; select * from test.t where substring(a, -3, 2) = 'ab'
a
abc

mysql> set session tidb_isolation_read_engines='tiflash'; select * from test.t where substring(a, -4, 3) = 'abc'
# Empty

mysql> set session tidb_isolation_read_engines='tiflash'; select count(*) from test.t where substring(a, 0, 3) = '' order by a
count(*)
2

mysql> drop table if exists test.t

0 comments on commit fc39209

Please sign in to comment.