Skip to content

Commit b6d796c

Browse files
committed
Improve mysqldump compatibility
Signed-off-by: Wazir Ahmed <[email protected]>
1 parent 62b8103 commit b6d796c

File tree

3 files changed

+159
-0
lines changed

3 files changed

+159
-0
lines changed

include/MySQL_Session.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class MySQL_Session: public Base_Session<MySQL_Session, MySQL_Data_Stream, MySQL
129129
*/
130130
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_USE_DB(PtrSize_t *pkt);
131131
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PING(PtrSize_t *);
132+
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(PtrSize_t *pkt);
132133

133134
void handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_CHANGE_USER(PtrSize_t *, bool *);
134135
/**

lib/Admin_Handler.cpp

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,6 +2284,89 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
22842284
// add global mutex, see bug #1188
22852285
pthread_mutex_lock(&pa->sql_query_global_mutex);
22862286

2287+
if (strcasestr(query_no_space, "INFORMATION_SCHEMA.TABLES") != nullptr) {
2288+
const char* info_table_name = "SELECT table_name FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = DATABASE() AND table_name = '";
2289+
const char* info_engine_table_type = "SELECT engine, table_type FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = DATABASE() AND table_name = '";
2290+
2291+
if (query_no_space_length > strlen(info_table_name) &&
2292+
strncasecmp(query_no_space, info_table_name, strlen(info_table_name)) == 0) {
2293+
std::string query_str(query_no_space, query_no_space_length);
2294+
2295+
size_t start_pos = strlen(info_table_name);
2296+
size_t end_pos = query_str.find('\'', start_pos);
2297+
2298+
if (end_pos != std::string::npos) {
2299+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2300+
2301+
char buf[256];
2302+
snprintf(buf, sizeof(buf),
2303+
"SELECT name as TABLE_NAME FROM sqlite_master WHERE type = 'table' AND name = '%s'",
2304+
table_name_value.c_str());
2305+
2306+
l_free(query_length, query);
2307+
query = l_strdup(buf);
2308+
query_length = strlen(query) + 1;
2309+
goto __run_query;
2310+
}
2311+
}
2312+
2313+
if (query_no_space_length > strlen(info_engine_table_type) &&
2314+
strncasecmp(query_no_space, info_engine_table_type, strlen(info_engine_table_type)) == 0) {
2315+
std::string query_str(query_no_space, query_no_space_length);
2316+
2317+
size_t start_pos = strlen(info_engine_table_type);
2318+
size_t end_pos = query_str.find('\'', start_pos);
2319+
2320+
if (end_pos != std::string::npos) {
2321+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2322+
2323+
char buf[256];
2324+
snprintf(buf, sizeof(buf),
2325+
"SELECT 'SQLite' as ENGINE, 'BASE TABLE' as TABLE_TYPE FROM sqlite_master WHERE type = 'table' AND name = '%s'",
2326+
table_name_value.c_str());
2327+
2328+
l_free(query_length, query);
2329+
query = l_strdup(buf);
2330+
query_length = strlen(query) + 1;
2331+
goto __run_query;
2332+
}
2333+
}
2334+
}
2335+
2336+
if (strcasestr(query_no_space, "INFORMATION_SCHEMA.COLUMNS") != nullptr) {
2337+
const char* info_column_data_type = "SELECT column_name, extra, generation_expression, data_type FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema=database() AND table_name='";
2338+
2339+
if (query_no_space_length > strlen(info_column_data_type) &&
2340+
strncasecmp(query_no_space, info_column_data_type, strlen(info_column_data_type)) == 0) {
2341+
std::string query_str(query_no_space, query_no_space_length);
2342+
2343+
size_t start_pos = strlen(info_column_data_type);
2344+
size_t end_pos = query_str.find('\'', start_pos);
2345+
2346+
if (end_pos != std::string::npos) {
2347+
std::string table_name_value = query_str.substr(start_pos, end_pos - start_pos);
2348+
2349+
char buf[256];
2350+
snprintf(buf, sizeof(buf),
2351+
"SELECT name as COLUMN_NAME, '' as EXTRA, '' as GENERATION_EXPRESSION, type as DATA_TYPE FROM pragma_table_info('%s') ORDER BY cid",
2352+
table_name_value.c_str());
2353+
2354+
l_free(query_length, query);
2355+
query = l_strdup(buf);
2356+
query_length = strlen(query) + 1;
2357+
goto __run_query;
2358+
}
2359+
}
2360+
}
2361+
2362+
if (!strncasecmp("SELECT LOGFILE", query_no_space, strlen("SELECT LOGFILE")) && strcasestr(query_no_space, "FROM INFORMATION_SCHEMA.FILES") != nullptr) {
2363+
string err_msg = "Invalid command - SELECT .. FROM INFORMATION_SCHEMA.FILES. ";
2364+
err_msg += "If you are using mysqldump, use --no-tablespaces flag to avoid this error message";
2365+
SPA->send_error_msg_to_client(sess, const_cast<char*>(err_msg.c_str()));
2366+
run_query = false;
2367+
goto __run_query;
2368+
}
2369+
22872370
if (sess->session_type == PROXYSQL_SESSION_ADMIN) { // no stats
22882371
if (!strncasecmp("LOGENTRY ", query_no_space, strlen("LOGENTRY "))) {
22892372
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Received command LOGENTRY: %s\n", query_no_space + strlen("LOGENTRY "));
@@ -2789,12 +2872,14 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
27892872
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
27902873
if (
27912874
!strncmp("/*!40014 SET ", query_no_space, 13) ||
2875+
!strncmp("/*!40100 SET ", query_no_space, 13) ||
27922876
!strncmp("/*!40101 SET ", query_no_space, 13) ||
27932877
!strncmp("/*!40103 SET ", query_no_space, 13) ||
27942878
!strncmp("/*!40111 SET ", query_no_space, 13) ||
27952879
!strncmp("/*!80000 SET ", query_no_space, 13) ||
27962880
!strncmp("/*!50503 SET ", query_no_space, 13) ||
27972881
!strncmp("/*!50717 SET ", query_no_space, 13) ||
2882+
!strncmp("/*M!100100 SET ", query_no_space, 15) ||
27982883
!strncmp("/*!50717 SELECT ", query_no_space, strlen("/*!50717 SELECT ")) ||
27992884
!strncmp("/*!50717 PREPARE ", query_no_space, strlen("/*!50717 PREPARE ")) ||
28002885
!strncmp("/*!50717 EXECUTE ", query_no_space, strlen("/*!50717 EXECUTE ")) ||
@@ -2817,13 +2902,68 @@ void admin_session_handler(S* sess, void *_pa, PtrSize_t *pkt) {
28172902
||
28182903
!strncmp("SET SESSION character_set_results", query_no_space, strlen("SET SESSION character_set_results"))
28192904
||
2905+
!strncasecmp("FLUSH /*!40101 LOCAL */ TABLES", query_no_space, strlen("FLUSH /*!40101 LOCAL */ TABLES"))
2906+
||
2907+
!strncasecmp("FLUSH /*!40101 LOCAL */ LOGS", query_no_space, strlen("FLUSH /*!40101 LOCAL */ LOGS"))
2908+
||
2909+
!strncasecmp("FLUSH TABLES WITH READ LOCK", query_no_space, strlen("FLUSH TABLES WITH READ LOCK"))
2910+
||
28202911
!strncasecmp("USE ", query_no_space, strlen("USE ")) // this applies to all clients, not only mysqldump
28212912
) {
28222913
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
28232914
run_query=false;
28242915
goto __run_query;
28252916
}
28262917

