Skip to content

Commit 99d9a9b

Browse files
rennoxdahlerlend
authored andcommitted
BUG#37694461 Commands out of sync after executing JavaScript using getSession
The problem was caused because the result was not properly cleaned up when the execution of the script terminated. Change-Id: Ica6afb418d32ec41bc02221d2115168109ef47a2
1 parent 9d8a6c9 commit 99d9a9b

File tree

12 files changed

+64
-66
lines changed

12 files changed

+64
-66
lines changed

router/src/jit_executor/src/utils/utils_general.h renamed to router/src/harness/include/mysql/harness/scoped_callback.h

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,46 +23,42 @@
2323
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2424
*/
2525

26-
#ifndef MYSQLSHDK_LIBS_UTILS_UTILS_GENERAL_H_
27-
#define MYSQLSHDK_LIBS_UTILS_UTILS_GENERAL_H_
26+
#ifndef ROUTER_SRC_HARNESS_INCLUDE_MYSQL_HARNESS_SCOPED_CALLBACK_H_
27+
#define ROUTER_SRC_HARNESS_INCLUDE_MYSQL_HARNESS_SCOPED_CALLBACK_H_
2828

2929
#include <functional>
30-
#include <stdexcept>
31-
#include <string_view>
3230
#include <utility>
3331

