From c0547d0cec2ec7a7f5f5884b8e14da3abc0848ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 1 Mar 2021 17:11:43 +0000 Subject: [PATCH 1/2] Closes #3327: Moved call to 'ProcessQueryAndSetStatusFlags' to 'MySQL_Session::RequestEnd' --- lib/MySQL_Session.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index ffe65f51d2..3abe7598cd 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -4345,11 +4345,6 @@ int MySQL_Session::handler() { handler_rc0_Process_GTID(myconn); - // check if multiplexing needs to be disabled - char *qdt=CurrentQuery.get_digest_text(); - if (qdt) - myconn->ProcessQueryAndSetStatusFlags(qdt); - if (mirror == false) { // Support for LAST_INSERT_ID() if (myconn->mysql->insert_id) { @@ -6557,6 +6552,11 @@ void MySQL_Session::LogQuery(MySQL_Data_Stream *myds) { // this should execute most of the commands executed when a request is finalized // this should become the place to hook other functions void MySQL_Session::RequestEnd(MySQL_Data_Stream *myds) { + // check if multiplexing needs to be disabled + char *qdt=CurrentQuery.get_digest_text(); + if (qdt && myds && myds->myconn) { + myds->myconn->ProcessQueryAndSetStatusFlags(qdt); + } switch (status) { case PROCESSING_STMT_EXECUTE: From ee7420c87ab04b0f264f9a0d0cdf3e9b8a368441 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 1 Mar 2021 17:12:58 +0000 Subject: [PATCH 2/2] Added regression test for #3327 to check that 'ProcessQueryAndSetStatusFlags' is properly call after a failed query --- ..._3327-process_query_set_status_flags-t.cpp | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 test/tap/tests/reg_test_3327-process_query_set_status_flags-t.cpp diff --git a/test/tap/tests/reg_test_3327-process_query_set_status_flags-t.cpp b/test/tap/tests/reg_test_3327-process_query_set_status_flags-t.cpp new file mode 100644 index 0000000000..8f6c0506ed --- /dev/null +++ b/test/tap/tests/reg_test_3327-process_query_set_status_flags-t.cpp @@ -0,0 +1,77 @@ +/** + * @file reg_test_3327-process_query_set_status_flags-t.cpp + * @brief This test is a regression test for issue #3327. + * @details The test performs a invalid query that according to the new introduced behavior in + * ProxySQL #3327 should be processed by 'ProcessQueryAndSetStatusFlags' and disable multiplexing. + * @date 2021-03-01 + */ + +#include +#include +#include +#include + +#include "tap.h" +#include "command_line.h" +#include "utils.h" +#include "json.hpp" + +using std::string; +using namespace nlohmann; + +void parse_result_json_column(MYSQL_RES *result, json& j) { + if(!result) return; + MYSQL_ROW row; + + while ((row = mysql_fetch_row(result))) { + j = json::parse(row[0]); + } +} + +int main(int argc, char** argv) { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + MYSQL* proxysql_mysql = mysql_init(NULL); + + if (!mysql_real_connect(proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_mysql)); + return -1; + } + + int query_err = mysql_query(proxysql_mysql, "SELECT SQL_CALC_FOUND_ROWS * FROM reg_test_3327_non_exist_table"); + ok (query_err != 0, "Initial query failed as intended."); + + MYSQL_QUERY(proxysql_mysql, "PROXYSQL INTERNAL SESSION"); + json j_status {}; + MYSQL_RES* int_session_res = mysql_store_result(proxysql_mysql); + parse_result_json_column(int_session_res, j_status); + mysql_free_result(int_session_res); + + if (j_status.contains("backends")) { + bool found_backend = false; + for (auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok( + multiplex_disabled == true, + "Connection status should reflect that 'MultiplexDisabled' is enabled due to the invalid 'SELECT SQL_CALC_FOUND_ROWS'." + ); + } + } + if (found_backend == false) { + ok(false, "'backends' doens't contains 'conn' objects with the relevant session information"); + } + } else { + ok(false, "No backends detected for the current connection."); + } + + mysql_close(proxysql_mysql); + + return exit_status(); +}