From 13c9fe0ebb910cdc4f5eab51b4d9ee2ea5348d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Canna=C3=B2?= Date: Wed, 13 Jul 2016 20:47:14 +0000 Subject: [PATCH] Support extra syntax in Admin module - SELECT @@max_allowed_packet - SELECT @@variable - SHOW VARIABLES LIKE - SHOW VARIABLES WHERE --- include/MySQL_Protocol.h | 1 + include/proxysql_admin.h | 7 ++++ lib/MySQL_Protocol.cpp | 12 ++++++ lib/ProxySQL_Admin.cpp | 80 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 100 insertions(+) diff --git a/include/MySQL_Protocol.h b/include/MySQL_Protocol.h index e38d7084b..ef14f9c22 100644 --- a/include/MySQL_Protocol.h +++ b/include/MySQL_Protocol.h @@ -96,5 +96,6 @@ class MySQL_Protocol { bool process_pkt_handshake_response(unsigned char *pkt, unsigned int len); bool process_pkt_COM_QUERY(unsigned char *pkt, unsigned int len); bool process_pkt_COM_CHANGE_USER(unsigned char *pkt, unsigned int len); + void * Query_String_to_packet(uint8_t sid, std::string *s, unsigned int *l); }; #endif /* __CLASS_MYSQL_PROTOCOL_H */ diff --git a/include/proxysql_admin.h b/include/proxysql_admin.h index 818205b09..651c1a642 100644 --- a/include/proxysql_admin.h +++ b/include/proxysql_admin.h @@ -74,6 +74,7 @@ class ProxySQL_Admin { #endif /* DEBUG */ } variables; + ProxySQL_External_Scheduler *scheduler; void dump_mysql_collations(); @@ -121,6 +122,12 @@ class ProxySQL_Admin { void delete_credentials(char *credentials); #endif /* DEBUG */ public: + struct { + //re2::RE2::Options *opt; + //RE2 *re1; + void *opt; + void **re; + } match_regexes; ProxySQL_Admin(); ~ProxySQL_Admin(); SQLite3DB *admindb; // in memory diff --git a/lib/MySQL_Protocol.cpp b/lib/MySQL_Protocol.cpp index ab45371ad..9c638b48a 100644 --- a/lib/MySQL_Protocol.cpp +++ b/lib/MySQL_Protocol.cpp @@ -1393,6 +1393,18 @@ __exit_process_pkt_handshake_response: return ret; } +void * MySQL_Protocol::Query_String_to_packet(uint8_t sid, std::string *s, unsigned int *l) { + mysql_hdr hdr; + hdr.pkt_id=sid; + hdr.pkt_length=1+s->length(); + *l=hdr.pkt_length+sizeof(mysql_hdr); + void *pkt=malloc(*l); + memcpy(pkt,&hdr,sizeof(mysql_hdr)); + uint8_t c=_MYSQL_COM_QUERY; + memcpy((char *)pkt+4,&c,1); + memcpy((char *)pkt+5,s->c_str(),s->length()); + return pkt; +} MySQL_ResultSet::MySQL_ResultSet(MySQL_Protocol *_myprot, MYSQL_RES *_res, MYSQL *_my) { transfer_started=false; diff --git a/lib/ProxySQL_Admin.cpp b/lib/ProxySQL_Admin.cpp index f0d86a215..57e38da8d 100644 --- a/lib/ProxySQL_Admin.cpp +++ b/lib/ProxySQL_Admin.cpp @@ -1,3 +1,8 @@ +#include // std::cout +#include // std::sort +#include // std::vector +#include "re2/re2.h" +#include "re2/regexp.h" #include "proxysql.h" #include "cpp.h" @@ -1634,6 +1639,65 @@ void admin_session_handler(MySQL_Session *sess, ProxySQL_Admin *pa, PtrSize_t *p goto __run_query; } + { + bool rc; + rc=RE2::PartialMatch(query_no_space,*(RE2 *)(pa->match_regexes.re[0])); + if (rc) { + string *new_query=new std::string(query_no_space); + RE2::Replace(new_query,(char *)"^(\\w+)\\s+@@(\\w+)\\s*",(char *)"SELECT variable_value AS '@@max_allowed_packet' FROM global_variables WHERE variable_name='mysql-max_allowed_packet'"); + free(query); + query_length=new_query->length()+1; + query=(char *)malloc(query_length); + memcpy(query,new_query->c_str(),query_length-1); + query[query_length-1]='\0'; + goto __run_query; + } + } + { + bool rc; + //RE2 *re=(RE2 *)pa->match_regexes.re; + rc=RE2::PartialMatch(query_no_space,*(RE2 *)(pa->match_regexes.re[1])); + if (rc) { + string *new_query=new std::string(query_no_space); + //RE2::Replace(new_query,(char *)"-",(char *)"_"); + RE2::Replace(new_query,(char *)"^(\\w+) *@@([0-9A-Za-z_-]+) *",(char *)"SELECT variable_value AS '@@\\2' FROM global_variables WHERE variable_name='\\2'"); + free(query); + query_length=new_query->length()+1; + query=(char *)malloc(query_length); + memcpy(query,new_query->c_str(),query_length-1); + query[query_length-1]='\0'; + goto __run_query; + } + } + { + bool rc; + rc=RE2::PartialMatch(query_no_space,*(RE2 *)(pa->match_regexes.re[2])); + if (rc) { + string *new_query=new std::string(query_no_space); + RE2::Replace(new_query,(char *)"([Ss][Hh][Oo][Ww]\\s+[Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]\\s+[Ww][Hh][Ee][Rr][Ee])",(char *)"SELECT variable_name AS Variable_name, variable_value AS Value FROM global_variables WHERE"); + free(query); + query_length=new_query->length()+1; + query=(char *)malloc(query_length); + memcpy(query,new_query->c_str(),query_length-1); + query[query_length-1]='\0'; + goto __run_query; + } + } + { + bool rc; + rc=RE2::PartialMatch(query_no_space,*(RE2 *)(pa->match_regexes.re[3])); + if (rc) { + string *new_query=new std::string(query_no_space); + RE2::Replace(new_query,(char *)"([Ss][Hh][Oo][Ww]\\s+[Vv][Aa][Rr][Ii][Aa][Bb][Ll][Ee][Ss]\\s+[Ll][Ii][Kk][Ee])",(char *)"SELECT variable_name AS Variable_name, variable_value AS Value FROM global_variables WHERE variable_name LIKE"); + free(query); + query_length=new_query->length()+1; + query=(char *)malloc(query_length); + memcpy(query,new_query->c_str(),query_length-1); + query[query_length-1]='\0'; + goto __run_query; + } + } + if (!strncasecmp("SET ", query_no_space, 4)) { proxy_debug(PROXY_DEBUG_ADMIN, 4, "Received SET\n"); run_query = admin_handler_command_set(query_no_space, query_no_space_length, sess, pa, &query, &query_length); @@ -2298,6 +2362,16 @@ ProxySQL_Admin::ProxySQL_Admin() { #endif /* DEBUG */ // create the scheduler scheduler=new ProxySQL_External_Scheduler(); + + match_regexes.opt=(re2::RE2::Options *)new re2::RE2::Options(RE2::Quiet); + re2::RE2::Options *opt2=(re2::RE2::Options *)match_regexes.opt; + opt2->set_case_sensitive(false); + //match_regexes.re1=(RE2 *)new RE2("^SELECT @@\\w+ *", *opt2); + match_regexes.re=(void **)malloc(sizeof(void *)*10); + match_regexes.re[0]=(RE2 *)new RE2("^SELECT\\s+@@max_allowed_packet\\s*", *opt2); + match_regexes.re[1]=(RE2 *)new RE2("^SELECT\\s+@@[0-9A-Za-z_-]+\\s*", *opt2); + match_regexes.re[2]=(RE2 *)new RE2("SHOW\\s+VARIABLES\\s+WHERE", *opt2); + match_regexes.re[3]=(RE2 *)new RE2("SHOW\\s+VARIABLES\\s+LIKE", *opt2); }; void ProxySQL_Admin::wrlock() { @@ -2525,6 +2599,12 @@ void ProxySQL_Admin::admin_shutdown() { ProxySQL_Admin::~ProxySQL_Admin() { admin_shutdown(); + delete (RE2 *)match_regexes.re[0]; + delete (RE2 *)match_regexes.re[1]; + delete (RE2 *)match_regexes.re[2]; + delete (RE2 *)match_regexes.re[3]; + free(match_regexes.re); + delete (re2::RE2::Options *)match_regexes.opt; };