Template for handler_special_queries_STATUS()

v2.x_pg_PrepStmtBase_240714
Rene Cannao 2 years ago
parent 80928395cc
commit 48eff16cdc

@ -113,6 +113,7 @@ class Base_Session {
virtual void SQLite3_to_MySQL(SQLite3_result*, char*, int, MySQL_Protocol*, bool in_transaction = false, bool deprecate_eof_active = false) = 0;
bool has_any_backend();
void reset_all_backends();
bool handler_special_queries_STATUS(PtrSize_t*);
};
#endif // CLASS_BASE_SESSION_H

@ -156,7 +156,7 @@ class MySQL_Session: public Base_Session<MySQL_Session, MySQL_Data_Stream, MySQL
//void return_proxysql_internal(PtrSize_t *);
bool handler_special_queries(PtrSize_t *);
bool handler_special_queries_STATUS(PtrSize_t *);
//bool handler_special_queries_STATUS(PtrSize_t *);
/**
* @brief Handles 'COMMIT|ROLLBACK' commands.
* @details Forwarding the packet is required when there are active transactions. Since we are limited to

@ -149,7 +149,7 @@ private:
//void return_proxysql_internal(PtrSize_t*);
bool handler_special_queries(PtrSize_t*);
bool handler_special_queries_STATUS(PtrSize_t*);
//bool handler_special_queries_STATUS(PtrSize_t*);
/**
* @brief Handles 'COMMIT|ROLLBACK' commands.
* @details Forwarding the packet is required when there are active transactions. Since we are limited to

@ -8,6 +8,11 @@ using json = nlohmann::json;
#include "MySQL_Data_Stream.h"
#include "PgSQL_Data_Stream.h"
#define SELECT_DB_USER "select DATABASE(), USER() limit 1"
#define SELECT_DB_USER_LEN 33
#define SELECT_CHARSET_STATUS "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
#define SELECT_CHARSET_STATUS_LEN 115
using json = nlohmann::json;
// Explicitly instantiate the required template class and member functions
@ -51,6 +56,9 @@ template bool Base_Session<PgSQL_Session, PgSQL_Data_Stream, PgSQL_Backend, PgSQ
template void Base_Session<MySQL_Session, MySQL_Data_Stream, MySQL_Backend, MySQL_Thread>::reset_all_backends();
template void Base_Session<PgSQL_Session, PgSQL_Data_Stream, PgSQL_Backend, PgSQL_Thread>::reset_all_backends();
template bool Base_Session<MySQL_Session, MySQL_Data_Stream, MySQL_Backend, MySQL_Thread>::handler_special_queries_STATUS(_PtrSize_t*);
template bool Base_Session<PgSQL_Session, PgSQL_Data_Stream, PgSQL_Backend, PgSQL_Thread>::handler_special_queries_STATUS(_PtrSize_t*);
template<typename S, typename DS, typename B, typename T>
Base_Session<S,DS,B,T>::Base_Session() {
};
@ -370,3 +378,94 @@ void Base_Session<S,DS,B,T>::reset_all_backends() {
delete mybe;
}
};
/**
* @brief Handles special queries executed by the STATUS command in mysql cli .
* Specifically:
* "select DATABASE(), USER() limit 1"
* "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
* See Github issues 4396 and 4426
*
* @param PtrSize_t The packet from the client
*
* @return True if the queries are handled
*
* @note even if this function uses templates, perhaps is relevant only for MySQL client and not PostgreSQL
*/
template<typename S, typename DS, typename B, typename T>
bool Base_Session<S,DS,B,T>::handler_special_queries_STATUS(PtrSize_t* pkt) {
if (pkt->size == (SELECT_DB_USER_LEN + 5)) {
if (strncasecmp(SELECT_DB_USER, (char*)pkt->ptr + 5, SELECT_DB_USER_LEN) == 0) {
SQLite3_result* resultset = new SQLite3_result(2);
resultset->add_column_definition(SQLITE_TEXT, "DATABASE()");
resultset->add_column_definition(SQLITE_TEXT, "USER()");
char* pta[2];
pta[0] = client_myds->myconn->userinfo->username;
pta[1] = client_myds->myconn->userinfo->schemaname;
resultset->add_row(pta);
bool deprecate_eof_active = client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF;
SQLite3_to_MySQL(resultset, NULL, 0, &client_myds->myprot, false, deprecate_eof_active);
delete resultset;
l_free(pkt->size, pkt->ptr);
return true;
}
}
if (pkt->size == (SELECT_CHARSET_STATUS_LEN + 5)) {
if (strncasecmp(SELECT_CHARSET_STATUS, (char*)pkt->ptr + 5, SELECT_CHARSET_STATUS_LEN) == 0) {
SQLite3_result* resultset = new SQLite3_result(4);
resultset->add_column_definition(SQLITE_TEXT, "@@character_set_client");
resultset->add_column_definition(SQLITE_TEXT, "@@character_set_connection");
resultset->add_column_definition(SQLITE_TEXT, "@@character_set_server");
resultset->add_column_definition(SQLITE_TEXT, "@@character_set_database");
// here we do a bit back and forth to and from JSON to reuse existing code instead of writing new code.
// This is not great for performance, but this query is rarely executed.
string vals[4];
json j = {};
json& jc = j["conn"];
if constexpr (std::is_same_v<S, MySQL_Session>) {
MySQL_Connection * conn = client_myds->myconn;
conn->variables[SQL_CHARACTER_SET_CLIENT].fill_client_internal_session(jc, SQL_CHARACTER_SET_CLIENT);
conn->variables[SQL_CHARACTER_SET_CONNECTION].fill_client_internal_session(jc, SQL_CHARACTER_SET_CONNECTION);
conn->variables[SQL_CHARACTER_SET_DATABASE].fill_client_internal_session(jc, SQL_CHARACTER_SET_DATABASE);
} else if constexpr (std::is_same_v<S, PgSQL_Session>) {
PgSQL_Connection * conn = client_myds->myconn;
conn->variables[SQL_CHARACTER_SET_CLIENT].fill_client_internal_session(jc, SQL_CHARACTER_SET_CLIENT);
conn->variables[SQL_CHARACTER_SET_CONNECTION].fill_client_internal_session(jc, SQL_CHARACTER_SET_CONNECTION);
conn->variables[SQL_CHARACTER_SET_DATABASE].fill_client_internal_session(jc, SQL_CHARACTER_SET_DATABASE);
} else {
assert(0);
}
// @@character_set_client
vals[0] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_CLIENT].internal_variable_name];
// @@character_set_connection
vals[1] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_CONNECTION].internal_variable_name];
// @@character_set_server
if constexpr (std::is_same_v<S, MySQL_Session>) {
vals[2] = string(mysql_thread___default_variables[SQL_CHARACTER_SET]);
} else if constexpr (std::is_same_v<S, PgSQL_Session>) {
vals[2] = string(mysql_thread___default_variables[SQL_CHARACTER_SET]);
} else {
assert(0);
}
// @@character_set_database
vals[3] = jc[mysql_tracked_variables[SQL_CHARACTER_SET_DATABASE].internal_variable_name];
const char* pta[4];
for (int i = 0; i < 4; i++) {
pta[i] = vals[i].c_str();
}
resultset->add_row(pta);
bool deprecate_eof_active = client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF;
SQLite3_to_MySQL(resultset, NULL, 0, &client_myds->myprot, false, deprecate_eof_active);
delete resultset;
l_free(pkt->size, pkt->ptr);
return true;
}
}
return false;
}