2918+
if (query_no_space_length == strlen("SHOW MASTER STATUS") && !strncasecmp("SHOW MASTER STATUS", query_no_space, query_no_space_length)) {
2919+
l_free(query_length, query);
2920+
query = l_strdup("SELECT '' AS 'File', 0 AS 'Position', '' AS 'Binlog_Do_DB', '' AS 'Binlog_Ignore_DB', '' AS 'Executed_Gtid_Set' WHERE 1=0");
2921+
query_length = strlen(query) + 1;
2922+
goto __run_query;
2923+
}
2924+
2925+
if (query_no_space_length == strlen("SHOW BINARY LOG STATUS") && !strncasecmp("SHOW BINARY LOG STATUS", query_no_space, query_no_space_length)) {
2926+
l_free(query_length, query);
2927+
query = l_strdup("SELECT '' AS 'File', 0 AS 'Position', '' AS 'Binlog_Do_DB', '' AS 'Binlog_Ignore_DB', '' AS 'Executed_Gtid_Set' WHERE 1=0");
2928+
query_length = strlen(query) + 1;
2929+
goto __run_query;
2930+
}
2931+
2932+
if (query_no_space_length >= strlen("SHOW FUNCTION STATUS") && !strncasecmp("SHOW FUNCTION STATUS", query_no_space, strlen("SHOW FUNCTION STATUS"))) {
2933+
l_free(query_length, query);
2934+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Type', '' AS 'Definer', '' AS 'Modified', '' AS 'Created', '' AS 'Security_type', '' AS 'Comment', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
2935+
query_length = strlen(query) + 1;
2936+
goto __run_query;
2937+
}
2938+
2939+
if (query_no_space_length >= strlen("SHOW PROCEDURE STATUS") && !strncasecmp("SHOW PROCEDURE STATUS", query_no_space, strlen("SHOW PROCEDURE STATUS"))) {
2940+
l_free(query_length, query);
2941+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Type', '' AS 'Definer', '' AS 'Modified', '' AS 'Created', '' AS 'Security_type', '' AS 'Comment', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
2942+
query_length = strlen(query) + 1;
2943+
goto __run_query;
2944+
}
2945+
2946+
if (query_no_space_length >= strlen("SHOW TRIGGERS") && !strncasecmp("SHOW TRIGGERS", query_no_space, strlen("SHOW TRIGGERS"))) {
2947+
l_free(query_length, query);
2948+
query = l_strdup("SELECT '' AS 'Trigger', '' AS 'Event', '' AS 'Table', '' AS 'Statement', '' AS 'Timing', '' AS 'Created', '' AS 'sql_mode', '' AS 'Definer', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
2949+
query_length = strlen(query) + 1;
2950+
goto __run_query;
2951+
}
2952+
2953+
if (query_no_space_length >= strlen("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS") && !strncasecmp("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS", query_no_space, strlen("SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS"))) {
2954+
l_free(query_length, query);
2955+
query = l_strdup("SELECT '' AS 'TRIGGER_NAME' WHERE 1=0");
2956+
query_length = strlen(query) + 1;
2957+
goto __run_query;
2958+
}
2959+
2960+
if (query_no_space_length >= strlen("SHOW EVENTS") && !strncasecmp("SHOW EVENTS", query_no_space, strlen("SHOW EVENTS"))) {
2961+
l_free(query_length, query);
2962+
query = l_strdup("SELECT '' AS 'Db', '' AS 'Name', '' AS 'Definer', '' AS 'Time zone', '' AS 'Type', '' AS 'Execute at', '' AS 'Interval value', '' AS 'Interval field', '' AS 'Starts', '' AS 'Ends', '' AS 'Status', '' AS 'Originator', '' AS 'character_set_client', '' AS 'collation_connection', '' AS 'Database Collation' WHERE 1=0");
2963+
query_length = strlen(query) + 1;
2964+
goto __run_query;
2965+
}
2966+
28272967
if (!strncmp("SHOW STATUS LIKE 'binlog_snapshot_gtid_executed'", query_no_space, strlen("SHOW STATUS LIKE 'binlog_snapshot_gtid_executed'"))) {
28282968
l_free(query_length, query);
28292969
query = l_strdup("SELECT variable_name AS Variable_name, Variable_value AS Value FROM global_variables WHERE 1=0");

lib/MySQL_Session.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3641,6 +3641,9 @@ bool MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
36413641
case _MYSQL_COM_RESET_CONNECTION:
36423642
handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_RESET_CONNECTION(pkt);
36433643
break;
3644+
case _MYSQL_COM_REFRESH:
3645+
handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(pkt);
3646+
break;
36443647
default:
36453648
return false;
36463649
break;
@@ -5789,6 +5792,21 @@ void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_C
57895792
}
57905793
}
57915794

5795+
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_REFRESH(PtrSize_t *pkt) {
5796+
proxy_debug(PROXY_DEBUG_MYSQL_COM, 5, "Got COM_REFRESH packet\n");
5797+
5798+
l_free(pkt->size, pkt->ptr);
5799+
client_myds->setDSS_STATE_QUERY_SENT_NET();
5800+
5801+
unsigned int nTrx = NumActiveTransactions();
5802+
uint16_t setStatus = (nTrx ? SERVER_STATUS_IN_TRANS : 0);
5803+
if (autocommit)
5804+
setStatus |= SERVER_STATUS_AUTOCOMMIT;
5805+
5806+
client_myds->myprot.generate_pkt_OK(true, NULL, NULL, 1, 0, 0, setStatus, 0, NULL);
5807+
client_myds->DSS=STATE_SLEEP;
5808+
}
5809+
57925810
void MySQL_Session::handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_PROCESS_KILL(PtrSize_t *pkt) {
57935811
l_free(pkt->size,pkt->ptr);
57945812
client_myds->setDSS_STATE_QUERY_SENT_NET();

0 commit comments

Comments
 (0)