mirror of https://github.com/sysown/proxysql
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
162 lines
4.6 KiB
162 lines
4.6 KiB
#include "MySQL_Variables.h"
|
|
#include "proxysql.h"
|
|
|
|
#include "MySQL_Session.h"
|
|
#include "MySQL_Data_Stream.h"
|
|
#include "SpookyV2.h"
|
|
|
|
MySQL_Variables::MySQL_Variables(MySQL_Session* _session) {
|
|
assert(_session);
|
|
session = _session;
|
|
|
|
for (auto i = 0; i < SQL_NAME_LAST; i++) {
|
|
switch(i) {
|
|
case SQL_SAFE_UPDATES:
|
|
case SQL_SELECT_LIMIT:
|
|
case SQL_SQL_MODE:
|
|
case SQL_TIME_ZONE:
|
|
case SQL_CHARACTER_SET_RESULTS:
|
|
case SQL_ISOLATION_LEVEL:
|
|
case SQL_TRANSACTION_READ:
|
|
case SQL_SESSION_TRACK_GTIDS:
|
|
case SQL_SQL_AUTO_IS_NULL:
|
|
updaters[i] = new Generic_Updater();
|
|
break;
|
|
default:
|
|
proxy_error("Wrong variable index\n");
|
|
assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
MySQL_Variables::~MySQL_Variables() {
|
|
for (auto u : updaters)
|
|
delete u;
|
|
}
|
|
|
|
void MySQL_Variables::client_set_value(int idx, const char* value) {
|
|
session->client_myds->myconn->variables[idx].hash = SpookyHash::Hash32(value,strlen(value),10);
|
|
|
|
if (session->client_myds->myconn->variables[idx].value) {
|
|
free(session->client_myds->myconn->variables[idx].value);
|
|
}
|
|
session->client_myds->myconn->variables[idx].value = strdup(value);
|
|
}
|
|
|
|
const char* MySQL_Variables::client_get_value(int idx) {
|
|
return session->client_myds->myconn->variables[idx].value;
|
|
}
|
|
|
|
uint32_t MySQL_Variables::client_get_hash(int idx) {
|
|
return session->client_myds->myconn->variables[idx].hash;
|
|
}
|
|
|
|
void MySQL_Variables::server_set_value(int idx, const char* value) {
|
|
session->mybe->server_myds->myconn->variables[idx].hash = SpookyHash::Hash32(value,strlen(value),10);
|
|
|
|
if (session->mybe->server_myds->myconn->variables[idx].value) {
|
|
free(session->mybe->server_myds->myconn->variables[idx].value);
|
|
}
|
|
session->mybe->server_myds->myconn->variables[idx].value = strdup(value);
|
|
}
|
|
|
|
const char* MySQL_Variables::server_get_value(int idx) {
|
|
return session->mybe->server_myds->myconn->variables[idx].value;
|
|
}
|
|
|
|
uint32_t MySQL_Variables::server_get_hash(int idx) {
|
|
return session->mybe->server_myds->myconn->variables[idx].hash;
|
|
}
|
|
|
|
bool MySQL_Variables::verify_generic_variable(uint32_t *be_int, char **be_var, char *def, uint32_t *fe_int, char *fe_var, enum session_status next_sess_status) {
|
|
// be_int = backend int (hash)
|
|
// be_var = backend value
|
|
// def = default
|
|
// fe_int = frontend int (has)
|
|
// fe_var = frontend value
|
|
if (*be_int == 0) {
|
|
// it is the first time we use this backend. Set value to default
|
|
if (*be_var) {
|
|
free(*be_var);
|
|
*be_var = NULL;
|
|
}
|
|
*be_var = strdup(def);
|
|
uint32_t tmp_int = SpookyHash::Hash32(*be_var, strlen(*be_var), 10);
|
|
*be_int = tmp_int;
|
|
}
|
|
if (*fe_int) {
|
|
if (*fe_int != *be_int) {
|
|
{
|
|
*be_int = *fe_int;
|
|
if (*be_var) {
|
|
free(*be_var);
|
|
*be_var = NULL;
|
|
}
|
|
if (fe_var) {
|
|
*be_var = strdup(fe_var);
|
|
}
|
|
}
|
|
switch(session->status) { // this switch can be replaced with a simple previous_status.push(status), but it is here for readibility
|
|
case PROCESSING_QUERY:
|
|
session->previous_status.push(PROCESSING_QUERY);
|
|
break;
|
|
case PROCESSING_STMT_PREPARE:
|
|
session->previous_status.push(PROCESSING_STMT_PREPARE);
|
|
break;
|
|
case PROCESSING_STMT_EXECUTE:
|
|
session->previous_status.push(PROCESSING_STMT_EXECUTE);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
break;
|
|
}
|
|
session->set_status(next_sess_status);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool MySQL_Variables::update_variable(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) {
|
|
idx = i;
|
|
break;
|
|
}
|
|
}
|
|
assert(idx != SQL_NAME_LAST);
|
|
updaters[idx]->update_server_variable(session, idx, _rc);
|
|
}
|
|
|
|
bool MySQL_Variables::verify_variable(int idx) {
|
|
int rc = 0;
|
|
auto ret = updaters[idx]->verify_variables(session, idx);
|
|
if (ret) {
|
|
// FIXME
|
|
//update_variable(rc);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
bool Generic_Updater::verify_variables(MySQL_Session* session, int idx) {
|
|
auto ret = session->mysql_variables->verify_generic_variable(
|
|
&session->mybe->server_myds->myconn->variables[idx].hash,
|
|
&session->mybe->server_myds->myconn->variables[idx].value,
|
|
mysql_thread___default_variables[idx],
|
|
&session->client_myds->myconn->variables[idx].hash,
|
|
session->client_myds->myconn->variables[idx].value,
|
|
mysql_tracked_variables[idx].status
|
|
);
|
|
return ret;
|
|
}
|
|
|
|
bool Generic_Updater::update_server_variable(MySQL_Session* session, int idx, int &_rc) {
|
|
bool no_quote = true;
|
|
if (mysql_tracked_variables[idx].quote) no_quote = false;
|
|
bool st = mysql_tracked_variables[idx].set_transaction;
|
|
const char * set_var_name = mysql_tracked_variables[idx].set_variable_name;
|
|
auto ret = session->handler_again___status_SETTING_GENERIC_VARIABLE(&_rc, set_var_name, session->mysql_variables->server_get_value(idx), no_quote, st);
|
|
return ret;
|
|
}
|