From c46a0ab5f07a3053138ebac152b2a667381352f7 Mon Sep 17 00:00:00 2001 From: Leonid Fedorov <79837786+mariadb-LeonidFedorov@users.noreply.github.com> Date: Mon, 5 Feb 2024 18:31:57 +0300 Subject: [PATCH] bug(funcexp): Fixes MCOL-5599 where LIKE operator never finishes (#3116) This is a fix of logging subsystem, nothing else. The old code expanded an argument into string and advanced too little and, if expansion contained argument's index, it expanded it again. And again. Co-authored-by: Serguey Zefirov --- .../basic/r/MCOL-5599-like-never-finishes.result | 7 +++++++ .../basic/t/MCOL-5599-like-never-finishes.test | 11 +++++++++++ utils/loggingcpp/format.h | 15 +++++++++++++-- 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 mysql-test/columnstore/basic/r/MCOL-5599-like-never-finishes.result create mode 100644 mysql-test/columnstore/basic/t/MCOL-5599-like-never-finishes.test diff --git a/mysql-test/columnstore/basic/r/MCOL-5599-like-never-finishes.result b/mysql-test/columnstore/basic/r/MCOL-5599-like-never-finishes.result new file mode 100644 index 000000000..e6aabb2a4 --- /dev/null +++ b/mysql-test/columnstore/basic/r/MCOL-5599-like-never-finishes.result @@ -0,0 +1,7 @@ +DROP DATABASE IF EXISTS MCOL5599; +CREATE DATABASE MCOL5599; +USE MCOL5599; +CREATE TABLE t (t TEXT) ENGINE = COLUMNSTORE; +SELECT * FROM t WHERE t LIKE '%1%'; +t +DROP DATABASE MCOL5599; diff --git a/mysql-test/columnstore/basic/t/MCOL-5599-like-never-finishes.test b/mysql-test/columnstore/basic/t/MCOL-5599-like-never-finishes.test new file mode 100644 index 000000000..4cd01f33b --- /dev/null +++ b/mysql-test/columnstore/basic/t/MCOL-5599-like-never-finishes.test @@ -0,0 +1,11 @@ +--disable_warnings +DROP DATABASE IF EXISTS MCOL5599; +--enable_warnings +CREATE DATABASE MCOL5599; +USE MCOL5599; +CREATE TABLE t (t TEXT) ENGINE = COLUMNSTORE; +# This tests logging facility to correctly process agruments +# with "logging argument index" (like "%1%") in them. This has +# nothing to do with regexps. This query just have to finish. +SELECT * FROM t WHERE t LIKE '%1%'; +DROP DATABASE MCOL5599; diff --git a/utils/loggingcpp/format.h b/utils/loggingcpp/format.h index f12d019ce..93fdf2585 100644 --- a/utils/loggingcpp/format.h +++ b/utils/loggingcpp/format.h @@ -40,16 +40,27 @@ void formatOne(std::string& errMsg, Iter iter, uint32_t position) if (index == std::string::npos) break; + size_t advance_length; + + // below we can replace token with longer or shorter string. + // we should compute exact replacement length to prevent + // 1) recognizing token inside a replacement + // 2) not skipping token recognition if replacement is shorter.i + // regarding 1: the string is "%1%" and replacement is "aaaaa %1%". + // regarding 2: the string is "%1% %1%" and replacement is empty string. + if constexpr (std::is_same_v) { + advance_length = arg.length(); errMsg.replace(index, token.length(), arg); } else { + advance_length = std::to_string(arg).length(); errMsg.replace(index, token.length(), std::to_string(arg)); } - index += token.length(); + index += advance_length; } } @@ -89,4 +100,4 @@ void formatMany(std::string& errMsg, const T& args) errMsg = std::regex_replace(errMsg, restToken, ""); } -} // namespace logging \ No newline at end of file +} // namespace logging