diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index dd37d46b65d..325167ad753 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -3030,6 +3030,13 @@ class FunctionTiDBTrim : public IFunction class TidbPadImpl { + static void addTrailingZero(ColumnString::Chars_t & res, ColumnString::Offset & res_offset) + { + res.resize(res.size() + 1); + res[res_offset] = '\0'; + ++res_offset; + } + public: template static void tidbExecutePadImpl(Block & block, const ColumnNumbers & arguments, const size_t result, const String & func_name) @@ -3209,9 +3216,7 @@ class TidbPadImpl } else { - result_data.resize(result_data.size() + 1); - result_data[res_prev_offset] = '\0'; - res_prev_offset++; + addTrailingZero(result_data, res_prev_offset); } string_prev_offset = string_offsets[i]; @@ -3246,9 +3251,7 @@ class TidbPadImpl } else { - result_data.resize(result_data.size() + 1); - result_data[res_prev_offset] = '\0'; - res_prev_offset++; + addTrailingZero(result_data, res_prev_offset); } string_prev_offset = string_offsets[i]; @@ -3282,9 +3285,7 @@ class TidbPadImpl } else { - result_data.resize(result_data.size() + 1); - result_data[res_prev_offset] = '\0'; - res_prev_offset++; + addTrailingZero(result_data, res_prev_offset); } padding_prev_offset = (*padding_offsets)[i]; @@ -3317,9 +3318,7 @@ class TidbPadImpl } else { - result_data.resize(result_data.size() + 1); - result_data[res_prev_offset] = '\0'; - res_prev_offset++; + addTrailingZero(result_data, res_prev_offset); } result_offsets[i] = res_prev_offset; @@ -3337,6 +3336,7 @@ class TidbPadImpl if (target_len < 0 || (data_len < static_cast(target_len) && pad_len == 0)) { + addTrailingZero(res, res_offset); return true; } @@ -3388,10 +3388,7 @@ class TidbPadImpl ++left; } } - // Add trailing zero. - res.resize(res.size() + 1); - res[res_offset] = '\0'; - res_offset++; + addTrailingZero(res, res_offset); return false; } @@ -3404,6 +3401,7 @@ class TidbPadImpl if (target_len < 0 || (data_len < static_cast(target_len) && pad_len == 0)) { + addTrailingZero(res, res_offset); return true; } @@ -3456,10 +3454,7 @@ class TidbPadImpl copyResult(res, res_offset, data, 0, tmp_target_len); res_offset += tmp_target_len; } - // Add trailing zero. - res.resize(res.size() + 1); - res[res_offset] = '\0'; - res_offset++; + addTrailingZero(res, res_offset); return false; } diff --git a/tests/fullstack-test/expr/pad.test b/tests/fullstack-test/expr/pad.test index 890eae62e91..fc12496679e 100644 --- a/tests/fullstack-test/expr/pad.test +++ b/tests/fullstack-test/expr/pad.test @@ -111,3 +111,27 @@ mysql> set tidb_isolation_read_engines='tiflash'; set tidb_enforce_mpp=1; select mysql> set tidb_isolation_read_engines='tiflash'; set tidb_enforce_mpp=1; SELECT max(lpad('y',0,c1)) FROM test.t2 max(lpad('y',0,c1)) + + +mysql> drop table if exists test.t1 +mysql> create table test.t1(c1 varchar(100), c2 int) +mysql> alter table test.t1 set tiflash replica 1 +mysql> insert into test.t1 values('a', -1) +func> wait_table test t1 + +# crc32 will call ColumnString::getDataAt(i), which assume all string rows ends with '\0'. +mysql> set tidb_isolation_read_engines='tiflash'; set tidb_enforce_mpp=1; select crc32(lpad(c1, c2, 'b')) from test.t1 ++--------------------------+ +| crc32(lpad(c1, c2, 'b')) | ++--------------------------+ +| NULL | ++--------------------------+ + +mysql> set tidb_isolation_read_engines='tiflash'; set tidb_enforce_mpp=1; select crc32(rpad(c1, c2, 'b')) from test.t1 ++--------------------------+ +| crc32(rpad(c1, c2, 'b')) | ++--------------------------+ +| NULL | ++--------------------------+ + +mysql> drop table if exists test.t1