From db632cd7f5a41b9d6ab5e5eca152ceccbae98825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Thu, 13 Jul 2023 03:59:04 +0000 Subject: [PATCH] Preserve STATUS_MYSQL_CONNECTION_COMPRESSION after connection reset In MySQL_Connection::reset() we were forgetting the value of STATUS_MYSQL_CONNECTION_COMPRESSION. De-facto disabling compression if it was enabled. --- lib/mysql_connection.cpp | 3 + .../tap/tests/reg_test_4158_change_user-t.cpp | 115 ++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 test/tap/tests/reg_test_4158_change_user-t.cpp diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 9e2bfe5bf..d3300bb2e 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -2779,9 +2779,12 @@ int MySQL_Connection::async_send_simple_command(short event, char *stmt, unsigne void MySQL_Connection::reset() { bool old_no_multiplex_hg = get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG); + bool old_compress = get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); status_flags=0; // reconfigure STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG set_status(old_no_multiplex_hg,STATUS_MYSQL_CONNECTION_NO_MULTIPLEX_HG); + // reconfigure STATUS_MYSQL_CONNECTION_COMPRESSION + set_status(old_compress,STATUS_MYSQL_CONNECTION_COMPRESSION); reusable=true; options.last_set_autocommit=-1; // never sent diff --git a/test/tap/tests/reg_test_4158_change_user-t.cpp b/test/tap/tests/reg_test_4158_change_user-t.cpp new file mode 100644 index 000000000..cb4fab278 --- /dev/null +++ b/test/tap/tests/reg_test_4158_change_user-t.cpp @@ -0,0 +1,115 @@ +/** + * @file reg_test_4158_change_user-t.cpp + * @brief This test verifies COM_CHANGE_USER and COM_RESET_CONNECTION with compression + * + * @details It run COM_CHANGE_USER and COM_RESET_CONNECTION with compression. + * This seems broken in 2.x (not sure yet in which version the regression was + * first introduced), while working fine in 1.4 + */ + +#include "mysql.h" + +#include "proxysql_utils.h" +#include "tap.h" +#include "utils.h" + +#include +#include + +using std::string; + +//#include "json.hpp" +//using nlohmann::json; + + +using namespace std; + +int loop1 = 3; +int loop2 = 3; + +CommandLine cl; + +int work_mysql() { + MYSQL* proxy = mysql_init(NULL); + if (!mysql_real_connect(proxy, cl.host, cl.username, cl.password, NULL, cl.port, NULL, CLIENT_COMPRESS)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxy)); + return EXIT_FAILURE; + } + + for (int j=0; j < loop1 ; j++) { + diag("We run multiple queries just to verify that the connection is still healthy after the firstone"); + for (int i=0; i < loop2 ; i++) { + MYSQL_QUERY_T(proxy, "SELECT CONNECTION_ID()"); + MYSQL_RES* myres; + myres = mysql_store_result(proxy); + int nr = mysql_num_rows(myres); + ok(nr == 1, "Rows returned: %d" , nr); + mysql_free_result(myres); + } + int rb; + diag("Running mysql_reset_connection()"); + rb = mysql_reset_connection(proxy); + ok(rb == 0 , "mysql_reset_connection(): %s", (rb == 0 ? "OK" : mysql_error(proxy))); + diag("Running mysql_change_user()"); + rb = mysql_change_user(proxy, cl.username, cl.password, NULL); + ok(rb == 0 , "mysql_change_user(): %s", (rb == 0 ? "OK" : mysql_error(proxy))); + } + mysql_close(proxy); + return 0; +} + +void * work(void *arg) { + work_mysql(); // this return an int + return NULL; +} + +int main(int, char**) { + + plan(loop1 * (loop2 + 2)); + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return EXIT_FAILURE; + } + +/* + // PLACEHOLDER + MYSQL* admin = mysql_init(NULL); + if (!mysql_real_connect(admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(admin)); + return EXIT_FAILURE; + } + + MYSQL_QUERY_T(admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + + mysql_close(admin); +*/ + + // we run the test on a separate thread because we have a built-in timeout + pthread_t thread_id; + if (pthread_create(&thread_id, NULL, work, NULL)) { + fprintf(stderr, "Error calling pthread_create()"); + return EXIT_FAILURE; + } + + int timeout = 10; // this is the timeout for the whole TAP test + if (timeout != 0) { + int tr = 0; + while (timeout != 0) { + sleep(1); + tr = pthread_tryjoin_np(thread_id, NULL); + if (tr == 0) { + timeout = 0; + } else { + timeout--; + diag("Waiting up to %d seconds", timeout); + } + } + } else { + // if timeout == 0 , the timeout is disabled + // This is useful during debugging, while running the TAP test in gdb + diag("Built-in timeout DISABLED"); + pthread_join(thread_id, NULL); + } + return exit_status(); +}