@ -29,9 +29,9 @@ using json = nlohmann::json;
#define SELECT_VERSION_COMMENT "select @@version_comment limit 1"
#define SELECT_VERSION_COMMENT_LEN 32
#define SELECT_DB_USER "select DATABASE(), USER() limit 1"
//#define SELECT_DB_USER "select DATABASE(), USER() limit 1"
#define SELECT_DB_USER_LEN 33
#define SELECT_CHARSET_STATUS "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
//#define SELECT_CHARSET_STATUS "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
#define SELECT_CHARSET_STATUS_LEN 115
#define PROXYSQL_VERSION_COMMENT "\x01\x00\x00\x01\x01\x27\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x11\x40\x40\x76\x65\x72\x73\x69\x6f\x6e\x5f\x63\x6f\x6d\x6d\x65\x6e\x74\x00\x0c\x21\x00\x18\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x05\x00\x00\x03\xfe\x00\x00\x02\x00\x0b\x00\x00\x04\x0a(ProxySQL)\x05\x00\x00\x05\xfe\x00\x00\x02\x00"
#define PROXYSQL_VERSION_COMMENT_LEN 81
@ -1309,7 +1309,6 @@ void MySQL_Session::return_proxysql_internal(PtrSize_t *pkt) {
}
l_free(pkt->size,pkt->ptr);
}
#endif // 0
/**
* @brief Handles special queries executed by the STATUS command in mysql cli .
@ -1376,6 +1375,7 @@ bool MySQL_Session::handler_special_queries_STATUS(PtrSize_t *pkt) {
}
return false;
}
#endif // 0
bool MySQL_Session::handler_special_queries(PtrSize_t *pkt) {
bool deprecate_eof_active = client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF;

@ -30,9 +30,9 @@ using json = nlohmann::json;
#define SELECT_VERSION_COMMENT "select @@version_comment limit 1"
#define SELECT_VERSION_COMMENT_LEN 32
#define SELECT_DB_USER "select DATABASE(), USER() limit 1"
//#define SELECT_DB_USER "select DATABASE(), USER() limit 1"
#define SELECT_DB_USER_LEN 33
#define SELECT_CHARSET_STATUS "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
//#define SELECT_CHARSET_STATUS "select @@character_set_client, @@character_set_connection, @@character_set_server, @@character_set_database limit 1"
#define SELECT_CHARSET_STATUS_LEN 115
#define PROXYSQL_VERSION_COMMENT "\x01\x00\x00\x01\x01\x27\x00\x00\x02\x03\x64\x65\x66\x00\x00\x00\x11\x40\x40\x76\x65\x72\x73\x69\x6f\x6e\x5f\x63\x6f\x6d\x6d\x65\x6e\x74\x00\x0c\x21\x00\x18\x00\x00\x00\xfd\x00\x00\x1f\x00\x00\x05\x00\x00\x03\xfe\x00\x00\x02\x00\x0b\x00\x00\x04\x0a(ProxySQL)\x05\x00\x00\x05\xfe\x00\x00\x02\x00"
#define PROXYSQL_VERSION_COMMENT_LEN 81
@ -1289,7 +1289,6 @@ void PgSQL_Session::return_proxysql_internal(PtrSize_t* pkt) {
}
l_free(pkt->size, pkt->ptr);
}
#endif // 0
/**
* @brief Handles special queries executed by the STATUS command in pgsql cli .
@ -1355,6 +1354,7 @@ bool PgSQL_Session::handler_special_queries_STATUS(PtrSize_t* pkt) {
}
return false;
}
#endif // 0
bool PgSQL_Session::handler_special_queries(PtrSize_t* pkt) {
bool deprecate_eof_active = client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF;

Loading…
Cancel
Save