34-
namespace shcore {
32+
namespace mysql_harness {
3533

36-
class Scoped_callback {
34+
class ScopedCallback {
3735
public:
38-
explicit Scoped_callback(std::function<void()> c) noexcept
39-
: m_callback{std::move(c)} {}
36+
explicit ScopedCallback(std::function<void()> c) noexcept
37+
: callback_{std::move(c)} {}
4038

41-
Scoped_callback() = default;
42-
Scoped_callback(const Scoped_callback &) = delete;
43-
Scoped_callback &operator=(const Scoped_callback &) = delete;
39+
ScopedCallback() = default;
40+
ScopedCallback(const ScopedCallback &) = delete;
41+
ScopedCallback &operator=(const ScopedCallback &) = delete;
4442

45-
Scoped_callback(Scoped_callback &&o) noexcept { *this = std::move(o); }
46-
Scoped_callback &operator=(Scoped_callback &&o) noexcept {
47-
if (this != &o) std::swap(m_callback, o.m_callback);
43+
ScopedCallback(ScopedCallback &&o) noexcept { *this = std::move(o); }
44+
ScopedCallback &operator=(ScopedCallback &&o) noexcept {
45+
if (this != &o) std::swap(callback_, o.callback_);
4846
return *this;
4947
}
5048

51-
~Scoped_callback() noexcept;
49+
~ScopedCallback() noexcept;
5250

5351
void call() {
54-
if (!m_callback) return;
55-
std::exchange(m_callback, nullptr)();
52+
if (!callback_) return;
53+
std::exchange(callback_, nullptr)();
5654
}
5755

58-
void cancel() { m_callback = nullptr; }
56+
void cancel() { callback_ = nullptr; }
5957

6058
private:
61-
std::function<void()> m_callback;
59+
std::function<void()> callback_;
6260
};
6361

64-
bool is_valid_identifier(std::string_view name);
62+
} // namespace mysql_harness
6563

66-
} // namespace shcore
67-
68-
#endif // MYSQLSHDK_LIBS_UTILS_UTILS_GENERAL_H_
64+
#endif // ROUTER_SRC_HARNESS_INCLUDE_MYSQL_HARNESS_SCOPED_CALLBACK_H_

router/src/harness/src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,7 @@ SET(harness_source
262262
log_reopen.cc
263263
random_generator.cc
264264
signal_handler.cc
265+
scoped_callback.cc
265266
sd_notify.cc
266267
socket_operations.cc
267268
tls_cipher.cc

router/src/jit_executor/src/utils/utils_general.cc renamed to router/src/harness/src/scoped_callback.cc

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,36 +23,22 @@
2323
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
2424
*/
2525

26-
#include "utils/utils_general.h"
26+
#include "mysql/harness/scoped_callback.h"
2727

28-
#include <regex>
29-
#include <string_view>
30-
#include <utility>
28+
#include <exception>
3129

3230
#include "mysql/harness/logging/logging.h"
3331

34-
namespace shcore {
32+
namespace mysql_harness {
3533

36-
Scoped_callback::~Scoped_callback() noexcept {
34+
IMPORT_LOG_FUNCTIONS()
35+
36+
ScopedCallback::~ScopedCallback() noexcept {
3737
try {
3838
call();
3939
} catch (const std::exception &e) {
40-
mysql_harness::logging::log_error("Unexpected exception: %s", e.what());
40+
log_error("Unexpected exception: %s", e.what());
4141
}
4242
}
4343

44-
bool is_valid_identifier(std::string_view name) {
45-
if (name.empty()) return false;
46-
47-
std::locale locale;
48-
49-
if (!std::isalpha(name.front(), locale) && (name.front() != '_'))
50-
return false;
51-
52-
return std::all_of(
53-
std::next(name.begin()), name.end(), [&locale](auto cur_char) {
54-
return std::isalnum(cur_char, locale) || (cur_char == '_');
55-
});
56-
}
57-
58-
} // namespace shcore
44+
} // namespace mysql_harness

router/src/jit_executor/src/CMakeLists.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ SET(jit_executor_plugin_SOURCE
5959
utils/polyglot_utils.cc
6060
utils/profiling.cc
6161
utils/utils_encoding.cc
62-
utils/utils_general.cc
6362
utils/utils_json.cc
6463
utils/utils_path.cc
6564
utils/utils_string.cc

router/src/jit_executor/src/database/session.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@
3535
// #include "mysqlshdk/libs/utils/debug.h"
3636
// #include "mysqlshdk/libs/utils/fault_injection.h"
3737
// #include "mysqlshdk/libs/utils/log_sql.h"
38+
#include "mysql/harness/scoped_callback.h"
3839
#include "objects/polyglot_date.h"
3940
#include "router/src/router/include/mysqlrouter/mysql_session.h"
4041
#include "utils/profiling.h"
41-
#include "utils/utils_general.h"
4242

4343
namespace shcore {
4444
namespace polyglot {
@@ -150,7 +150,7 @@ void Session::reset() {
150150
std::shared_ptr<IResult> Session::run_sql(const std::string &sql) {
151151
auto attributes = query_attributes();
152152

153-
shcore::Scoped_callback clean_query_attributes(
153+
mysql_harness::ScopedCallback clean_query_attributes(
154154
[this]() { m_query_attributes.clear(); });
155155

156156
return run_sql(sql.c_str(), sql.size(), false, false, attributes);

router/src/jit_executor/src/database/session.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class JIT_EXECUTOR_PLUGIN_EXPORT Session
6262
Session(MYSQL *mysql);
6363
~Session() override;
6464

65+
// Ensures the connection is ready for the next query execution
66+
void reset() override;
67+
6568
private:
6669
std::shared_ptr<IResult> query(
6770
const char *sql, size_t len, bool buffered,
@@ -134,9 +137,6 @@ class JIT_EXECUTOR_PLUGIN_EXPORT Session
134137
void set_query_attributes(const shcore::Dictionary_t &args);
135138
std::vector<Query_attribute> query_attributes() const;
136139

137-
// Ensures the connection is ready for the next query execution
138-
void reset() override;
139-
140140
std::shared_ptr<IResult> run_sql(const std::string &sql) override;
141141

142142
std::shared_ptr<IResult> run_sql(

router/src/jit_executor/src/jit_executor_javascript.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,14 @@
3838
#include "include/my_thread.h"
3939
#include "languages/polyglot_javascript.h"
4040
#include "mysql/harness/logging/logging.h"
41+
#include "mysql/harness/scoped_callback.h"
4142
#include "mysqlrouter/jit_executor_common.h"
4243
#include "mysqlrouter/jit_executor_db_interface.h"
4344
#include "mysqlrouter/polyglot_file_system.h"
4445
#include "objects/polyglot_date.h"
4546
#include "objects/polyglot_session.h"
4647
#include "utils/polyglot_error.h"
4748
#include "utils/polyglot_utils.h"
48-
#include "utils/utils_general.h"
4949
#include "utils/utils_string.h"
5050

5151
namespace jit_executor {
@@ -257,7 +257,7 @@ void JavaScript::run() {
257257
set_processing_state(ProcessingState::Finished);
258258
}
259259

260-
shcore::Scoped_callback terminate([this, &initialized]() {
260+
mysql_harness::ScopedCallback terminate([this, &initialized]() {
261261
if (initialized) {
262262
try {
263263
finalize();
@@ -516,7 +516,7 @@ std::string JavaScript::execute(const std::string &code, int timeout,
516516
m_global_callbacks = &global_callbacks;
517517
m_code.push(Code{code, result_type});
518518

519-
shcore::Scoped_callback clean_resources([this]() {
519+
mysql_harness::ScopedCallback clean_resources([this]() {
520520
if (m_session) {
521521
m_session->reset();
522522
}

router/src/jit_executor/src/languages/polyglot_common_context.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,10 @@
2727

2828
#include <cstring>
2929

30+
#include "mysql/harness/scoped_callback.h"
3031
#include "native_wrappers/polyglot_collectable.h"
3132
#include "utils/polyglot_scope.h"
3233
#include "utils/polyglot_utils.h"
33-
#include "utils/utils_general.h"
3434

3535
namespace shcore {
3636
namespace polyglot {
@@ -60,7 +60,7 @@ void Polyglot_common_context::initialize(
6060
const std::vector<std::string> &isolate_args) {
6161
if (!isolate_args.empty()) {
6262
char **params = get_char_ptr(isolate_args);
63-
shcore::Scoped_callback release([&]() { delete[] params; });
63+
mysql_harness::ScopedCallback release([&]() { delete[] params; });
6464

6565
poly_isolate_params isolate_params;
6666
if (poly_ok != poly_set_isolate_params(&isolate_params,

router/src/jit_executor/src/languages/polyglot_language.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@
3737

3838
#include "languages/polyglot_common_context.h"
3939
#include "mysql/harness/logging/logging.h"
40+
#include "mysql/harness/scoped_callback.h"
4041
#include "native_wrappers/polyglot_file_system_wrapper.h"
4142
#include "utils/polyglot_error.h"
4243
#include "utils/polyglot_scope.h"
43-
#include "utils/utils_general.h"
4444
#include "utils/utils_path.h"
4545
#include "utils/utils_string.h"
4646

@@ -204,7 +204,7 @@ void Polyglot_language::finalize() {
204204
m_globals.reset();
205205
m_types->dispose();
206206

207-
shcore::Scoped_callback cleanup{[this]() {
207+
mysql_harness::ScopedCallback cleanup{[this]() {
208208
m_context.reset();
209209
m_storage->clear();
210210
m_scope->close();

router/src/jit_executor/src/objects/polyglot_row.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
#include "mysqlrouter/jit_executor_db_interface.h"
3434
#include "mysqlrouter/jit_executor_exceptions.h"
3535
#include "objects/polyglot_date.h"
36-
#include "utils/utils_general.h"
3736

3837
namespace shcore {
3938
namespace polyglot {

router/src/mysql_rest_service/src/mrs/endpoint/handler/handler_db_object_script.cc

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "mrs/rest/request_context.h"
5151
#include "mrs/rest/response_cache.h"
5252
#include "mrs/router_observation_entities.h"
53+
#include "mysql/harness/scoped_callback.h"
5354
#include "router/src/mysql_rest_service/include/collector/mysql_cache_manager.h"
5455

5556
#ifdef HAVE_JIT_EXECUTOR_PLUGIN
@@ -144,7 +145,7 @@ class HandlerDbObjectScript::Impl {
144145

145146
if (params.get_type() != shcore::Map) {
146147
throw http::Error(HttpStatusCode::BadRequest,
147-
"Invalid parameters format");
148+
"Invalid parameters format.");
148149
}
149150

150151
auto params_map = params.as_map();
@@ -166,12 +167,16 @@ class HandlerDbObjectScript::Impl {
166167
allowed_params.push_back(it.name);
167168
}
168169

169-
auto allowed_str = shcore::str_join(allowed_params, ", ");
170+
std::string allowed_str{"The function accepts no parameters."};
171+
if (!allowed_params.empty()) {
172+
allowed_str =
173+
"Allowed: " + shcore::str_join(allowed_params, ", ") + ".";
174+
}
170175
auto invalid_str = shcore::str_join(invalid_params, ", ");
171176

172-
throw http::Error(HttpStatusCode::BadRequest,
173-
"Not allowed parameter:"s + invalid_str +
174-
". Allowed: " + allowed_str);
177+
throw http::Error(
178+
HttpStatusCode::BadRequest,
179+
"Not allowed parameter:"s + invalid_str + ". " + allowed_str);
175180
}
176181

177182
for (auto &el : fields) {
@@ -285,6 +290,15 @@ HttpResult HandlerDbObjectScript::handle_script(
285290
}
286291

287292
HandlerDbObjectTable::CachedSession session;
293+
std::shared_ptr<shcore::polyglot::database::Session> be_session;
294+
295+
mysql_harness::ScopedCallback reset_session([&be_session]() {
296+
// This reset ensures the session is left in a usable state
297+
if (be_session) {
298+
be_session->reset();
299+
}
300+
});
301+
288302
auto result = context->get()->execute(
289303
m_impl->entry_script(), entry_->content_set_def->class_name,
290304
entry_->content_set_def->name, parameters, timeout, result_type,
@@ -301,8 +315,10 @@ HttpResult HandlerDbObjectScript::handle_script(
301315
session = get_session(ctxt, session_type);
302316
session->connection_id();
303317

304-
return std::make_shared<shcore::polyglot::database::Session>(
318+
be_session = std::make_shared<shcore::polyglot::database::Session>(
305319
session.get()->get_handle());
320+
321+
return be_session;
306322
},
307323
// Get current MRS User ID Callback
308324
[&, ctxt]() -> std::optional<std::string> {

router/tests/mrs_client/main.cc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
Copyright (c) 2023, 2024, Oracle and/or its affiliates.
2+
Copyright (c) 2023, 2025, Oracle and/or its affiliates.
33
44
This program is free software; you can redistribute it and/or modify
55
it under the terms of the GNU General Public License, version 2.0,
@@ -229,6 +229,7 @@ static const std::map<std::string, HttpStatusCode::key_type>
229229
HTTP_STATUS_ENTRY(BadRequest),
230230
HTTP_STATUS_ENTRY(Unauthorized),
231231
HTTP_STATUS_ENTRY(Forbidden),
232+
HTTP_STATUS_ENTRY(RequestTimeout),
232233
HTTP_STATUS_ENTRY(NotFound),
233234
HTTP_STATUS_ENTRY(MethodNotAllowed),
234235
HTTP_STATUS_ENTRY(InternalError),

0 commit comments

Comments
 (0)