diff --git a/dbms/src/Functions/FunctionsString.cpp b/dbms/src/Functions/FunctionsString.cpp index 6197aad1b6b..c428fc7cb35 100644 --- a/dbms/src/Functions/FunctionsString.cpp +++ b/dbms/src/Functions/FunctionsString.cpp @@ -3147,6 +3147,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( @@ -3436,9 +3443,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]; @@ -3497,9 +3502,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]; @@ -3556,9 +3559,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]; @@ -3614,9 +3615,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; @@ -3641,6 +3640,7 @@ class TidbPadImpl if (target_len < 0 || (data_len < static_cast(target_len) && pad_len == 0)) { + addTrailingZero(res, res_offset); return true; } @@ -3692,10 +3692,7 @@ class TidbPadImpl ++left; } } - // Add trailing zero. - res.resize(res.size() + 1); - res[res_offset] = '\0'; - res_offset++; + addTrailingZero(res, res_offset); return false; } @@ -3715,6 +3712,7 @@ class TidbPadImpl if (target_len < 0 || (data_len < static_cast(target_len) && pad_len == 0)) { + addTrailingZero(res, res_offset); return true; } @@ -3767,10 +3765,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..40382763995 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> select crc32(lpad(c1, c2, 'b')) from test.t1 ++--------------------------+ +| crc32(lpad(c1, c2, 'b')) | ++--------------------------+ +| NULL | ++--------------------------+ + +mysql> select crc32(rpad(c1, c2, 'b')) from test.t1 ++--------------------------+ +| crc32(rpad(c1, c2, 'b')) | ++--------------------------+ +| NULL | ++--------------------------+ + +mysql> drop table if exists test.t1