Skip to content

Commit 41532f5

Browse files
Backport #82233 to 25.6: Fix possible data-race between suggestion thread and main client thread
1 parent 2d0bf03 commit 41532f5

File tree

4 files changed

+27
-12
lines changed

4 files changed

+27
-12
lines changed

src/Client/LineReader.cpp

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -79,18 +79,20 @@ replxx::Replxx::completions_t LineReader::Suggest::getCompletions(const String &
7979

8080
std::pair<Words::const_iterator, Words::const_iterator> range;
8181

82-
std::lock_guard lock(mutex);
83-
8482
Words to_search;
8583
bool no_case = false;
86-
/// Only perform case sensitive completion when the prefix string contains any uppercase characters
87-
if (std::none_of(prefix.begin(), prefix.end(), [](char32_t x) { return iswupper(static_cast<wint_t>(x)); }))
84+
8885
{
89-
to_search = words_no_case;
90-
no_case = true;
86+
std::lock_guard lock(mutex);
87+
/// Only perform case sensitive completion when the prefix string contains any uppercase characters
88+
if (std::none_of(prefix.begin(), prefix.end(), [](char32_t x) { return iswupper(static_cast<wint_t>(x)); }))
89+
{
90+
to_search = words_no_case;
91+
no_case = true;
92+
}
93+
else
94+
to_search = words;
9195
}
92-
else
93-
to_search = words;
9496

9597
if (custom_completions_callback)
9698
{

src/Client/Suggest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <AggregateFunctions/Combinators/AggregateFunctionCombinatorFactory.h>
55
#include <Columns/ColumnString.h>
66
#include <Common/Exception.h>
7+
#include <Common/setThreadName.h>
78
#include <Common/typeid_cast.h>
89
#include <Common/Macros.h>
910
#include "Core/Protocol.h"
@@ -94,7 +95,15 @@ void Suggest::load(ContextPtr context, const ConnectionParameters & connection_p
9495
{
9596
loading_thread = std::thread([my_context=Context::createCopy(context), connection_parameters, suggestion_limit, this]
9697
{
98+
/// Creates new QueryScope/ThreadStatus to avoid sharing global context, which settings can be modified by the client in another thread.
9799
ThreadStatus thread_status;
100+
std::optional<CurrentThread::QueryScope> query_scope;
101+
/// LocalConnection creates QueryScope for each query
102+
if constexpr (!std::is_same_v<ConnectionType, LocalConnection>)
103+
query_scope.emplace(my_context);
104+
105+
setThreadName("Suggest");
106+
98107
for (size_t retry = 0; retry < 10; ++retry)
99108
{
100109
try

tests/queries/0_stateless/02160_client_autocomplete_parse_query.expect

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@ exp_internal -f $CLICKHOUSE_TMP/$basename.debuglog 0
1111
set history_file $CLICKHOUSE_TMP/$basename.history
1212

1313
log_user 0
14-
# FIXME: workaround to obtain the stacktrace of the client in case of timeout
15-
# (clickhouse-test wrapper does this on timeout)
16-
set timeout 3600
14+
set timeout 60
1715
set uuid ""
1816
match_max 100000
1917
expect_after {

tests/queries/0_stateless/02815_no_throw_in_simple_queries.sh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,13 @@ log_user 0
3131
set timeout 60
3232
match_max 100000
3333
34-
spawn bash -c "$command"
34+
exp_internal -f $CLICKHOUSE_TMP/$(basename "${BASH_SOURCE[0]}").debuglog 0
35+
expect_after {
36+
-i \$any_spawn_id eof { exp_continue }
37+
-i \$any_spawn_id timeout { exit 1 }
38+
}
39+
40+
spawn $command
3541
3642
expect ":) "
3743

0 commit comments

Comments
 (0)