From 792aea2a7ce675077ef745a05bf59f06c8942154 Mon Sep 17 00:00:00 2001 From: Serguey Zefirov Date: Wed, 29 Nov 2023 13:10:33 +0300 Subject: [PATCH] Fixes MCOL-5599 where LIKE operator never finishes 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. --- .../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