make MySQL_Variables a global variable

pull/2650/head
val 6 years ago
parent dab4f8a4ae
commit b0ca1a030f

@ -3,9 +3,12 @@
#include "proxysql.h"
#include "cpp.h"
#include "MySQL_Variables.h"
#define RESULTSET_BUFLEN 16300
extern MySQL_Variables mysql_variables;
class MySQL_ResultSet {
private:
public:

@ -1,13 +1,13 @@
#ifndef __CLASS_MYSQL_SESSION_H
#define __CLASS_MYSQL_SESSION_H
#include "MySQL_Variables.h"
#include "proxysql.h"
#include "cpp.h"
#include "MySQL_Variables.h"
#include "../deps/json/json.hpp"
using json = nlohmann::json;
class MySQL_Variables;
extern class MySQL_Variables mysql_variables;
enum proxysql_session_type {
PROXYSQL_SESSION_MYSQL,
@ -151,7 +151,6 @@ class MySQL_Session
MySQL_Data_Stream *client_myds;
MySQL_Data_Stream *server_myds;
char * default_schema;
std::unique_ptr<MySQL_Variables> mysql_variables {nullptr};
//this pointer is always initialized inside handler().
// it is an attempt to start simplifying the complexing of handler()

@ -3,6 +3,7 @@
#define ____CLASS_STANDARD_MYSQL_THREAD_H
#include "proxysql.h"
#include "cpp.h"
#include "MySQL_Variables.h"
#ifdef IDLE_THREADS
#include <sys/epoll.h>
#endif // IDLE_THREADS
@ -22,6 +23,8 @@
#define MYSQL_DEFAULT_NET_WRITE_TIMEOUT "60"
#define MYSQL_DEFAULT_MAX_JOIN_SIZE "18446744073709551615"
extern class MySQL_Variables mysql_variables;
#ifdef IDLE_THREADS
typedef struct __attribute__((aligned(64))) _conn_exchange_t {
pthread_mutex_t mutex_idles;

@ -20,31 +20,30 @@ typedef bool (*update_var)(MySQL_Session* session, int idx, int &_rc);
bool validate_charset(MySQL_Session* session, int idx, int &_rc);
bool update_server_variable(MySQL_Session* session, int idx, int &_rc);
bool verify_variable(MySQL_Session* session, int idx, uint32_t client_hash, uint32_t server_hash);
bool verify_server_variable(MySQL_Session* session, int idx, uint32_t client_hash, uint32_t server_hash);
bool logbin_update_server_variable(MySQL_Session* session, int idx, int &_rc);
class MySQL_Variables {
MySQL_Session* session;
verify_var verifiers[SQL_NAME_LAST];
update_var updaters[SQL_NAME_LAST];
static verify_var verifiers[SQL_NAME_LAST];
static update_var updaters[SQL_NAME_LAST];
public:
MySQL_Variables();
bool is_connected_to_backend;
MySQL_Variables(MySQL_Session* session);
virtual ~MySQL_Variables();
bool client_set_value(int idx, const std::string& value);
const char* client_get_value(int idx) const;
uint32_t client_get_hash(int idx) const;
bool client_set_value(MySQL_Session* session, int idx, const std::string& value);
const char* client_get_value(MySQL_Session* session, int idx) const;
uint32_t client_get_hash(MySQL_Session* session, int idx) const;
void server_set_value(int idx, const char* value);
const char* server_get_value(int idx) const;
inline uint32_t server_get_hash(int idx) const;
void server_set_value(MySQL_Session* session, int idx, const char* value);
const char* server_get_value(MySQL_Session* session, int idx) const;
inline uint32_t server_get_hash(MySQL_Session* session, int idx) const;
bool verify_variable(int idx) const;
bool update_variable(session_status status, int &_rc);
bool on_connect_to_backend(mysql_variable_st* tracked_variables);
bool verify_variable(MySQL_Session* session, int idx) const;
bool update_variable(MySQL_Session* session, session_status status, int &_rc);
bool on_connect_to_backend(MySQL_Session* session, mysql_variable_st* tracked_variables);
};
#endif // #ifndef MYSQL_VARIABLES_H

@ -1977,10 +1977,10 @@ __exit_do_auth:
/* We are processing handshake from client. Client sends us a character set it will use in communication.
* we store this character set in the client's variables to use later in multiplexing with different backends
*/
sess->mysql_variables->client_set_value(SQL_CHARACTER_SET_RESULTS, ss.str().c_str());
sess->mysql_variables->client_set_value(SQL_CHARACTER_SET_CLIENT, ss.str().c_str());
sess->mysql_variables->client_set_value(SQL_CHARACTER_SET_CONNECTION, ss.str().c_str());
sess->mysql_variables->client_set_value(SQL_COLLATION_CONNECTION, ss.str().c_str());
mysql_variables.client_set_value(sess, SQL_CHARACTER_SET_RESULTS, ss.str().c_str());
mysql_variables.client_set_value(sess, SQL_CHARACTER_SET_CLIENT, ss.str().c_str());
mysql_variables.client_set_value(sess, SQL_CHARACTER_SET_CONNECTION, ss.str().c_str());
mysql_variables.client_set_value(sess, SQL_COLLATION_CONNECTION, ss.str().c_str());
}
// enable compression
if (capabilities & CLIENT_COMPRESS) {

@ -496,7 +496,6 @@ void MySQL_Session::init() {
mybes= new PtrArray(4);
sess_STMTs_meta=new MySQL_STMTs_meta();
SLDH=new StmtLongDataHandler();
mysql_variables = std::unique_ptr<MySQL_Variables>(new MySQL_Variables(this));
}
void MySQL_Session::reset() {
@ -1969,7 +1968,7 @@ bool MySQL_Session::handler_again___status_SETTING_SQL_LOG_BIN(int *_rc) {
if (myconn->async_state_machine==ASYNC_IDLE) {
char *q=(char *)"SET SQL_LOG_BIN=%s";
query=(char *)malloc(strlen(q)+8);
sprintf(query,q,mysql_variables->client_get_value(SQL_LOG_BIN));
sprintf(query,q,mysql_variables.client_get_value(this, SQL_LOG_BIN));
query_length=strlen(query);
}
int rc=myconn->async_send_simple_command(myds->revents,query,query_length);
@ -1978,12 +1977,12 @@ bool MySQL_Session::handler_again___status_SETTING_SQL_LOG_BIN(int *_rc) {
query=NULL;
}
if (rc==0) {
if (!strcmp("0", mysql_variables->client_get_value(SQL_LOG_BIN)) || !strcasecmp("OFF", mysql_variables->client_get_value(SQL_LOG_BIN))) {
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);
} else if (!strcmp("1", mysql_variables->client_get_value(SQL_LOG_BIN)) || !strcasecmp("ON", mysql_variables->client_get_value(SQL_LOG_BIN))) {
} 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);
}
myds->revents|=POLLOUT; // we also set again POLLOUT to send a query immediately!
@ -3382,9 +3381,9 @@ handler_again:
goto handler_again;
}
if (mysql_variables->is_connected_to_backend) {
if (mysql_variables.is_connected_to_backend) {
for (auto i = 0; i < SQL_NAME_LAST; i++) {
if(mysql_tracked_variables[i].special_handling && mysql_variables->verify_variable(i)) {
if(mysql_tracked_variables[i].special_handling && mysql_variables.verify_variable(this, i)) {
goto handler_again;
}
}
@ -3912,7 +3911,7 @@ handler_again:
case SETTING_WSREP_SYNC_WAIT:
for (auto i = 0; i < SQL_NAME_LAST; i++) {
int rc = 0;
if (mysql_variables->update_variable(status, rc)) {
if (mysql_variables.update_variable(this, status, rc)) {
goto handler_again;
}
if (rc == -1) {
@ -4714,11 +4713,11 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (rc && ( i==0 || i==1) ) {
//fprintf(stderr,"sql_log_bin=%d\n", i);
if (i == 1) {
if (!mysql_variables->client_set_value(SQL_LOG_BIN, "1"))
if (!mysql_variables.client_set_value(this, SQL_LOG_BIN, "1"))
return false;
}
else if (i == 0) {
if (!mysql_variables->client_set_value(SQL_LOG_BIN, "0"))
if (!mysql_variables.client_set_value(this, SQL_LOG_BIN, "0"))
return false;
}
@ -4833,8 +4832,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET SQL Mode value %s\n", value1.c_str());
uint32_t sql_mode_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_SQL_MODE) != sql_mode_int) {
if (!mysql_variables->client_set_value(SQL_SQL_MODE, value1.c_str())) {
if (mysql_variables.client_get_hash(this, SQL_SQL_MODE) != sql_mode_int) {
if (!mysql_variables.client_set_value(this, SQL_SQL_MODE, value1.c_str())) {
return false;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection SQL Mode to %s\n", value1.c_str());
@ -4845,8 +4844,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if ((strcasecmp(value1.c_str(),"0")==0) || (strcasecmp(value1.c_str(),"1")==0)) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 7, "Processing SET wsrep_sync_wait value %s\n", value1.c_str());
uint32_t wsrep_sync_wait_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_WSREP_SYNC_WAIT) != wsrep_sync_wait_int) {
if (!mysql_variables->client_set_value(SQL_WSREP_SYNC_WAIT, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_WSREP_SYNC_WAIT) != wsrep_sync_wait_int) {
if (!mysql_variables.client_set_value(this, SQL_WSREP_SYNC_WAIT, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection session_track_gtids to %s\n", value1.c_str());
}
@ -4889,12 +4888,12 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
if (mysql_variables->client_get_hash(idx) != var_value_int) {
if (mysql_variables.client_get_hash(this, idx) != var_value_int) {
if (__tmp_value == 0) {
if (!mysql_variables->client_set_value(idx, "OFF"))
if (!mysql_variables.client_set_value(this, idx, "OFF"))
return false;
} else {
if (!mysql_variables->client_set_value(idx, "ON"))
if (!mysql_variables.client_set_value(this, idx, "ON"))
return false;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection %s to %s\n", var.c_str(), value1.c_str());
@ -4970,8 +4969,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET Time Zone value %s\n", value1.c_str());
uint32_t time_zone_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_TIME_ZONE) != time_zone_int) {
if (!mysql_variables->client_set_value(SQL_TIME_ZONE, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_TIME_ZONE) != time_zone_int) {
if (!mysql_variables.client_set_value(this, SQL_TIME_ZONE, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection Time zone to %s\n", value1.c_str());
}
@ -4981,8 +4980,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if ((strcasecmp(value1.c_str(),"OWN_GTID")==0) || (strcasecmp(value1.c_str(),"OFF")==0)) {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 7, "Processing SET session_track_gtids value %s\n", value1.c_str());
uint32_t session_track_gtids_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_SESSION_TRACK_GTIDS) != session_track_gtids_int) {
if (!mysql_variables->client_set_value(SQL_SESSION_TRACK_GTIDS, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_SESSION_TRACK_GTIDS) != session_track_gtids_int) {
if (!mysql_variables.client_set_value(this, SQL_SESSION_TRACK_GTIDS, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection session_track_gtids to %s\n", value1.c_str());
}
@ -5023,8 +5022,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
if (mysql_variables->client_get_hash(idx) != var_value_int) {
if (!mysql_variables->client_set_value(idx, value1.c_str()))
if (mysql_variables.client_get_hash(this, idx) != var_value_int) {
if (!mysql_variables.client_set_value(this, idx, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection %s to %s\n", var.c_str(), value1.c_str());
}
@ -5060,7 +5059,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
if (mysql_variables->client_get_hash(idx) != var_value_int) {
if (mysql_variables.client_get_hash(this, idx) != var_value_int) {
const MARIADB_CHARSET_INFO *ci = NULL;
if (var == "character_set_results" || var == "character_set_connection" ||
var == "character_set_client" || var == "character_set_database") {
@ -5072,11 +5071,11 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (!ci) {
if (var == "character_set_results") {
if (!strcasecmp("NULL", value1.c_str())) {
if (!mysql_variables->client_set_value(idx, "NULL")) {
if (!mysql_variables.client_set_value(this, idx, "NULL")) {
return false;
}
} else if (!strcasecmp("binary", value1.c_str())) {
if (!mysql_variables->client_set_value(idx, "binary")) {
if (!mysql_variables.client_set_value(this, idx, "binary")) {
return false;
}
} else {
@ -5091,18 +5090,18 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
* and vice versa
*/
if (var == "collation_connection") {
if (!mysql_variables->client_set_value(SQL_CHARACTER_SET_CONNECTION, ss.str().c_str()))
if (!mysql_variables.client_set_value(this, SQL_CHARACTER_SET_CONNECTION, ss.str().c_str()))
return false;
}
if (var == "character_set_connection") {
if (!mysql_variables->client_set_value(SQL_COLLATION_CONNECTION, ss.str().c_str()))
if (!mysql_variables.client_set_value(this, SQL_COLLATION_CONNECTION, ss.str().c_str()))
return false;
}
/* this is explicit statement from client. we do not multiplex, therefor we must
* remember client's choice in the client's variable for future use in verifications, multiplexing etc.
*/
if (!mysql_variables->client_set_value(idx, ss.str().c_str()))
if (!mysql_variables.client_set_value(this, idx, ss.str().c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection %s to %s\n", var.c_str(), value1.c_str());
}
@ -5159,8 +5158,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
if (pos != std::string::npos)
value1[pos] = ' ';
uint32_t isolation_level_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_ISOLATION_LEVEL) != isolation_level_int) {
if (!mysql_variables->client_set_value(SQL_ISOLATION_LEVEL, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_ISOLATION_LEVEL) != isolation_level_int) {
if (!mysql_variables.client_set_value(this, SQL_ISOLATION_LEVEL, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TX ISOLATION to %s\n", value1.c_str());
}
@ -5207,8 +5206,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
delete opt2;
if (rc) {
uint32_t sql_mode_int=SpookyHash::Hash32(s1.c_str(),s1.length(),10);
if (mysql_variables->client_get_hash(SQL_SQL_MODE) != sql_mode_int) {
if (!mysql_variables->client_set_value(SQL_SQL_MODE, s1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_SQL_MODE) != sql_mode_int) {
if (!mysql_variables.client_set_value(this, SQL_SQL_MODE, s1.c_str()))
return false;
std::size_t found_at = s1.find("@");
if (found_at != std::string::npos) {
@ -5276,8 +5275,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET SESSION TRANSACTION ISOLATION LEVEL value %s\n", value1.c_str());
uint32_t isolation_level_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_ISOLATION_LEVEL) != isolation_level_int) {
if (!mysql_variables->client_set_value(SQL_ISOLATION_LEVEL, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_ISOLATION_LEVEL) != isolation_level_int) {
if (!mysql_variables.client_set_value(this, SQL_ISOLATION_LEVEL, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TRANSACTION ISOLATION LEVEL to %s\n", value1.c_str());
}
@ -5286,8 +5285,8 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET SESSION TRANSACTION READ value %s\n", value1.c_str());
uint32_t transaction_read_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables->client_get_hash(SQL_TRANSACTION_READ) != transaction_read_int) {
if (!mysql_variables->client_set_value(SQL_TRANSACTION_READ, value1.c_str()))
if (mysql_variables.client_get_hash(this, SQL_TRANSACTION_READ) != transaction_read_int) {
if (!mysql_variables.client_set_value(this, SQL_TRANSACTION_READ, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TRANSACTION READ to %s\n", value1.c_str());
}
@ -5733,7 +5732,7 @@ void MySQL_Session::handler___client_DSS_QUERY_SENT___server_DSS_NOT_INITIALIZED
status=CONNECTING_SERVER;
mybe->server_myds->myconn->reusable=true;
} else {
mysql_variables->on_connect_to_backend(mysql_tracked_variables);
mysql_variables.on_connect_to_backend(this, mysql_tracked_variables);
proxy_debug(PROXY_DEBUG_MYSQL_CONNECTION, 5, "Sess=%p -- MySQL Connection found = %p\n", this, mybe->server_myds->myconn);
mybe->server_myds->assign_fd_from_mysql_conn();
mybe->server_myds->myds_type=MYDS_BACKEND;

@ -14,7 +14,6 @@
#include "StatCounters.h"
#include "MySQL_PreparedStatement.h"
#include "MySQL_Logger.hpp"
#include "MySQL_Variables.h"
#ifdef DEBUG
MySQL_Session *sess_stopat;
@ -3309,7 +3308,7 @@ MySQL_Session * MySQL_Thread::create_new_session_and_client_data_stream(int _fd)
}
std::stringstream ss;
ss << ci->nr;
sess->mysql_variables->client_set_value(i, ss.str());
mysql_variables.client_set_value(sess, i, ss.str());
} else if (i == SQL_COLLATION_CONNECTION) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_collate(mysql_thread___default_variables[i]);
@ -3320,9 +3319,9 @@ MySQL_Session * MySQL_Thread::create_new_session_and_client_data_stream(int _fd)
}
std::stringstream ss;
ss << ci->nr;
sess->mysql_variables->client_set_value(i, ss.str());
mysql_variables.client_set_value(sess, i, ss.str());
} else {
sess->mysql_variables->client_set_value(i, mysql_thread___default_variables[i]);
mysql_variables.client_set_value(sess, i, mysql_thread___default_variables[i]);
}
}

@ -7,9 +7,11 @@
#include <sstream>
MySQL_Variables::MySQL_Variables(MySQL_Session* _session) : session(_session), is_connected_to_backend(false) {
assert(_session);
verify_var MySQL_Variables::verifiers[SQL_NAME_LAST];
update_var MySQL_Variables::updaters[SQL_NAME_LAST];
MySQL_Variables::MySQL_Variables() {
for (auto i = 0; i < SQL_NAME_LAST; i++) {
switch(i) {
case SQL_SAFE_UPDATES:
@ -28,22 +30,22 @@ MySQL_Variables::MySQL_Variables(MySQL_Session* _session) : session(_session), i
case SQL_NET_WRITE_TIMEOUT:
case SQL_MAX_JOIN_SIZE:
case SQL_WSREP_SYNC_WAIT:
verifiers[i] = ::verify_variable;
updaters[i] = update_server_variable;
MySQL_Variables::verifiers[i] = verify_server_variable;
MySQL_Variables::updaters[i] = update_server_variable;
break;
case SQL_LOG_BIN:
verifiers[i] = ::verify_variable;
updaters[i] = logbin_update_server_variable;
MySQL_Variables::verifiers[i] = verify_server_variable;
MySQL_Variables::updaters[i] = logbin_update_server_variable;
break;
default:
updaters[i] = NULL;
MySQL_Variables::updaters[i] = NULL;
}
}
}
MySQL_Variables::~MySQL_Variables() {}
bool MySQL_Variables::on_connect_to_backend(mysql_variable_st *tracked_variables) {
bool MySQL_Variables::on_connect_to_backend(MySQL_Session* session, mysql_variable_st *tracked_variables) {
if (!session || !session->mybe || !session->mybe->server_myds || !session->mybe->server_myds->myconn) return false;
auto be_version = session->mybe->server_myds->myconn->mysql->server_version;
@ -77,7 +79,7 @@ bool MySQL_Variables::on_connect_to_backend(mysql_variable_st *tracked_variables
return true;
}
bool MySQL_Variables::client_set_value(int idx, const std::string& value) {
bool MySQL_Variables::client_set_value(MySQL_Session* session, int idx, const std::string& value) {
if (!session || !session->client_myds || !session->client_myds->myconn) {
proxy_warning("Session validation failed\n");
return false;
@ -92,20 +94,20 @@ bool MySQL_Variables::client_set_value(int idx, const std::string& value) {
case SQL_CHARACTER_ACTION:
// SET NAMES command from client
if (value == "1") {
if (session->mysql_variables->client_get_value(SQL_CHARACTER_SET)) {
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_RESULTS, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CLIENT, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CONNECTION, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_COLLATION_CONNECTION, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
if (mysql_variables.client_get_value(session, SQL_CHARACTER_SET)) {
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_RESULTS, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CLIENT, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CONNECTION, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_COLLATION_CONNECTION, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
}
}
// SET CHARSET command from client
else if (value == "2") {
if (session->mysql_variables->client_get_value(SQL_CHARACTER_SET)) {
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_RESULTS, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CLIENT, session->mysql_variables->client_get_value(SQL_CHARACTER_SET));
if (mysql_variables.client_get_value(session, SQL_CHARACTER_SET)) {
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_RESULTS, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CLIENT, mysql_variables.client_get_value(session, SQL_CHARACTER_SET));
}
if (session->mysql_variables->client_get_value(SQL_CHARACTER_SET_DATABASE)) {
if (mysql_variables.client_get_value(session, SQL_CHARACTER_SET_DATABASE)) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_name(mysql_tracked_variables[SQL_CHARACTER_SET_CONNECTION].default_value);
@ -113,7 +115,7 @@ bool MySQL_Variables::client_set_value(int idx, const std::string& value) {
std::stringstream ss;
ss << nr;
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CONNECTION, ss.str());
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CONNECTION, ss.str());
ci = proxysql_find_charset_collate(mysql_tracked_variables[SQL_COLLATION_CONNECTION].default_value);
nr = ci->nr;
@ -121,16 +123,16 @@ bool MySQL_Variables::client_set_value(int idx, const std::string& value) {
ss.clear();
ss << nr;
session->mysql_variables->client_set_value(SQL_COLLATION_CONNECTION, ss.str());
mysql_variables.client_set_value(session, SQL_COLLATION_CONNECTION, ss.str());
}
}
// SET NAMES during handshake etc.
else if (value == "3") {
if (session->mysql_variables->server_get_value(SQL_CHARACTER_SET)) {
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_RESULTS, session->mysql_variables->server_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CLIENT, session->mysql_variables->server_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_CHARACTER_SET_CONNECTION, session->mysql_variables->server_get_value(SQL_CHARACTER_SET));
session->mysql_variables->client_set_value(SQL_COLLATION_CONNECTION, session->mysql_variables->server_get_value(SQL_CHARACTER_SET));
if (mysql_variables.server_get_value(session, SQL_CHARACTER_SET)) {
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_RESULTS, mysql_variables.server_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CLIENT, mysql_variables.server_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_CHARACTER_SET_CONNECTION, mysql_variables.server_get_value(session, SQL_CHARACTER_SET));
mysql_variables.client_set_value(session, SQL_COLLATION_CONNECTION, mysql_variables.server_get_value(session, SQL_CHARACTER_SET));
}
}
}
@ -144,17 +146,17 @@ bool MySQL_Variables::client_set_value(int idx, const std::string& value) {
return true;
}
const char* MySQL_Variables::client_get_value(int idx) const {
const char* MySQL_Variables::client_get_value(MySQL_Session* session, int idx) const {
if (!session || !session->client_myds || !session->client_myds->myconn) return NULL;
return session->client_myds->myconn->variables[idx].value;
}
uint32_t MySQL_Variables::client_get_hash(int idx) const {
uint32_t MySQL_Variables::client_get_hash(MySQL_Session* session, int idx) const {
if (!session || !session->client_myds || !session->client_myds->myconn) return 0;
return session->client_myds->myconn->var_hash[idx];
}
void MySQL_Variables::server_set_value(int idx, const char* value) {
void MySQL_Variables::server_set_value(MySQL_Session* session, int idx, const char* value) {
if (!session || !session->mybe || !session->mybe->server_myds || !session->mybe->server_myds->myconn || !value) return;
session->mybe->server_myds->myconn->var_hash[idx] = SpookyHash::Hash32(value,strlen(value),10);
@ -164,17 +166,17 @@ void MySQL_Variables::server_set_value(int idx, const char* value) {
session->mybe->server_myds->myconn->variables[idx].value = strdup(value);
}
const char* MySQL_Variables::server_get_value(int idx) const {
const char* MySQL_Variables::server_get_value(MySQL_Session* session, int idx) const {
if (!session || !session->mybe || !session->mybe->server_myds || !session->mybe->server_myds->myconn) return NULL;
return session->mybe->server_myds->myconn->variables[idx].value;
}
uint32_t MySQL_Variables::server_get_hash(int idx) const {
uint32_t MySQL_Variables::server_get_hash(MySQL_Session* session, int idx) const {
if (!session || !session->mybe || !session->mybe->server_myds || !session->mybe->server_myds->myconn) return 0;
return session->mybe->server_myds->myconn->var_hash[idx];
}
bool MySQL_Variables::update_variable(session_status status, int &_rc) {
bool MySQL_Variables::update_variable(MySQL_Session* session, session_status status, int &_rc) {
int idx = SQL_NAME_LAST;
for (int i=0; i<SQL_NAME_LAST; i++) {
if (mysql_tracked_variables[i].status == status) {
@ -186,7 +188,7 @@ bool MySQL_Variables::update_variable(session_status status, int &_rc) {
return updaters[idx](session, idx, _rc);
}
bool MySQL_Variables::verify_variable(int idx) const {
bool MySQL_Variables::verify_variable(MySQL_Session* session, int idx) const {
auto ret = false;
if (likely(verifiers[idx])) {
auto client_hash = session->client_myds->myconn->var_hash[idx];
@ -207,11 +209,11 @@ bool validate_charset(MySQL_Session* session, int idx, int &_rc) {
const char* not_supported_collation = NULL;
unsigned int replace_collation_nr = 0;
std::stringstream ss;
int charset = atoi(session->mysql_variables->client_get_value(idx));
int charset = atoi(mysql_variables.client_get_value(session, idx));
if (charset >= 255 && myconn->mysql->server_version[0] != '8') {
switch(mysql_thread___handle_unknown_charset) {
case HANDLE_UNKNOWN_CHARSET__DISCONNECT_CLIENT:
snprintf(msg,sizeof(msg),"Can't initialize character set %s", session->mysql_variables->client_get_value(idx));
snprintf(msg,sizeof(msg),"Can't initialize character set %s", mysql_variables.client_get_value(session, idx));
proxy_error("Can't initialize character set on %s, %d: Error %d (%s). Closing client connection %s:%d.\n",
myconn->parent->address, myconn->parent->port, 2019, msg, session->client_myds->addr.addr, session->client_myds->addr.port);
myds->destroy_MySQL_Connection_From_Pool(false);
@ -221,7 +223,7 @@ bool validate_charset(MySQL_Session* session, int idx, int &_rc) {
case HANDLE_UNKNOWN_CHARSET__REPLACE_WITH_DEFAULT_VERBOSE:
ci = proxysql_find_charset_nr(charset);
if (!ci) {
proxy_error("Cannot find character set [%s]\n", session->mysql_variables->client_get_value(idx));
proxy_error("Cannot find character set [%s]\n", mysql_variables.client_get_value(session, idx));
assert(0);
}
not_supported_collation = ci->name;
@ -240,11 +242,11 @@ bool validate_charset(MySQL_Session* session, int idx, int &_rc) {
replace_collation_nr = ci->nr;
proxy_warning("Server doesn't support collation (%s) %s. Replacing it with the configured default (%d) %s. Client %s:%d\n",
session->mysql_variables->client_get_value(idx), not_supported_collation,
mysql_variables.client_get_value(session, idx), not_supported_collation,
replace_collation_nr, replace_collation, session->client_myds->addr.addr, session->client_myds->addr.port);
ss << replace_collation_nr;
session->mysql_variables->client_set_value(idx, ss.str());
mysql_variables.client_set_value(session, idx, ss.str());
_rc=0;
return true;
case HANDLE_UNKNOWN_CHARSET__REPLACE_WITH_DEFAULT:
@ -261,7 +263,7 @@ bool validate_charset(MySQL_Session* session, int idx, int &_rc) {
replace_collation_nr = ci->nr;
ss << replace_collation_nr;
session->mysql_variables->client_set_value(idx, ss.str());
mysql_variables.client_set_value(session, idx, ss.str());
_rc=0;
return true;
default:
@ -294,55 +296,55 @@ bool update_server_variable(MySQL_Session* session, int idx, int &_rc) {
*/
if (idx==SQL_CHARACTER_SET_RESULTS) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_nr(atoi(session->mysql_variables->client_get_value(SQL_CHARACTER_SET_RESULTS)));
ci = proxysql_find_charset_nr(atoi(mysql_variables.client_get_value(session, SQL_CHARACTER_SET_RESULTS)));
if (!ci) {
if (!strcmp(session->mysql_variables->client_get_value(SQL_CHARACTER_SET_RESULTS), "NULL")) {
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
if (!strcmp(mysql_variables.client_get_value(session, SQL_CHARACTER_SET_RESULTS), "NULL")) {
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, "NULL", no_quote, st);
} else if (!strcmp(session->mysql_variables->client_get_value(SQL_CHARACTER_SET_RESULTS), "binary")) {
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
} else if (!strcmp(mysql_variables.client_get_value(session, SQL_CHARACTER_SET_RESULTS), "binary")) {
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, "binary", no_quote, st);
}
} else {
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, ci->csname, no_quote, st);
}
} else if (idx==SQL_COLLATION_CONNECTION) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_nr(atoi(session->mysql_variables->client_get_value(SQL_COLLATION_CONNECTION)));
ci = proxysql_find_charset_nr(atoi(mysql_variables.client_get_value(session, SQL_COLLATION_CONNECTION)));
std::stringstream ss;
ss << ci->nr;
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, ci->name, no_quote, st);
} else if (idx==SQL_CHARACTER_SET_CONNECTION) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_nr(atoi(session->mysql_variables->client_get_value(SQL_CHARACTER_SET_CONNECTION)));
ci = proxysql_find_charset_nr(atoi(mysql_variables.client_get_value(session, SQL_CHARACTER_SET_CONNECTION)));
unsigned int nr = ci->nr;
std::stringstream ss;
ss << nr;
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, ci->csname, no_quote, st);
} else if (idx==SQL_CHARACTER_SET_CLIENT || idx==SQL_CHARACTER_SET_DATABASE) {
const MARIADB_CHARSET_INFO *ci = NULL;
ci = proxysql_find_charset_nr(atoi(session->mysql_variables->client_get_value(idx)));
ci = proxysql_find_charset_nr(atoi(mysql_variables.client_get_value(session, idx)));
std::stringstream ss;
ss << ci->nr;
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, ci->csname, no_quote, st);
} else {
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, session->mysql_variables->server_get_value(idx), no_quote, st);
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, mysql_variables.server_get_value(session, idx), no_quote, st);
}
return ret;
}
inline bool verify_variable(MySQL_Session* session, int idx, uint32_t client_hash, uint32_t server_hash) {
inline bool verify_server_variable(MySQL_Session* session, int idx, uint32_t client_hash, uint32_t server_hash) {
if (client_hash != server_hash) {
switch(session->status) { // this switch can be replaced with a simple previous_status.push(status), but it is here for readibility
case PROCESSING_QUERY:
@ -360,7 +362,7 @@ inline bool verify_variable(MySQL_Session* session, int idx, uint32_t client_has
break;
}
session->set_status(mysql_tracked_variables[idx].status);
session->mysql_variables->server_set_value(idx, session->mysql_variables->client_get_value(idx));
mysql_variables.server_set_value(session, idx, mysql_variables.client_get_value(session, idx));
return true;
}
return false;

@ -406,14 +406,14 @@ unsigned int MySQL_Connection::set_charset(unsigned int _c, enum charset_action
// SQL_CHARACTER_SET should be set befor setting SQL_CHRACTER_ACTION
std::stringstream ss;
ss << _c;
myds->sess->mysql_variables->client_set_value(SQL_CHARACTER_SET, ss.str());
mysql_variables.client_set_value(myds->sess, SQL_CHARACTER_SET, ss.str());
// When SQL_CHARACTER_ACTION is set character set variables are set according to
// SQL_CHRACTER_SET value
ss.str(std::string());
ss.clear();
ss << action;
myds->sess->mysql_variables->client_set_value(SQL_CHARACTER_ACTION, ss.str());
mysql_variables.client_set_value(myds->sess, SQL_CHARACTER_ACTION, ss.str());
return _c;
}
@ -590,7 +590,7 @@ void MySQL_Connection::connect_start() {
mysql_options(mysql, MYSQL_OPT_CONNECT_TIMEOUT, (void *)&timeout);
/* Take client character set and use it to connect to backend */
if (myds && myds->sess) {
csname = myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_SET);
csname = mysql_variables.client_get_value(myds->sess, SQL_CHARACTER_SET);
}
const MARIADB_CHARSET_INFO * c = NULL;
@ -731,12 +731,12 @@ void MySQL_Connection::set_autocommit_cont(short event) {
void MySQL_Connection::set_names_start() {
PROXY_TRACE();
const MARIADB_CHARSET_INFO * c = proxysql_find_charset_nr(atoi(myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_SET)));
const MARIADB_CHARSET_INFO * c = proxysql_find_charset_nr(atoi(mysql_variables.client_get_value(myds->sess, SQL_CHARACTER_SET)));
if (!c) {
proxy_error("Not existing charset number %u\n", atoi(myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_SET)));
proxy_error("Not existing charset number %u\n", atoi(mysql_variables.client_get_value(myds->sess, SQL_CHARACTER_SET)));
assert(0);
}
async_exit_status = mysql_set_character_set_start(&interr,mysql, NULL, atoi(myds->sess->mysql_variables->client_get_value(SQL_CHARACTER_SET)));
async_exit_status = mysql_set_character_set_start(&interr,mysql, NULL, atoi(mysql_variables.client_get_value(myds->sess, SQL_CHARACTER_SET)));
}
void MySQL_Connection::set_names_cont(short event) {

@ -718,6 +718,7 @@ MySQL_Monitor *GloMyMon;
std::thread *MyMon_thread = NULL;
MySQL_Logger *GloMyLogger;
MySQL_Variables mysql_variables;
SQLite3_Server *GloSQLite3Server;
#ifdef PROXYSQLCLICKHOUSE

Loading…
Cancel
Save