From d10f519e4a62c3362753e8ac389f8536d5df7be6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 12 Jun 2020 10:14:43 +0200 Subject: [PATCH 1/6] Refactored 'MySQL_Session' set/get status functions - Added extra doc about the 'status_flags' and 'server_status'. - Added 'sql_log_bin0' and 'prepared_statement' to the 'conn.status' from PROXYSQL SESSION INFO. --- include/mysql_connection.h | 33 +++---- lib/MySQL_Session.cpp | 34 +++---- lib/mysql_connection.cpp | 185 +++++++------------------------------ lib/mysql_data_stream.cpp | 10 +- 4 files changed, 65 insertions(+), 197 deletions(-) diff --git a/include/mysql_connection.h b/include/mysql_connection.h index f946dbb1e..f9e21795e 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -105,6 +105,11 @@ class MySQL_Connection { MySrvC *parent; MySQL_Connection_userinfo *userinfo; MySQL_Data_Stream *myds; + /** + * @brief Keeps tracks of the 'server_status'. Do not confuse with the 'server_status' from the + * 'MYSQL' connection itself. This flag keeps track of the configured server status from the + * parent 'MySrvC'. + */ enum MySerStatus server_status; // this to solve a side effect of #774 bytes_stats_t bytes_info; // bytes statistics @@ -115,6 +120,10 @@ class MySQL_Connection { } statuses; unsigned long largest_query_length; + /** + * @brief This represents the internal knowledge of ProxySQL about the connection. It keeps track of those + * states which *are not reflected* into 'server_status', but are relevant for connection handling. + */ uint32_t status_flags; int async_exit_status; // exit status of MariaDB Client Library Non blocking API int interr; // integer return @@ -139,30 +148,10 @@ class MySQL_Connection { bool set_no_backslash_escapes(bool); unsigned int set_charset(unsigned int, enum charset_action); - void set_status_transaction(bool); - void set_status_compression(bool); - void set_status_get_lock(bool); - void set_status_lock_tables(bool); - void set_status_temporary_table(bool); - void set_status_no_backslash_escapes(bool); - void set_status_prepared_statement(bool); - void set_status_user_variable(bool); - void set_status_has_savepoint(bool); - void set_status_no_multiplex(bool); + void set_status(bool set, uint32_t status_flag); void set_status_sql_log_bin0(bool); - void set_status_found_rows(bool); - bool get_status_transaction(); - bool get_status_compression(); - bool get_status_get_lock(); - bool get_status_lock_tables(); - bool get_status_temporary_table(); - bool get_status_no_backslash_escapes(); - bool get_status_prepared_statement(); - bool get_status_user_variable(); - bool get_status_has_savepoint(); - bool get_status_no_multiplex(); + bool get_status(uint32_t status_flag); bool get_status_sql_log_bin0(); - bool get_status_found_rows(); void connect_start(); void connect_cont(short event); void change_user_start(); diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index a812a9a7d..6bb623244 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -974,8 +974,8 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["conn"]["client_flag"]["client_multi_statements"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_STATEMENTS ? 1 : 0); j["conn"]["client_flag"]["client_multi_results"] = (client_myds->myconn->options.client_flag & CLIENT_MULTI_RESULTS ? 1 : 0); j["conn"]["no_backslash_escapes"] = client_myds->myconn->options.no_backslash_escapes; - j["conn"]["status"]["compression"] = client_myds->myconn->get_status_compression(); - j["conn"]["status"]["transaction"] = client_myds->myconn->get_status_transaction(); + j["conn"]["status"]["compression"] = client_myds->myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); + j["conn"]["status"]["transaction"] = client_myds->myconn->get_status(STATUS_MYSQL_CONNECTION_TRANSACTION); j["conn"]["ps"]["client_stmt_to_global_ids"] = client_myds->myconn->local_stmts->client_stmt_to_global_ids; for (unsigned int k=0; klen; k++) { MySQL_Backend *_mybe = NULL; @@ -1017,13 +1017,15 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["backends"][i]["conn"]["autocommit"] = ( _myds->myconn->options.autocommit ? "ON" : "OFF" ); j["backends"][i]["conn"]["last_set_autocommit"] = _myds->myconn->options.last_set_autocommit; j["backends"][i]["conn"]["no_backslash_escapes"] = _myconn->options.no_backslash_escapes; - j["backends"][i]["conn"]["status"]["get_lock"] = _myconn->get_status_get_lock(); - j["backends"][i]["conn"]["status"]["lock_tables"] = _myconn->get_status_lock_tables(); - j["backends"][i]["conn"]["status"]["has_savepoint"] = _myconn->get_status_has_savepoint(); - j["backends"][i]["conn"]["status"]["temporary_table"] = _myconn->get_status_temporary_table(); - j["backends"][i]["conn"]["status"]["user_variable"] = _myconn->get_status_user_variable(); - j["backends"][i]["conn"]["status"]["found_rows"] = _myconn->get_status_found_rows(); - j["backends"][i]["conn"]["status"]["no_multiplex"] = _myconn->get_status_no_multiplex(); + j["backends"][i]["conn"]["status"]["get_lock"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_GET_LOCK); + j["backends"][i]["conn"]["status"]["lock_tables"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES); + j["backends"][i]["conn"]["status"]["has_savepoint"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT); + j["backends"][i]["conn"]["status"]["temporary_table"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE); + j["backends"][i]["conn"]["status"]["user_variable"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_USER_VARIABLE); + j["backends"][i]["conn"]["status"]["found_rows"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_FOUND_ROWS); + j["backends"][i]["conn"]["status"]["no_multiplex"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); + j["backends"][i]["conn"]["status"]["sql_log_bin0"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0); + j["backends"][i]["conn"]["status"]["prepared_statement"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); j["backends"][i]["conn"]["MultiplexDisabled"] = _myconn->MultiplexDisabled(); j["backends"][i]["conn"]["ps"]["backend_stmt_to_global_ids"] = _myconn->local_stmts->backend_stmt_to_global_ids; j["backends"][i]["conn"]["ps"]["global_stmt_to_backend_ids"] = _myconn->local_stmts->global_stmt_to_backend_ids; @@ -2054,12 +2056,12 @@ bool MySQL_Session::handler_again___status_SETTING_SQL_LOG_BIN(int *_rc) { } if (rc==0) { if (!strcmp("0", mysql_variables.client_get_value(this, SQL_LOG_BIN)) || !strcasecmp("OFF", mysql_variables.client_get_value(this, SQL_LOG_BIN))) { - // pay attention here. set_status_sql_log_bin0 sets it sql_log_bin is ZERO - // sql_log_bin=0 => true - // sql_log_bin=1 => false - myconn->set_status_sql_log_bin0(true); + // Pay attention here. STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0 sets sql_log_bin to ZERO: + // - sql_log_bin=0 => true + // - sql_log_bin=1 => false + myconn->set_status(true, STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0); } else if (!strcmp("1", mysql_variables.client_get_value(this, SQL_LOG_BIN)) || !strcasecmp("ON", mysql_variables.client_get_value(this, SQL_LOG_BIN))) { - myconn->set_status_sql_log_bin0(false); + myconn->set_status(false, STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0); } myds->revents|=POLLOUT; // we also set again POLLOUT to send a query immediately! myds->DSS = STATE_MARIADB_GENERIC; @@ -2503,7 +2505,7 @@ bool MySQL_Session::handler_again___status_CONNECTING_SERVER(int *_rc) { if (default_hostgroup<0) { // we are connected to a Admin module backend // we pretend to set a user variable to disable multiplexing - myconn->set_status_user_variable(true); + myconn->set_status(true, STATUS_MYSQL_CONNECTION_USER_VARIABLE); } enum session_status st=status; if (mybe->server_myds->myconn->async_state_machine==ASYNC_IDLE) { @@ -6394,7 +6396,7 @@ void MySQL_Session::finishQuery(MySQL_Data_Stream *myds, MySQL_Connection *mycon myds->myconn->reduce_auto_increment_delay_token(); if (locked_on_hostgroup >= 0) { if (qpo->multiplex == -1) { - myds->myconn->set_status_no_multiplex(true); + myds->myconn->set_status(true, STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); } } if (mysql_thread___multiplexing && (myds->myconn->reusable==true) && myds->myconn->IsActiveTransaction()==false && myds->myconn->MultiplexDisabled()==false) { diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 8e6fa83c2..7e59da0fb 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -449,97 +449,18 @@ bool MySQL_Connection::is_expired(unsigned long long timeout) { return false; } -void MySQL_Connection::set_status_transaction(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_TRANSACTION; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_TRANSACTION; - } -} - -void MySQL_Connection::set_status_compression(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_COMPRESSION; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_COMPRESSION; - } -} - -void MySQL_Connection::set_status_get_lock(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_GET_LOCK; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_GET_LOCK; - } -} - -void MySQL_Connection::set_status_found_rows(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_FOUND_ROWS; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_FOUND_ROWS; - } -} - -void MySQL_Connection::set_status_lock_tables(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_LOCK_TABLES; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_LOCK_TABLES; - } -} - -void MySQL_Connection::set_status_temporary_table(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE; - } -} - -void MySQL_Connection::set_status_no_backslash_escapes(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_NO_BACKSLASH_ESCAPES; +void MySQL_Connection::set_status(bool set, uint32_t status_flag) { + if (set) { + this->status_flags |= status_flag; } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_NO_BACKSLASH_ESCAPES; + this->status_flags &= ~status_flag; } } -void MySQL_Connection::set_status_user_variable(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_USER_VARIABLE; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_USER_VARIABLE; - } +bool MySQL_Connection::get_status(uint32_t status_flag) { + return this->status_flags & status_flag; } -void MySQL_Connection::set_status_has_savepoint(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT; - } -} - -void MySQL_Connection::set_status_prepared_statement(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT; - } -} - -void MySQL_Connection::set_status_no_multiplex(bool v) { - if (v) { - status_flags |= STATUS_MYSQL_CONNECTION_NO_MULTIPLEX; - } else { - status_flags &= ~STATUS_MYSQL_CONNECTION_NO_MULTIPLEX; - } -} - -// pay attention here. set_status_sql_log_bin0 sets it sql_log_bin is ZERO -// sql_log_bin=0 => true -// sql_log_bin=1 => false void MySQL_Connection::set_status_sql_log_bin0(bool v) { if (v) { status_flags |= STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0; @@ -548,50 +469,6 @@ void MySQL_Connection::set_status_sql_log_bin0(bool v) { } } -bool MySQL_Connection::get_status_transaction() { - return status_flags & STATUS_MYSQL_CONNECTION_TRANSACTION; -} - -bool MySQL_Connection::get_status_compression() { - return status_flags & STATUS_MYSQL_CONNECTION_COMPRESSION; -} - -bool MySQL_Connection::get_status_user_variable() { - return status_flags & STATUS_MYSQL_CONNECTION_USER_VARIABLE; -} - -bool MySQL_Connection::get_status_has_savepoint() { - return status_flags & STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT; -} - -bool MySQL_Connection::get_status_get_lock() { - return status_flags & STATUS_MYSQL_CONNECTION_GET_LOCK; -} - -bool MySQL_Connection::get_status_found_rows() { - return status_flags & STATUS_MYSQL_CONNECTION_FOUND_ROWS; -} - -bool MySQL_Connection::get_status_lock_tables() { - return status_flags & STATUS_MYSQL_CONNECTION_LOCK_TABLES; -} - -bool MySQL_Connection::get_status_temporary_table() { - return status_flags & STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE; -} - -bool MySQL_Connection::get_status_no_backslash_escapes() { - return status_flags & STATUS_MYSQL_CONNECTION_NO_BACKSLASH_ESCAPES; -} - -bool MySQL_Connection::get_status_prepared_statement() { - return status_flags & STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT; -} - -bool MySQL_Connection::get_status_no_multiplex() { - return status_flags & STATUS_MYSQL_CONNECTION_NO_MULTIPLEX; -} - bool MySQL_Connection::get_status_sql_log_bin0() { return status_flags & STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0; } @@ -1965,7 +1842,7 @@ bool MySQL_Connection::IsActiveTransaction() { } } if (ret == false) { - if (get_status_has_savepoint()) { + if (get_status(STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT)) { // there are savepoints ret = true; } @@ -2101,16 +1978,16 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { if (myds->sess->qpo) { mul=myds->sess->qpo->multiplex; if (mul==0) { - set_status_no_multiplex(true); + set_status(true, STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); } else { if (mul==1) { - set_status_no_multiplex(false); + set_status(false, STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); } } } } } - if (get_status_user_variable()==false) { // we search for variables only if not already set + if (get_status(STATUS_MYSQL_CONNECTION_USER_VARIABLE)==false) { // we search for variables only if not already set // if ( // strncasecmp(query_digest_text,"SELECT @@tx_isolation", strlen("SELECT @@tx_isolation")) // && @@ -2123,12 +2000,12 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { if (mul!=2) { if (index(query_digest_text,'@')) { // mul = 2 has a special meaning : do not disable multiplex for variables in THIS QUERY ONLY if (!IsKeepMultiplexEnabledVariables(query_digest_text)) { - set_status_user_variable(true); + set_status(true, STATUS_MYSQL_CONNECTION_USER_VARIABLE); } } else { for (unsigned int i = 0; i < sizeof(session_vars)/sizeof(char *); i++) { if (strcasestr(query_digest_text,session_vars[i])!=NULL) { - set_status_user_variable(true); + set_status(true, STATUS_MYSQL_CONNECTION_USER_VARIABLE); break; } } @@ -2138,7 +2015,7 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { case 1: // new algorithm if (myds->sess->locked_on_hostgroup > -1) { // locked_on_hostgroup was set, so some variable wasn't parsed - set_status_user_variable(true); + set_status(true, STATUS_MYSQL_CONNECTION_USER_VARIABLE); } break; default: @@ -2147,47 +2024,47 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { } else { if (mul!=2 && index(query_digest_text,'@')) { // mul = 2 has a special meaning : do not disable multiplex for variables in THIS QUERY ONLY if (!IsKeepMultiplexEnabledVariables(query_digest_text)) { - set_status_user_variable(true); + set_status(true, STATUS_MYSQL_CONNECTION_USER_VARIABLE); } } } } - if (get_status_prepared_statement()==false) { // we search if prepared was already executed + if (get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT)==false) { // we search if prepared was already executed if (!strncasecmp(query_digest_text,"PREPARE ", strlen("PREPARE "))) { - set_status_prepared_statement(true); + set_status(true, STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); } } - if (get_status_temporary_table()==false) { // we search for temporary if not already set + if (get_status(STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE)==false) { // we search for temporary if not already set if (!strncasecmp(query_digest_text,"CREATE TEMPORARY TABLE ", strlen("CREATE TEMPORARY TABLE "))) { - set_status_temporary_table(true); + set_status(true, STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE); } } - if (get_status_lock_tables()==false) { // we search for lock tables only if not already set + if (get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES)==false) { // we search for lock tables only if not already set if (!strncasecmp(query_digest_text,"LOCK TABLE", strlen("LOCK TABLE"))) { - set_status_lock_tables(true); + set_status(true, STATUS_MYSQL_CONNECTION_LOCK_TABLES); } } - if (get_status_lock_tables()==false) { // we search for lock tables only if not already set + if (get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES)==false) { // we search for lock tables only if not already set if (!strncasecmp(query_digest_text,"FLUSH TABLES WITH READ LOCK", strlen("FLUSH TABLES WITH READ LOCK"))) { // issue 613 - set_status_lock_tables(true); + set_status(true, STATUS_MYSQL_CONNECTION_LOCK_TABLES); } } - if (get_status_lock_tables()==true) { + if (get_status(STATUS_MYSQL_CONNECTION_LOCK_TABLES)==true) { if (!strncasecmp(query_digest_text,"UNLOCK TABLES", strlen("UNLOCK TABLES"))) { - set_status_lock_tables(false); + set_status(false, STATUS_MYSQL_CONNECTION_LOCK_TABLES); } } - if (get_status_get_lock()==false) { // we search for get_lock if not already set + if (get_status(STATUS_MYSQL_CONNECTION_GET_LOCK)==false) { // we search for get_lock if not already set if (strcasestr(query_digest_text,"GET_LOCK(")) { - set_status_get_lock(true); + set_status(true, STATUS_MYSQL_CONNECTION_GET_LOCK); } } - if (get_status_found_rows()==false) { // we search for SQL_CALC_FOUND_ROWS if not already set + if (get_status(STATUS_MYSQL_CONNECTION_FOUND_ROWS)==false) { // we search for SQL_CALC_FOUND_ROWS if not already set if (strcasestr(query_digest_text,"SQL_CALC_FOUND_ROWS")) { - set_status_found_rows(true); + set_status(true, STATUS_MYSQL_CONNECTION_FOUND_ROWS); } } - if (get_status_has_savepoint()==false) { + if (get_status(STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT)==false) { if (mysql) { if ( (mysql->server_status & SERVER_STATUS_IN_TRANS) @@ -2195,7 +2072,7 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { ((mysql->server_status & SERVER_STATUS_AUTOCOMMIT) == 0) ) { if (!strncasecmp(query_digest_text,"SAVEPOINT ", strlen("SAVEPOINT "))) { - set_status_has_savepoint(true); + set_status(true, STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT); } } } @@ -2213,7 +2090,7 @@ void MySQL_Connection::ProcessQueryAndSetStatusFlags(char *query_digest_text) { || !strcasecmp(query_digest_text,"ROLLBACK") ) { - set_status_has_savepoint(false); + set_status(false, STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT); } } } diff --git a/lib/mysql_data_stream.cpp b/lib/mysql_data_stream.cpp index 8f7bfea39..dc2ed54bb 100644 --- a/lib/mysql_data_stream.cpp +++ b/lib/mysql_data_stream.cpp @@ -875,7 +875,7 @@ int MySQL_Data_Stream::buffer2array() { return ret; } - if (myconn->get_status_compression()==true) { + if (myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION)==true) { if ((queueIN.pkt.size==0) && queue_data(queueIN)>=7) { proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Session=%p . Reading the header of a new compressed packet\n", sess); memcpy(&queueIN.hdr,queue_r_ptr(queueIN), sizeof(mysql_hdr)); @@ -918,7 +918,7 @@ int MySQL_Data_Stream::buffer2array() { ret+=b; } if ((queueIN.pkt.size>0) && (queueIN.pkt.size==queueIN.partial) ) { - if (myconn->get_status_compression()==true) { + if (myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION)==true) { Bytef *dest = NULL; uLongf destLen; proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Session=%p . Copied the whole compressed packet\n", sess); @@ -1143,7 +1143,7 @@ int MySQL_Data_Stream::array2buffer() { queueOUT.pkt.ptr=NULL; } //VALGRIND_ENABLE_ERROR_REPORTING; - if (myconn->get_status_compression()==true) { + if (myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION)==true) { proxy_debug(PROXY_DEBUG_PKT_ARRAY, 5, "Session=%p . DataStream: %p -- Compression enabled\n", sess, this); generate_compressed_packet(); // it is copied directly into queueOUT.pkt } else { @@ -1157,12 +1157,12 @@ int MySQL_Data_Stream::array2buffer() { // enable compression if (myconn->options.server_capabilities & CLIENT_COMPRESS) { if (myconn->options.compression_min_length) { - myconn->set_status_compression(true); + myconn->set_status(true, STATUS_MYSQL_CONNECTION_COMPRESSION); } } else { //explicitly disable compression myconn->options.compression_min_length=0; - myconn->set_status_compression(false); + myconn->set_status(false, STATUS_MYSQL_CONNECTION_COMPRESSION); } } } From 996060bc7c342b41b20cffe13f6b314bdab1a2ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 12 Jun 2020 10:24:33 +0200 Subject: [PATCH 2/6] Added test file for testing the behavior of 'MySQL_Session::status_flag' to the different operations should modify it --- test/tap/tests/Makefile | 3 + .../tap/tests/test_session_status_flags-t.cpp | 557 ++++++++++++++++++ 2 files changed, 560 insertions(+) create mode 100644 test/tap/tests/test_session_status_flags-t.cpp diff --git a/test/tap/tests/Makefile b/test/tap/tests/Makefile index 8d8d7f859..9030ef6cb 100644 --- a/test/tap/tests/Makefile +++ b/test/tap/tests/Makefile @@ -109,3 +109,6 @@ test_tokenizer-t: test_tokenizer-t.cpp $(TAP_LIBDIR)/libtap.a 2793_compression: reg_test_2793-compression-t.cpp g++ -DDEBUG reg_test_2793-compression-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(OBJ) $(MYLIBS) -ltap -ldl $(STATIC_LIBS) -o reg_test_2793-compression-t -DGITVERSION=\"$(GIT_VERSION)\" + +test_session_status_flags: test_session_status_flags-t.cpp + g++ -DDEBUG test_session_status_flags-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(OBJ) $(MYLIBS) -ltap -ldl $(STATIC_LIBS) -o test_session_status_flags-t -DGITVERSION=\"$(GIT_VERSION)\" diff --git a/test/tap/tests/test_session_status_flags-t.cpp b/test/tap/tests/test_session_status_flags-t.cpp new file mode 100644 index 000000000..7e2531f51 --- /dev/null +++ b/test/tap/tests/test_session_status_flags-t.cpp @@ -0,0 +1,557 @@ +/** + * @file test_session_status_flags-t.cpp + * @brief Test file for testing the different operations that modify the 'status_flags' in a MySQL_Session. + */ + +#include +#include +#include +#include +#include "json.hpp" + +#include "tap.h" +#include "utils.h" +#include "command_line.h" + +using nlohmann::json; + +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()) { + return exit_status(); + } + + { + MYSQL* proxysql_mysql = mysql_init(NULL); + + // Waiting for proxysql to be ready + uint con_waited = 0; + 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; + } + + // Check that transaction state is reflected when actively in a transaction + const std::vector transaction_queries { "START TRANSACTION", "SELECT 1", "PROXYSQL INTERNAL SESSION", "COMMIT" }; + json j_status; + + for (const auto& query : transaction_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + int32_t server_status = j_status["backends"][0]["conn"]["mysql"]["server_status"]; + ok(server_status & 0x01, "Connection status should reflect being in a transaction"); + + mysql_close(proxysql_mysql); + } + + { + MYSQL* proxysql_mysql = mysql_init(NULL); + + if (!mysql_real_connect(proxysql_mysql, 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(proxysql_mysql)); + return -1; + } + + // Check that state reflects when in a compressed connection + const std::string internal_session_query { "PROXYSQL INTERNAL SESSION" }; + json j_status; + + MYSQL_QUERY(proxysql_mysql, internal_session_query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + parse_result_json_column(tr_res, j_status); + mysql_free_result(tr_res); + + bool compression_enabled = j_status["conn"]["status"]["compression"]; + ok(compression_enabled == true, "Connection status should reflect being in a compressed connection"); + + mysql_close(proxysql_mysql); + } + + // USER VARIABLE + { + 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; + } + + // Check that state reflects when in a compressed connection + const std::vector user_variable_queries { "SET @test_variable = 43", "PROXYSQL INTERNAL SESSION" }; + json j_status; + + for (const auto& query : user_variable_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (auto& backend : j_status["backends"]) { + if (backend != nullptr) { + int32_t user_variable_status = backend["conn"]["status"]["user_variable"]; + ok(user_variable_status == true, "Connection status should reflect that a 'user_variable' have been set."); + } + } + + mysql_close(proxysql_mysql); + } + + // PREPARED STATEMENT + { + 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; + } + + const std::vector prepared_stmt_queries { "PREPARE stmt_test FROM 'SELECT 1'", "PROXYSQL INTERNAL SESSION" }; + json j_status; + + for (const auto& query : prepared_stmt_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool prepared_stmt = backend["conn"]["status"]["prepared_statement"]; + ok(prepared_stmt == true, "Connection status should reflect that a 'prepared statement' have been prepared."); + + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to the 'prepared statement'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_LOCK_TABLES + { + 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; + } + + const char* create_test_table = + "CREATE TABLE IF NOT EXISTS sysbench.test_session_var (" + " c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + " c2 VARCHAR(100)," + " c3 VARCHAR(100)" + ")"; + const std::vector prepared_stmt_queries { + create_test_table, + "LOCK TABLES sysbench.test_session_var READ", + "PROXYSQL INTERNAL SESSION", + // Set a variable so we make sure connection is not dropped after "UNLOCK TABLES" + "SET @test_variable = 43", + "UNLOCK TABLES", + "PROXYSQL INTERNAL SESSION", + "DROP TABLE sysbench.test_session_var" + }; + + std::vector vj_status; + + for (const auto& query : prepared_stmt_queries) { + json j_status; + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + vj_status.push_back(j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr) { + bool lock_tables = backend["conn"]["status"]["lock_tables"]; + ok(lock_tables == true, "Connection status should reflect that 'LOCK TABLE' have been executed."); + } + } + + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr) { + bool unlock_tables = backend["conn"]["status"]["lock_tables"]; + ok(unlock_tables == false, "Connection status should reflect that 'UNLOCK TABLE' have been executed."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_TEMPORARY_TABLE + { + 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; + } + + const char* create_test_table = + "CREATE TEMPORARY TABLE IF NOT EXISTS sysbench.test_temp_table_session_var (" + " c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + " c2 VARCHAR(100)," + " c3 VARCHAR(100)" + ")"; + const std::vector prepared_stmt_queries { + create_test_table, + "PROXYSQL INTERNAL SESSION", + "DROP TABLE sysbench.test_temp_table_session_var" + }; + json j_status; + + for (const auto& query : prepared_stmt_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool temp_table = backend["conn"]["status"]["temporary_table"]; + ok(temp_table == true, "Connection status should reflect that a 'CREATE TEMPORARY TABLE' have been executed."); + + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'CREATE TEMPORARY TABLE'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_GET_LOCK + // TODO: Check why when GET_LOCK is executed the first backend is "NULL", and not filled like in the rest + { + 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; + } + + const std::vector prepared_stmt_queries { + "SELECT 1", + "SELECT GET_LOCK('test_session_vars_lock', 2)", + "PROXYSQL INTERNAL SESSION", + "SELECT RELEASE_LOCK('test_session_vars_lock')" + }; + json j_status; + + for (const auto& query : prepared_stmt_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool lock_tables = backend["conn"]["status"]["get_lock"]; + ok(lock_tables == true, "Connection status should reflect that a 'GET_LOCK' have been executed."); + + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'GET_LOCK'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_NO_MULTIPLEX - SET VARIABLE + { + 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; + } + + const std::vector prepared_stmt_queries { + "SET @test_variable = 44", + "PROXYSQL INTERNAL SESSION", + }; + json j_status; + + for (const auto& query : prepared_stmt_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool user_variable = backend["conn"]["status"]["user_variable"]; + ok(user_variable == true, "Connection status should have 'status.user_variable' set due to 'SET @variable'."); + + bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; + ok(no_multiplex == true, "Connection status should have 'no_multiplex' set due to 'SET @variable'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_NO_MULTIPLEX - TRANSACTION SHOULD NOT REPORT DISABLED MULTIPLEXING + + // Transaction detection is done through server status, while the MULTIPLEXING will be disabled for the connection and + // the connection wont be returned to the connection pool, both of the metrics 'MultiplexDisabled' and 'status.no_multiplex' + // will report 'false'. + { + 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; + } + + const std::vector transaction_queries { "START TRANSACTION", "SELECT 1", "PROXYSQL INTERNAL SESSION", "COMMIT" }; + json j_status; + + for (const auto& query : transaction_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to false even with 'START TRANSACTION'."); + + bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; + ok(no_multiplex == false, "Connection status should have 'no_multiplex' set to false even with 'START TRANSACTION'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_NO_MULTIPLEX - Multiplex disabled due to STATUS_MYSQL_CONNECTION_LOCK_TABLES + { + 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; + } + + const char* create_test_table = + "CREATE TABLE IF NOT EXISTS sysbench.test_session_var (" + " c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + " c2 VARCHAR(100)," + " c3 VARCHAR(100)" + ")"; + + const std::vector lock_tables_queries { + create_test_table, + "LOCK TABLES sysbench.test_session_var READ", + "PROXYSQL INTERNAL SESSION", + "UNLOCK TABLES", + "PROXYSQL INTERNAL SESSION", + "DROP TABLE sysbench.test_session_var" + }; + + std::vector vj_status; + + for (const auto& query : lock_tables_queries) { + json j_status; + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + vj_status.push_back(j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr) { + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'LOCK TABLES'."); + } + } + + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr) { + ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'UNLOCK TABLES'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0 - Multiplex disabled due to STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0 + { + 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; + } + + const std::vector sql_log_bin_queries { + "SET SQL_LOG_BIN=0", + "SELECT 1", + "PROXYSQL INTERNAL SESSION" + }; + + json j_status; + + for (const auto& query : sql_log_bin_queries) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr) { + bool sql_log_bin0 = backend["conn"]["status"]["sql_log_bin0"]; + ok(sql_log_bin0 == true, "Connection status should have 'status.sql_log_bin0' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); + + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_FOUND_ROWS - Multiplex disabled due to STATUS_MYSQL_CONNECTION_FOUND_ROWS + { + 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; + } + + const char* create_test_table = + "CREATE TABLE IF NOT EXISTS sysbench.test_session_var (" + " c1 INT NOT NULL AUTO_INCREMENT PRIMARY KEY," + " c2 VARCHAR(100)," + " c3 VARCHAR(100)" + ")"; + + const std::vector found_rows { + create_test_table, + "SELECT SQL_CALC_FOUND_ROWS * from sysbench.test_session_var", + "SELECT FOUND_ROWS()", + "PROXYSQL INTERNAL SESSION" + }; + + json j_status; + + for (const auto& query : found_rows) { + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + bool found_rows = backend["conn"]["status"]["found_rows"]; + ok(found_rows == true, "Connection status should have 'status.found_rows' set to 'true' 'DUE TO 'SQL_CALC_FOUND_ROWS'."); + + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SQL_CALC_FOUND_ROWS'."); + } + } + + mysql_close(proxysql_mysql); + } + + // STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT - Multiplex disabled due to STATUS_MYSQL_CONNECTION_HAS_SAVEPOINT + { + 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; + } + + const std::vector savepoint_queries { + "SET AUTOCOMMIT=0", + "SAVEPOINT test_session_variables_savepoint", + "PROXYSQL INTERNAL SESSION", + "COMMIT" + }; + + std::vector vj_status; + + for (const auto& query : savepoint_queries) { + json j_status; + MYSQL_QUERY(proxysql_mysql, query.c_str()); + MYSQL_RES* tr_res = mysql_store_result(proxysql_mysql); + if (query == "PROXYSQL INTERNAL SESSION") { + parse_result_json_column(tr_res, j_status); + vj_status.push_back(j_status); + } + mysql_free_result(tr_res); + } + + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr) { + bool found_rows = backend["conn"]["status"]["has_savepoint"]; + ok(found_rows == true, "Connection status should have 'status.has_savepoint' set to 'true' 'DUE TO 'SAVEPOINT'."); + + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SAVEPOINT'."); + } + } + + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr) { + ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'COMMIT'."); + + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to 'false' 'DUE TO 'COMMIT'."); + } + } + + mysql_close(proxysql_mysql); + } +} \ No newline at end of file From 9eda5a6d0a9544f4a2f393dab15d499eb7cee76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 12 Jun 2020 19:04:17 +0200 Subject: [PATCH 3/6] Removed 'sql_log_bin0' from 'conn.status' because it's a session variable and added 'compression' --- lib/MySQL_Session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 6bb623244..483f4c83a 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -1024,7 +1024,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["backends"][i]["conn"]["status"]["user_variable"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_USER_VARIABLE); j["backends"][i]["conn"]["status"]["found_rows"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_FOUND_ROWS); j["backends"][i]["conn"]["status"]["no_multiplex"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_NO_MULTIPLEX); - j["backends"][i]["conn"]["status"]["sql_log_bin0"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_SQL_LOG_BIN0); + j["backends"][i]["conn"]["status"]["compression"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_COMPRESSION); j["backends"][i]["conn"]["status"]["prepared_statement"] = _myconn->get_status(STATUS_MYSQL_CONNECTION_PREPARED_STATEMENT); j["backends"][i]["conn"]["MultiplexDisabled"] = _myconn->MultiplexDisabled(); j["backends"][i]["conn"]["ps"]["backend_stmt_to_global_ids"] = _myconn->local_stmts->backend_stmt_to_global_ids; From 1f958489cee6e16736ede7d16f3b3d1b5c4e4fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Fri, 12 Jun 2020 19:06:49 +0200 Subject: [PATCH 4/6] Removed unused code and added missing return with 'exit_status()' --- test/tap/tests/test_session_status_flags-t.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/tap/tests/test_session_status_flags-t.cpp b/test/tap/tests/test_session_status_flags-t.cpp index 7e2531f51..76044ea8a 100644 --- a/test/tap/tests/test_session_status_flags-t.cpp +++ b/test/tap/tests/test_session_status_flags-t.cpp @@ -34,8 +34,6 @@ int main(int argc, char *argv[]) { { MYSQL* proxysql_mysql = mysql_init(NULL); - // Waiting for proxysql to be ready - uint con_waited = 0; 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; @@ -554,4 +552,6 @@ int main(int argc, char *argv[]) { mysql_close(proxysql_mysql); } -} \ No newline at end of file + + return exit_status(); +} From 2aef129325b73614916204e47ba35bd995623863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Sat, 13 Jun 2020 01:20:43 +0200 Subject: [PATCH 5/6] Added checks to verify information contained in 'backends' before trying to access it --- .../tap/tests/test_session_status_flags-t.cpp | 36 +++++++++++-------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/test/tap/tests/test_session_status_flags-t.cpp b/test/tap/tests/test_session_status_flags-t.cpp index 76044ea8a..2397956a2 100644 --- a/test/tap/tests/test_session_status_flags-t.cpp +++ b/test/tap/tests/test_session_status_flags-t.cpp @@ -52,8 +52,12 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - int32_t server_status = j_status["backends"][0]["conn"]["mysql"]["server_status"]; - ok(server_status & 0x01, "Connection status should reflect being in a transaction"); + for (auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + int32_t server_status = backend["conn"]["mysql"]["server_status"]; + ok(server_status & 0x01, "Connection status should reflect being in a transaction"); + } + } mysql_close(proxysql_mysql); } @@ -104,7 +108,7 @@ int main(int argc, char *argv[]) { } for (auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { int32_t user_variable_status = backend["conn"]["status"]["user_variable"]; ok(user_variable_status == true, "Connection status should reflect that a 'user_variable' have been set."); } @@ -135,7 +139,7 @@ int main(int argc, char *argv[]) { } for (auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool prepared_stmt = backend["conn"]["status"]["prepared_statement"]; ok(prepared_stmt == true, "Connection status should reflect that a 'prepared statement' have been prepared."); @@ -187,14 +191,14 @@ int main(int argc, char *argv[]) { } for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool lock_tables = backend["conn"]["status"]["lock_tables"]; ok(lock_tables == true, "Connection status should reflect that 'LOCK TABLE' have been executed."); } } for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool unlock_tables = backend["conn"]["status"]["lock_tables"]; ok(unlock_tables == false, "Connection status should reflect that 'UNLOCK TABLE' have been executed."); } @@ -235,7 +239,7 @@ int main(int argc, char *argv[]) { } for (const auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool temp_table = backend["conn"]["status"]["temporary_table"]; ok(temp_table == true, "Connection status should reflect that a 'CREATE TEMPORARY TABLE' have been executed."); @@ -275,7 +279,7 @@ int main(int argc, char *argv[]) { } for (auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool lock_tables = backend["conn"]["status"]["get_lock"]; ok(lock_tables == true, "Connection status should reflect that a 'GET_LOCK' have been executed."); @@ -312,7 +316,7 @@ int main(int argc, char *argv[]) { } for (const auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool user_variable = backend["conn"]["status"]["user_variable"]; ok(user_variable == true, "Connection status should have 'status.user_variable' set due to 'SET @variable'."); @@ -350,7 +354,7 @@ int main(int argc, char *argv[]) { } for (const auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to false even with 'START TRANSACTION'."); @@ -401,14 +405,14 @@ int main(int argc, char *argv[]) { } for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'LOCK TABLES'."); } } for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'UNLOCK TABLES'."); } } @@ -443,12 +447,14 @@ int main(int argc, char *argv[]) { } for (const auto& backend : j_status["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool sql_log_bin0 = backend["conn"]["status"]["sql_log_bin0"]; ok(sql_log_bin0 == true, "Connection status should have 'status.sql_log_bin0' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); + } else { + ok(false, "'backends' doens't contains 'conn' objects with the relevant session information"); } } @@ -532,7 +538,7 @@ int main(int argc, char *argv[]) { } for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { bool found_rows = backend["conn"]["status"]["has_savepoint"]; ok(found_rows == true, "Connection status should have 'status.has_savepoint' set to 'true' 'DUE TO 'SAVEPOINT'."); @@ -542,7 +548,7 @@ int main(int argc, char *argv[]) { } for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'COMMIT'."); bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; From 28fa6fa241f675c25844c4b51e65808eb0c8dddd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Sat, 13 Jun 2020 10:48:09 +0200 Subject: [PATCH 6/6] Added backend connections field check to avoid asserts in case of errors --- .../tap/tests/test_session_status_flags-t.cpp | 292 +++++++++++++----- 1 file changed, 210 insertions(+), 82 deletions(-) diff --git a/test/tap/tests/test_session_status_flags-t.cpp b/test/tap/tests/test_session_status_flags-t.cpp index 2397956a2..3248b738d 100644 --- a/test/tap/tests/test_session_status_flags-t.cpp +++ b/test/tap/tests/test_session_status_flags-t.cpp @@ -52,11 +52,20 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - int32_t server_status = backend["conn"]["mysql"]["server_status"]; - ok(server_status & 0x01, "Connection status should reflect being in a transaction"); + 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; + int32_t server_status = backend["conn"]["mysql"]["server_status"]; + ok(server_status & 0x01, "Connection status should reflect being in a transaction"); + } } + 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); @@ -107,11 +116,20 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - int32_t user_variable_status = backend["conn"]["status"]["user_variable"]; - ok(user_variable_status == true, "Connection status should reflect that a 'user_variable' have been set."); + 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; + int32_t user_variable_status = backend["conn"]["status"]["user_variable"]; + ok(user_variable_status == true, "Connection status should reflect that a 'user_variable' have been set."); + } } + 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); @@ -138,14 +156,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool prepared_stmt = backend["conn"]["status"]["prepared_statement"]; - ok(prepared_stmt == true, "Connection status should reflect that a 'prepared statement' have been prepared."); + 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 prepared_stmt = backend["conn"]["status"]["prepared_statement"]; + ok(prepared_stmt == true, "Connection status should reflect that a 'prepared statement' have been prepared."); - bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; - ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to the 'prepared statement'."); + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to the 'prepared statement'."); + } } + 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); @@ -190,18 +217,36 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool lock_tables = backend["conn"]["status"]["lock_tables"]; - ok(lock_tables == true, "Connection status should reflect that 'LOCK TABLE' have been executed."); + if (vj_status[0].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool lock_tables = backend["conn"]["status"]["lock_tables"]; + ok(lock_tables == true, "Connection status should reflect that 'LOCK TABLE' have been executed."); + } } - } - - for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool unlock_tables = backend["conn"]["status"]["lock_tables"]; - ok(unlock_tables == false, "Connection status should reflect that 'UNLOCK TABLE' have been executed."); + 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."); + } + + if (vj_status[1].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool unlock_tables = backend["conn"]["status"]["lock_tables"]; + ok(unlock_tables == false, "Connection status should reflect that 'UNLOCK TABLE' have been executed."); + } + } + 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); @@ -238,14 +283,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool temp_table = backend["conn"]["status"]["temporary_table"]; - ok(temp_table == true, "Connection status should reflect that a 'CREATE TEMPORARY TABLE' have been executed."); + if (j_status.contains("backends")) { + bool found_backend = false; + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool temp_table = backend["conn"]["status"]["temporary_table"]; + ok(temp_table == true, "Connection status should reflect that a 'CREATE TEMPORARY TABLE' have been executed."); - bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; - ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'CREATE TEMPORARY TABLE'."); + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'CREATE TEMPORARY TABLE'."); + } + } + 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); @@ -278,14 +332,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool lock_tables = backend["conn"]["status"]["get_lock"]; - ok(lock_tables == true, "Connection status should reflect that a 'GET_LOCK' have been executed."); + 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 lock_tables = backend["conn"]["status"]["get_lock"]; + ok(lock_tables == true, "Connection status should reflect that a 'GET_LOCK' have been executed."); - bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; - ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'GET_LOCK'."); + bool multiplex_disabled = backend["conn"]["MultiplexDisabled"]; + ok(multiplex_disabled == true, "Connection status should reflect that 'MultiplexDisabled' is enabled due to 'GET_LOCK'."); + } + } + 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); @@ -315,14 +378,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool user_variable = backend["conn"]["status"]["user_variable"]; - ok(user_variable == true, "Connection status should have 'status.user_variable' set due to 'SET @variable'."); + if (j_status.contains("backends")) { + bool found_backend = false; + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool user_variable = backend["conn"]["status"]["user_variable"]; + ok(user_variable == true, "Connection status should have 'status.user_variable' set due to 'SET @variable'."); - bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; - ok(no_multiplex == true, "Connection status should have 'no_multiplex' set due to 'SET @variable'."); + bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; + ok(no_multiplex == true, "Connection status should have 'no_multiplex' set due to 'SET @variable'."); + } + } + 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); @@ -353,14 +425,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to false even with 'START TRANSACTION'."); + if (j_status.contains("backends")) { + bool found_backend = false; + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to false even with 'START TRANSACTION'."); - bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; - ok(no_multiplex == false, "Connection status should have 'no_multiplex' set to false even with 'START TRANSACTION'."); + bool no_multiplex = backend["conn"]["status"]["no_multiplex"]; + ok(no_multiplex == false, "Connection status should have 'no_multiplex' set to false even with 'START TRANSACTION'."); + } + } + 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); @@ -404,17 +485,35 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'LOCK TABLES'."); + if (vj_status[0].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'LOCK TABLES'."); + } + } + 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."); } - for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'UNLOCK TABLES'."); + if (vj_status[1].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr) { + found_backend = true; + ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'UNLOCK TABLES'."); + } } + 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); @@ -446,16 +545,20 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool sql_log_bin0 = backend["conn"]["status"]["sql_log_bin0"]; - ok(sql_log_bin0 == true, "Connection status should have 'status.sql_log_bin0' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); - - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); - } else { + if (j_status.contains("backends")) { + bool found_backend = false; + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SET SQL_LOG_BIN'."); + } + } + 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); @@ -495,14 +598,23 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : j_status["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool found_rows = backend["conn"]["status"]["found_rows"]; - ok(found_rows == true, "Connection status should have 'status.found_rows' set to 'true' 'DUE TO 'SQL_CALC_FOUND_ROWS'."); + if (j_status.contains("backends")) { + bool found_backend = false; + for (const auto& backend : j_status["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool found_rows = backend["conn"]["status"]["found_rows"]; + ok(found_rows == true, "Connection status should have 'status.found_rows' set to 'true' 'DUE TO 'SQL_CALC_FOUND_ROWS'."); - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SQL_CALC_FOUND_ROWS'."); + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO '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); @@ -521,7 +633,8 @@ int main(int argc, char *argv[]) { "SET AUTOCOMMIT=0", "SAVEPOINT test_session_variables_savepoint", "PROXYSQL INTERNAL SESSION", - "COMMIT" + "COMMIT", + "PROXYSQL INTERNAL SESSION" }; std::vector vj_status; @@ -537,23 +650,38 @@ int main(int argc, char *argv[]) { mysql_free_result(tr_res); } - for (const auto& backend : vj_status[0]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - bool found_rows = backend["conn"]["status"]["has_savepoint"]; - ok(found_rows == true, "Connection status should have 'status.has_savepoint' set to 'true' 'DUE TO 'SAVEPOINT'."); + if (vj_status[0].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[0]["backends"]) { + if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { + found_backend = true; + bool found_rows = backend["conn"]["status"]["has_savepoint"]; + ok(found_rows == true, "Connection status should have 'status.has_savepoint' set to 'true' 'DUE TO 'SAVEPOINT'."); - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SAVEPOINT'."); + bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; + ok(MultiplexDisabled == true, "Connection status should have 'MultiplexDisabled' set to 'true' 'DUE TO 'SAVEPOINT'."); + } + } + 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."); } - for (const auto& backend : vj_status[1]["backends"]) { - if (backend != nullptr && backend.contains("conn") && backend["conn"].contains("status")) { - ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'COMMIT'."); - - bool MultiplexDisabled = backend["conn"]["MultiplexDisabled"]; - ok(MultiplexDisabled == false, "Connection status should have 'MultiplexDisabled' set to 'false' 'DUE TO 'COMMIT'."); + if (vj_status[1].contains("backends")) { + bool found_backend = false; + for (const auto& backend : vj_status[1]["backends"]) { + if (backend != nullptr) { + found_backend = true; + ok(backend.contains("conn") == false, "Connection should be returned to the connection pool due to 'COMMIT'."); + } + } + 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);