|
|
|
|
@ -25,7 +25,10 @@
|
|
|
|
|
|
|
|
|
|
#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_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
|
|
|
|
|
#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
|
|
|
|
|
|
|
|
|
|
@ -1320,9 +1323,83 @@ void MySQL_Session::return_proxysql_internal(PtrSize_t *pkt) {
|
|
|
|
|
l_free(pkt->size,pkt->ptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @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
|
|
|
|
|
*/
|
|
|
|
|
bool MySQL_Session::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");
|
|
|
|
|
|
|
|
|
|
string vals[4];
|
|
|
|
|
json j = {};
|
|
|
|
|
MySQL_Connection *conn = client_myds->myconn;
|
|
|
|
|
// 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.
|
|
|
|
|
conn->variables[SQL_CHARACTER_SET_CLIENT].fill_client_internal_session(j, SQL_CHARACTER_SET_CLIENT);
|
|
|
|
|
conn->variables[SQL_CHARACTER_SET_CONNECTION].fill_client_internal_session(j, SQL_CHARACTER_SET_CONNECTION);
|
|
|
|
|
conn->variables[SQL_CHARACTER_SET_DATABASE].fill_client_internal_session(j, SQL_CHARACTER_SET_DATABASE);
|
|
|
|
|
|
|
|
|
|
vals[0] = j["conn"][mysql_tracked_variables[SQL_CHARACTER_SET_CLIENT].internal_variable_name];
|
|
|
|
|
vals[1] = j["conn"][mysql_tracked_variables[SQL_CHARACTER_SET_CONNECTION].internal_variable_name];
|
|
|
|
|
vals[2] = string(mysql_thread___default_variables[SQL_CHARACTER_SET]);
|
|
|
|
|
vals[3] = j["conn"][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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool MySQL_Session::handler_special_queries(PtrSize_t *pkt) {
|
|
|
|
|
bool deprecate_eof_active = client_myds->myconn->options.client_flag & CLIENT_DEPRECATE_EOF;
|
|
|
|
|
|
|
|
|
|
if (
|
|
|
|
|
(pkt->size == (SELECT_DB_USER_LEN+5))
|
|
|
|
|
||
|
|
|
|
|
(pkt->size == (SELECT_CHARSET_STATUS_LEN+5))
|
|
|
|
|
) {
|
|
|
|
|
if (handler_special_queries_STATUS(pkt) == true) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (pkt->size>(5+18) && strncasecmp((char *)"PROXYSQL INTERNAL ",(char *)pkt->ptr+5,18)==0) {
|
|
|
|
|
return_proxysql_internal(pkt);
|
|
|
|
|
return true;
|
|
|
|
|
|