Added transaction_isolation_level and transaction_read_only variable support.

pull/4280/head
Rahim Kanji 3 years ago
parent e2c45a9901
commit a908f2a17b

@ -2546,10 +2546,16 @@ bool MySQL_Session::handler_again___status_SETTING_GENERIC_VARIABLE(int *_rc, co
char *sv = mybe->server_myds->myconn->mysql->server_version;
if (strncmp(sv,(char *)"8",1)==0) {
sprintf(query,q,"transaction_isolation", var_value);
}
else {
} else {
sprintf(query,q,"tx_isolation", var_value);
}
} else if (strncasecmp("tx_read_only", var_name, 12) == 0) {
char* sv = mybe->server_myds->myconn->mysql->server_version;
if (strncmp(sv, (char *)"8", 1) == 0) {
sprintf(query,q,"transaction_read_only", var_value);
} else {
sprintf(query,q,"tx_read_only", var_value);
}
} else if (strncasecmp("aurora_read_replica_read_committed", var_name, 34) == 0) {
// If aurora_read_replica_read_committed is set, isolation level is
// internally reset so that it will be set again.
@ -2583,10 +2589,10 @@ bool MySQL_Session::handler_again___status_SETTING_GENERIC_VARIABLE(int *_rc, co
st=previous_status.top();
previous_status.pop();
if (strncasecmp("transaction isolation level", var_name, sizeof("transaction isolation level")-1) == 0) {
if (strcasecmp("transaction isolation level", var_name) == 0) {
mysql_variables.server_reset_value(this, SQL_NEXT_ISOLATION_LEVEL);
mysql_variables.client_reset_value(this, SQL_NEXT_ISOLATION_LEVEL);
} else if (strncasecmp("transaction read", var_name, sizeof("transaction read")-1) == 0) {
} else if (strcasecmp("transaction read", var_name) == 0) {
mysql_variables.server_reset_value(this, SQL_NEXT_TRANSACTION_READ);
mysql_variables.client_reset_value(this, SQL_NEXT_TRANSACTION_READ);
}
@ -6443,6 +6449,33 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TX ISOLATION to %s\n", value1.c_str());
}
} else if (var == "tx_read_only") {
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET tx_read_only value %s\n", value1.c_str());
if (
(value1 == "0") ||
(strcasecmp(value1.c_str(), "false")==0) ||
(strcasecmp(value1.c_str(), "off")==0)
) {
value1 = "WRITE";
} else if (
(value1 == "1") ||
(strcasecmp(value1.c_str(), "true")==0) ||
(strcasecmp(value1.c_str(), "on")==0)
) {
value1 = "ONLY";
} else {
//proxy_warning("Unknown tx_read_only value \"%s\"\n", value1.c_str());
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
uint32_t read_only_int=SpookyHash::Hash32(value1.c_str(),value1.length(),10);
if (mysql_variables.client_get_hash(this, SQL_TRANSACTION_READ) != read_only_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 TX ACCESS MODE to READ %s\n", value1.c_str());
}
} else if (std::find(mysql_variables.ignore_vars.begin(), mysql_variables.ignore_vars.end(), var) != mysql_variables.ignore_vars.end()) {
// this is a variable we parse but ignore
// see MySQL_Variables::MySQL_Variables() for a list of ignored variables
@ -6574,7 +6607,7 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
enum mysql_variable_name isolation_level_val;
enum mysql_variable_name transaction_read_val;
if (val[0] == "SESSION") {
if (val[0] == "session") {
isolation_level_val = SQL_ISOLATION_LEVEL;
transaction_read_val = SQL_TRANSACTION_READ;
} else {

@ -2975,7 +2975,7 @@ bool MySQL_Thread::init() {
match_regexes[0] = NULL; // NOTE: historically we used match_regexes[0] for SET SQL_LOG_BIN . Not anymore
std::stringstream ss;
ss << "^SET (|SESSION |@@|@@session.|@@local.)`?(" << mysql_variables.variables_regexp << "SESSION_TRACK_GTIDS|TX_ISOLATION)`?( *)(:|)=( *)";
ss << "^SET (|SESSION |@@|@@session.|@@local.)`?(" << mysql_variables.variables_regexp << "SESSION_TRACK_GTIDS|TX_ISOLATION|TX_READ_ONLY|TRANSACTION_ISOLATION|TRANSACTION_READ_ONLY)`?( *)(:|)=( *)";
match_regexes[1]=new Session_Regex((char *)ss.str().c_str());
match_regexes[2]=new Session_Regex((char *)"^SET(?: +)(|SESSION +)TRANSACTION(?: +)(?:(?:(ISOLATION(?: +)LEVEL)(?: +)(REPEATABLE(?: +)READ|READ(?: +)COMMITTED|READ(?: +)UNCOMMITTED|SERIALIZABLE))|(?:(READ)(?: +)(WRITE|ONLY)))");

@ -104,7 +104,12 @@ VALGRIND_ENABLE_ERROR_REPORTING;
}
} else if (value4 != "") {
// VARIABLE
value5.erase(value5.find_last_not_of(" \n\r\t,")+1);
if (strcasecmp("transaction_isolation", value4.c_str()) == 0) {
value4 = "tx_isolation";
} else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) {
value4 = "tx_read_only";
}
value5.erase(value5.find_last_not_of(" \n\r\t,")+1);
key = value4;
if (value5 == "''" || value5 == "\"\"") {
op.push_back("");
@ -356,6 +361,11 @@ VALGRIND_ENABLE_ERROR_REPORTING;
}
} else if (value4 != "") {
// VARIABLE
if (strcasecmp("transaction_isolation", value4.c_str()) == 0) {
value4 = "tx_isolation";
} else if (strcasecmp("transaction_read_only", value4.c_str()) == 0) {
value4 = "tx_read_only";
}
value5.erase(value5.find_last_not_of(" \n\r\t,")+1);
key = value4;
if (value5 == "''" || value5 == "\"\"") {
@ -415,21 +425,19 @@ std::map<std::string,std::vector<std::string>> SetParser::parse2() {
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 4, "SET parsing: v1='%s' , v2='%s' , v3='%s' , v4='%s' , v5='%s'\n", value1.c_str(), value2.c_str(), value3.c_str(), value4.c_str(), value5.c_str());
#endif // DEBUG
std::string key;
bool is_session = (value1 != "");
//if (value1 != "") { // session is specified
if (value2 != "") { // isolation level
key = value2;
key = value1 + ":" + value2;
std::transform(value3.begin(), value3.end(), value3.begin(), ::toupper);
op.push_back(value3);
} else {
key = value4;
key = value1 + ":" + value4;
std::transform(value5.begin(), value5.end(), value5.begin(), ::toupper);
op.push_back(value5);
}
//}
std::transform(key.begin(), key.end(), key.begin(), ::tolower);
result[std::string((is_session == true) ? "SESSION:" : ":") + key] = op;
result[key] = op;
}
delete opt2;

Loading…
Cancel
Save