Added DEALLOCATE <stmt_name> and DEALLOCATE ALL support

pull/5044/head
Rahim Kanji 10 months ago
parent 099597d2d8
commit 070d4ca18d

@ -271,7 +271,6 @@ private:
* @return 'true' if the packet is intercepted and never forwarded to the client, 'false' otherwise.
*/
bool handler_CommitRollback(PtrSize_t*);
//bool handler_SetAutocommit(PtrSize_t*);
/**
* @brief Should execute most of the commands executed when a request is finalized.
* @details Cleanup of current session state, and required operations to the supplied 'PgSQL_Data_Stream'

@ -763,7 +763,9 @@ EXECUTION_STATE PgSQL_Protocol::process_handshake_response_packet(unsigned char*
return EXECUTION_STATE::FAILED;
}
assert(hdr.data.size > 0);
if (hdr.data.size == 0) {
return EXECUTION_STATE::FAILED;
}
if (hdr.type != (*myds)->auth_next_pkt_type) {
return EXECUTION_STATE::FAILED;
@ -1431,13 +1433,18 @@ failed:
char* extract_tag_from_query(const char* query) {
constexpr size_t crete_table_len = sizeof("CREATE TABLE AS") - 1;
constexpr size_t create_table_len = sizeof("CREATE TABLE AS") - 1;
constexpr size_t deallocate_all_len = sizeof("DEALLOCATE ALL") - 1;
constexpr size_t deallocate_prepare_all_len = sizeof("DEALLOCATE PREPARE ALL") - 1;
size_t qtlen = strlen(query);
if ((qtlen > crete_table_len) && strncasecmp(query, "CREATE TABLE AS", crete_table_len) == 0) {
if ((qtlen > create_table_len) && strncasecmp(query, "CREATE TABLE AS", create_table_len) == 0) {
return strdup("SELECT");
}
else {
} else if ((qtlen >= deallocate_all_len) &&
(strncasecmp(query, "DEALLOCATE ALL", deallocate_all_len) == 0 ||
strncasecmp(query, "DEALLOCATE PREPARE ALL", deallocate_prepare_all_len) == 0)) {
return strdup("DEALLOCATE ALL");
} else {
const char* fs = strchr(query, ' ');
if (fs != NULL) {
@ -1593,7 +1600,7 @@ bool PgSQL_Protocol::generate_describe_completion_packet(bool send, bool ready,
return true;
}
//generate close statment completion packet
//generate close statement completion packet
bool PgSQL_Protocol::generate_close_completion_packet(bool send, bool ready, char trx_state, PtrSize_t* _ptr) {
// to avoid memory leak
assert(send == true || _ptr);

@ -893,35 +893,25 @@ void PgSQL_Session::generate_proxysql_internal_session_json(json& j) {
}
bool PgSQL_Session::handler_special_queries(PtrSize_t* pkt, bool* lock_hostgroup) {
// Unsupported Features:
// COPY
/*if (pkt->size > (5 + 5) && strncasecmp((char*)"COPY ", (char*)pkt->ptr + 5, 5) == 0) {
client_myds->DSS = STATE_QUERY_SENT_NET;
client_myds->myprot.generate_error_packet(true, true, "Feature not supported", PGSQL_ERROR_CODES::ERRCODE_FEATURE_NOT_SUPPORTED,
false, true);
//client_myds->DSS = STATE_SLEEP;
//status = WAITING_CLIENT_DATA;
if (mirror == false) {
RequestEnd(NULL);
} else {
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
}
l_free(pkt->size, pkt->ptr);
return true;
}*/
//
if (pkt->size > (5 + 18) && strncasecmp((char*)"PROXYSQL INTERNAL ", (char*)pkt->ptr + 5, 18) == 0) {
return_proxysql_internal(pkt);
return true;
}
if (locked_on_hostgroup == -1) {
//if (handler_SetAutocommit(pkt) == true) {
// return true;
//}
if (handler_CommitRollback(pkt) == true) {
return true;
}
} else {
if (strncasecmp((char*)"SET ", (char*)pkt->ptr + 5, 4) == 0 ||
strncasecmp((char*)"RESET ", (char*)pkt->ptr + 5, 6) == 0) {
// this is a circuit breaker, we will send everything to the backend
//
// also note that in the current implementation we stop tracking variables:
// this becomes a problem if pgsql-set_query_lock_on_hostgroup is
// disabled while a session is already locked
return false;
}
}
/*
//handle 2564
@ -982,82 +972,6 @@ bool PgSQL_Session::handler_special_queries(PtrSize_t* pkt, bool* lock_hostgroup
return true;
}*/
if (locked_on_hostgroup >= 0 &&
(strncasecmp((char*)"SET ", (char*)pkt->ptr + 5, 4) == 0 ||
strncasecmp((char*)"RESET ", (char*)pkt->ptr + 5, 6) == 0)) {
// this is a circuit breaker, we will send everything to the backend
//
// also note that in the current implementation we stop tracking variables:
// this becomes a problem if pgsql-set_query_lock_on_hostgroup is
// disabled while a session is already locked
return false;
}
/*
if (pkt->size > (5 + 6) && strncasecmp((char*)"RESET ", (char*)pkt->ptr + 5, 6) == 0) {
if (locked_on_hostgroup >= 0)
return false;
std::vector<char> param_name;
const char* ptr = (char*)pkt->ptr;
for (size_t idx = (5 + 6); idx < pkt->size; idx++) {
if (ptr[idx] == '\0' || ptr[idx] == ';')
break;
if (ptr[idx] == ' ')
continue;
param_name.push_back(ptr[idx]);
}
param_name.push_back('\0');
int idx = PGSQL_NAME_LAST_HIGH_WM;
for (int i = 0; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
if (idx == PGSQL_NAME_LAST_LOW_WM) continue;
if (variable_name_exists(pgsql_tracked_variables[i], param_name.data()) == true) {
idx = i;
break;
}
}
std::vector<std::pair<std::string, std::string>> param_status = {};
if (idx != PGSQL_NAME_LAST_HIGH_WM) {
const char* name = pgsql_tracked_variables[idx].set_variable_name;
const char* value = (idx < PGSQL_NAME_LAST_LOW_WM) ? pgsql_thread___default_variables[idx] : pgsql_tracked_variables[idx].default_value;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection %s to %s\n", name, value);
uint32_t var_hash_int = SpookyHash::Hash32(value, strlen(value), 10);
if (pgsql_variables.client_get_hash(this, pgsql_tracked_variables[idx].idx) != var_hash_int) {
if (!pgsql_variables.client_set_value(this, pgsql_tracked_variables[idx].idx, value)) {
return false;
}
if (IS_PGTRACKED_VAR_OPTION_SET_PARAM_STATUS(pgsql_tracked_variables[idx])) {
param_status.push_back(std::make_pair(name, value));
}
}
} else {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
client_myds->DSS = STATE_QUERY_SENT_NET;
unsigned int nTrx = NumActiveTransactions();
const char trx_state = (nTrx ? 'T' : 'I');
client_myds->myprot.generate_ok_packet(true, true, NULL, 0, (const char*)pkt->ptr + 5, trx_state, NULL, param_status);
if (mirror == false) {
RequestEnd(NULL);
} else {
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
}
l_free(pkt->size, pkt->ptr);
return true;
}
*/
// 'LOAD DATA LOCAL INFILE' is unsupported. We report an specific error to inform clients about this fact. For more context see #833.
if ((pkt->size >= 22 + 5) && (strncasecmp((char*)"LOAD DATA LOCAL INFILE", (char*)pkt->ptr + 5, 22) == 0)) {
@ -4013,8 +3927,8 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
// handle here #509, #815 and #816
if (CurrentQuery.QueryParserArgs.digest_text) {
char* dig = CurrentQuery.QueryParserArgs.digest_text;
//unsigned int nTrx = NumActiveTransactions();
if ((locked_on_hostgroup == -1) && (strncasecmp(dig, (char*)"SET ", 4) == 0)) {
if ((locked_on_hostgroup == -1) && (strncasecmp(dig, "SET ", 4) == 0)) {
// this code is executed only if locked_on_hostgroup is not set yet
// if locked_on_hostgroup is set, we do not try to parse the SET statement
#ifdef DEBUG
@ -4039,8 +3953,8 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
}
string nq = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
RE2::GlobalReplace(&nq, (char*)"^/\\*!\\d\\d\\d\\d\\d SET(.*)\\*/", (char*)"SET\\1");
RE2::GlobalReplace(&nq, (char*)"(?U)/\\*.*\\*/", (char*)"");
RE2::GlobalReplace(&nq, "^/\\*!\\d\\d\\d\\d\\d SET(.*)\\*/", "SET\\1");
RE2::GlobalReplace(&nq, "(?U)/\\*.*\\*/", "");
// remove trailing space and semicolon if present. See issue#4380
nq.erase(nq.find_last_not_of(" ;") + 1);
if (
@ -4098,7 +4012,7 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
}
if (idx != PGSQL_NAME_LAST_HIGH_WM) {
uint32_t current_hash = pgsql_variables.client_get_hash(this, idx);
if ((value1.size() == sizeof("DEFAULT") - 1) && strncasecmp(value1.c_str(), (char*)"DEFAULT",sizeof("DEFAULT")-1) == 0) {
if ((value1.size() == sizeof("DEFAULT") - 1) && strncasecmp(value1.c_str(), "DEFAULT",sizeof("DEFAULT")-1) == 0) {
auto [value, hash] = client_myds->myconn->get_startup_parameter_and_hash((enum pgsql_variable_name)idx);
if (hash == 0) {
if (current_hash != 0) {
@ -4174,166 +4088,7 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
}
}
}
} /*else if (var == "time_zone") {
std::string value1 = *values;
std::size_t found_at = value1.find("@");
if (found_at != std::string::npos) {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET Time Zone value %s\n", value1.c_str());
{
// reformat +1:23 to +01:23
if (value1.length() == 5) {
if (value1[0] == '+' || value1[0] == '-') {
if (value1[2] == ':') {
std::string s = std::string(value1, 0, 1);
s += "0";
s += std::string(value1, 1, 4);
value1 = s;
}
}
}
}
uint32_t time_zone_int = SpookyHash::Hash32(value1.c_str(), value1.length(), 10);
if (pgsql_variables.client_get_hash(this, SQL_TIME_ZONE) != time_zone_int) {
if (!pgsql_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());
}
} else if ((var == "client_encoding") || (var == "names")) {
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 7, "Processing SET %s value %s\n", var.c_str(), value1.c_str());
int idx = PGSQL_NAME_LAST_HIGH_WM;
for (int i = 0; i < PGSQL_NAME_LAST_HIGH_WM; i++) {
if (variable_name_exists(pgsql_tracked_variables[i], var.c_str()) == true) {
idx = pgsql_tracked_variables[i].idx;
break;
}
}
if (idx == PGSQL_NAME_LAST_HIGH_WM) {
proxy_error("Variable %s not found in pgsql_tracked_variables[]\n", var.c_str());
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
uint32_t var_value_int = SpookyHash::Hash32(value1.c_str(), value1.length(), 10);
if (pgsql_variables.client_get_hash(this, idx) != var_value_int) {
int charset_encoding = PgSQL_Connection::char_to_encoding(value1.c_str());
if (charset_encoding == -1) {
char* m = NULL;
char* errmsg = NULL;
proxy_error("Cannot find charset [%s]\n", value1.c_str());
m = (char*)"Unknown character set: '%s'";
errmsg = (char*)malloc(value1.length() + strlen(m));
sprintf(errmsg, m, value1.c_str());
client_myds->DSS = STATE_QUERY_SENT_NET;
client_myds->myprot.generate_error_packet(true, true, errmsg,
PGSQL_ERROR_CODES::ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, false, true);
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
free(errmsg);
return true;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Changing connection %s to %s\n", var.c_str(), value1.c_str());
if (!pgsql_variables.client_set_value(this, idx, value1.c_str()))
return false;
//client_myds->myconn->set_charset(value1.c_str());
}
}
else if (var == "names") {
std::string value1 = *values++;
std::size_t found_at = value1.find("@");
if (found_at != std::string::npos) {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET NAMES %s\n", value1.c_str());
const MARIADB_CHARSET_INFO* c;
std::string value2;
if (values != std::end(it->second)) {
value2 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET NAMES With COLLATE %s\n", value2.c_str());
c = proxysql_find_charset_collate_names(value1.c_str(), value2.c_str());
}
else {
c = proxysql_find_charset_name(value1.c_str());
}
if (!c) {
char* m = NULL;
char* errmsg = NULL;
if (value2.length()) {
m = (char*)"Unknown character set '%s' or collation '%s'";
errmsg = (char*)malloc(value1.length() + value2.length() + strlen(m));
sprintf(errmsg, m, value1.c_str(), value2.c_str());
}
else {
m = (char*)"Unknown character set: '%s'";
errmsg = (char*)malloc(value1.length() + strlen(m));
sprintf(errmsg, m, value1.c_str());
}
client_myds->DSS = STATE_QUERY_SENT_NET;
client_myds->myprot.generate_error_packet(true, true, errmsg,
PGSQL_ERROR_CODES::ERRCODE_SYNTAX_ERROR_OR_ACCESS_RULE_VIOLATION, false, true);
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
free(errmsg);
return true;
}
else {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection charset to %d\n", c->nr);
//-- client_myds->myconn->set_charset(c->nr, NAMES);
}
}
else if (var == "tx_isolation") {
std::string value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET tx_isolation value %s\n", value1.c_str());
auto pos = value1.find('-');
if (pos != std::string::npos)
value1[pos] = ' ';
uint32_t isolation_level_int = SpookyHash::Hash32(value1.c_str(), value1.length(), 10);
if (pgsql_variables.client_get_hash(this, SQL_ISOLATION_LEVEL) != isolation_level_int) {
if (!pgsql_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());
}
}
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 (pgsql_variables.client_get_hash(this, SQL_TRANSACTION_READ) != read_only_int) {
if (!pgsql_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(pgsql_variables.ignore_vars.begin(), pgsql_variables.ignore_vars.end(), var) != pgsql_variables.ignore_vars.end()) {
} else if (std::find(pgsql_variables.ignore_vars.begin(), pgsql_variables.ignore_vars.end(), var) != pgsql_variables.ignore_vars.end()) {
// this is a variable we parse but ignore
// see MySQL_Variables::MySQL_Variables() for a list of ignored variables
#ifdef DEBUG
@ -4356,11 +4111,6 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
/*
if (exit_after_SetParse) {
goto __exit_set_destination_hostgroup;
}
*/
client_myds->DSS = STATE_QUERY_SENT_NET;
unsigned int nTrx = NumActiveTransactions();
@ -4369,131 +4119,11 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
RequestEnd(NULL);
l_free(pkt->size, pkt->ptr);
return true;
}
/* TODO
else if (match_regexes && match_regexes[2]->match(dig)) {
PgSQL_Set_Stmt_Parser parser(nq);
std::map<std::string, std::vector<std::string>> set = parser.parse2();
for (auto it = std::begin(set); it != std::end(set); ++it) {
const std::vector<std::string>& val = split_string(it->first, ':');
if (val.size() == 2) {
const auto values = std::begin(it->second);
const std::string& var = val[1];
enum mysql_variable_name isolation_level_val;
enum mysql_variable_name transaction_read_val;
if (val[0] == "session") {
isolation_level_val = SQL_ISOLATION_LEVEL;
transaction_read_val = SQL_TRANSACTION_READ;
}
else {
isolation_level_val = SQL_NEXT_ISOLATION_LEVEL;
transaction_read_val = SQL_NEXT_TRANSACTION_READ;
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET variable %s\n", var.c_str());
if (var == "isolation level") {
const std::string& value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET %s TRANSACTION ISOLATION LEVEL value %s\n", val[0].c_str(), value1.c_str());
const uint32_t isolation_level_int = SpookyHash::Hash32(value1.c_str(), value1.length(), 10);
if (pgsql_variables.client_get_hash(this, isolation_level_val) != isolation_level_int) {
if (!pgsql_variables.client_set_value(this, isolation_level_val, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TRANSACTION ISOLATION LEVEL to %s\n", value1.c_str());
}
}
else if (var == "read") {
const std::string& value1 = *values;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET %s TRANSACTION READ value %s\n", val[0].c_str(), value1.c_str());
const uint32_t transaction_read_int = SpookyHash::Hash32(value1.c_str(), value1.length(), 10);
if (pgsql_variables.client_get_hash(this, transaction_read_val) != transaction_read_int) {
if (!pgsql_variables.client_set_value(this, transaction_read_val, value1.c_str()))
return false;
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection TRANSACTION READ to %s\n", value1.c_str());
}
}
else {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
}
else {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
}
client_myds->DSS = STATE_QUERY_SENT_NET;
unsigned int nTrx = NumActiveTransactions();
const char trx_state = (nTrx ? 'T' : 'I');
client_myds->myprot.generate_ok_packet(true, true, NULL, 0, dig, trx_state);
RequestEnd(NULL);
l_free(pkt->size, pkt->ptr);
return true;
} else if (match_regexes && match_regexes[3]->match(dig)) {
std::vector<std::pair<std::string, std::string>> param_status;
PgSQL_Set_Stmt_Parser parser(nq);
std::string charset = parser.parse_character_set();
int charset_encoding = -1;
if (!charset.empty()) {
if ((charset.size() == sizeof("DEFAULT") - 1) && strncasecmp(charset.c_str(), (char*)"DEFAULT", sizeof("DEFAULT") - 1) == 0) {
charset = get_default_session_variable(PGSQL_CLIENT_ENCODING);
assert(charset.empty() == false);
}
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Processing SET CLIENT_ENCODING %s\n", charset.c_str());
charset_encoding = PgSQL_Connection::char_to_encoding(charset.c_str());
} else {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
if (charset_encoding == -1) {
char* m = NULL;
char* errmsg = NULL;
proxy_error("invalid value for parameter \"Client_Encoding\": \"%s\"\n", charset.c_str());
m = (char*)"invalid value for parameter \"Client_Encoding\": \"%s\"";
errmsg = (char*)malloc(charset.length() + strlen(m));
sprintf(errmsg, m, charset.c_str());
client_myds->DSS = STATE_QUERY_SENT_NET;
client_myds->myprot.generate_error_packet(true, true, errmsg,
PGSQL_ERROR_CODES::ERRCODE_INVALID_PARAMETER_VALUE, false, true);
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
free(errmsg);
return true;
} else {
proxy_debug(PROXY_DEBUG_MYSQL_COM, 8, "Changing connection charset to %s\n", charset.c_str());
uint32_t var_hash_int = SpookyHash::Hash32(charset.c_str(), charset.length(), 10);
if (pgsql_variables.client_get_hash(this, pgsql_tracked_variables[PGSQL_CLIENT_ENCODING].idx) != var_hash_int) {
if (!pgsql_variables.client_set_value(this, pgsql_tracked_variables[PGSQL_CLIENT_ENCODING].idx, charset.c_str())) {
return false;
}
if (IS_PGTRACKED_VAR_OPTION_SET_PARAM_STATUS(pgsql_tracked_variables[PGSQL_CLIENT_ENCODING]))
param_status.push_back(std::make_pair(pgsql_tracked_variables[PGSQL_CLIENT_ENCODING].set_variable_name, charset));
}
}
client_myds->DSS = STATE_QUERY_SENT_NET;
unsigned int nTrx = NumActiveTransactions();
const char trx_state = (nTrx ? 'T' : 'I');
client_myds->myprot.generate_ok_packet(true, true, NULL, 0, dig, trx_state, NULL, param_status);
RequestEnd(NULL);
l_free(pkt->size, pkt->ptr);
return true;
}*/ else {
} else {
unable_to_parse_set_statement(lock_hostgroup);
return false;
}
} else if ((locked_on_hostgroup == -1) && (strncasecmp(dig, (char*)"RESET ", 6) == 0)) {
} else if ((locked_on_hostgroup == -1) && (strncasecmp(dig, "RESET ", 6) == 0)) {
#ifdef DEBUG
{
std::string nqn = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
@ -4517,9 +4147,9 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
string nq = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
RE2::GlobalReplace(&nq, (char*)"(?U)/\\*.*\\*/", (char*)"");
RE2::GlobalReplace(&nq, (char*)"(?i)RESET", (char*)"");
RE2::GlobalReplace(&nq, (char*)"[^\\w]*", (char*)"");
RE2::GlobalReplace(&nq, "(?U)/\\*.*\\*/", "");
RE2::GlobalReplace(&nq, "(?i)\\bRESET\\b", "");
RE2::GlobalReplace(&nq, "[^\\w]*", "");
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Parsing RESET command %s\n", nq.c_str());
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing RESET command = %s\n", nq.c_str());
@ -4604,6 +4234,56 @@ bool PgSQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___PGSQL_Q
const char txn_state = (nTrx ? 'T' : 'I');
client_myds->myprot.generate_ok_packet(true, true, NULL, 0, dig, txn_state, NULL, param_status);
if (mirror == false) {
RequestEnd(NULL);
} else {
client_myds->DSS = STATE_SLEEP;
status = WAITING_CLIENT_DATA;
}
l_free(pkt->size, pkt->ptr);
return true;
} else if (strncasecmp(dig, "DEALLOCATE ", 11) == 0) {
#ifdef DEBUG
{
std::string nqn = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing DEALLOCATE command = %s\n", nqn.c_str());
}
#endif
if (index(dig, ';') && (index(dig, ';') != dig + strlen(dig) - 1)) {
string nqn;
if (pgsql_thread___parse_failure_logs_digest)
nqn = string(CurrentQuery.get_digest_text());
else
nqn = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
proxy_warning(
"Unable to parse multi-statements command with DEALLOCATE statement from client"
" %s:%d: setting lock hostgroup. Command: %s\n", client_myds->addr.addr,
client_myds->addr.port, nqn.c_str()
);
*lock_hostgroup = true;
return false;
}
std::string nq = string((char*)CurrentQuery.QueryPointer, CurrentQuery.QueryLength);
RE2::GlobalReplace(&nq, "(?U)/\\*.*\\*/", "");
RE2::GlobalReplace(&nq, "(?i)\\bDEALLOCATE\\b(\\s+PREPARE)?", "");
RE2::GlobalReplace(&nq, "[^\\w]*", "");
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Parsing DEALLOCATE command %s\n", nq.c_str());
proxy_debug(PROXY_DEBUG_MYSQL_QUERY_PROCESSOR, 5, "Parsing DEALLOCATE command = %s\n", nq.c_str());
const char* dealloc_value = nq.c_str();
if (strncasecmp(dealloc_value, "ALL", 3) == 0) {
client_myds->myconn->local_stmts->client_close_all();
} else {
client_myds->myconn->local_stmts->client_close(dealloc_value);
}
client_myds->DSS = STATE_QUERY_SENT_NET;
unsigned int nTrx = NumActiveTransactions();
const char txn_state = (nTrx ? 'T' : 'I');
client_myds->myprot.generate_ok_packet(true, true, NULL, 0, dig, txn_state, NULL, {});
if (mirror == false) {
RequestEnd(NULL);
} else {

Loading…
Cancel
Save