Merge branch 'v2.1.0' into v2.1.0-cherrypicks_2.0.13_2

pull/2886/head
René Cannaò 6 years ago committed by GitHub
commit b9645b39dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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
@ -136,30 +145,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();

@ -986,8 +986,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; k<mybes->len; k++) {
MySQL_Backend *_mybe = NULL;
@ -1029,13 +1029,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"]["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;
j["backends"][i]["conn"]["ps"]["global_stmt_to_backend_ids"] = _myconn->local_stmts->global_stmt_to_backend_ids;
@ -2066,12 +2068,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;
@ -2515,7 +2517,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) {
@ -6403,7 +6405,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) {

@ -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);
}
}
}

@ -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);
}
}
}

@ -105,10 +105,4 @@ test_tokenizer-t: test_tokenizer-t.cpp $(TAP_LIBDIR)/libtap.a
g++ test_tokenizer-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(MYLIBS) -lproxysql -ltap -Wl,--no-as-needed -ldl -lpthread -o test_tokenizer-t -DGITVERSION=\"$(GIT_VERSION)\"
1493_mixed_compression: reg_test_1493-mixed_compression-t.cpp
g++ -DDEBUG test_mixed_compression-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(OBJ) $(MYLIBS) -ltap -ldl $(STATIC_LIBS) -o reg_test_1493-mixed_compression-t -DGITVERSION=\"$(GIT_VERSION)\"
2793_compression: reg_test_2793-compression-t.cpp
g++ -DTEST_AURORA -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)\"
create_connection_annotation: test_connection_annotation-t.cpp
g++ -DTEST_AURORA -DDEBUG test_connection_annotation-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(OBJ) $(MYLIBS) -ltap -ldl $(STATIC_LIBS) -o test_connection_annotation-t -DGITVERSION=\"$(GIT_VERSION)\"
g++ -DDEBUG test_mixed_compression-t.cpp $(INCLUDEDIRS) $(LDIRS) $(OPT) -std=c++11 $(OBJ) $(MYLIBS) -ltap -ldl $(STATIC_LIBS) -o reg_test_1493-mixed_compression-t -DGITVERSION=\"$(GIT_VERSION)\"

@ -0,0 +1,691 @@
/**
* @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 <stdio.h>
#include <mysql.h>
#include <string.h>
#include <string>
#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);
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<std::string> 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);
}
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);
}
{
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<std::string> 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);
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> 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<json> 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);
}
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.");
}
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> 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<json> 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);
}
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.");
}
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);
}
// 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<std::string> 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);
}
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);
}
// 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<std::string> 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);
}
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'.");
}
}
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);
}
// 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<std::string> savepoint_queries {
"SET AUTOCOMMIT=0",
"SAVEPOINT test_session_variables_savepoint",
"PROXYSQL INTERNAL SESSION",
"COMMIT",
"PROXYSQL INTERNAL SESSION"
};
std::vector<json> 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);
}
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'.");
}
}
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) {
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);
}
return exit_status();
}
Loading…
Cancel
Save