diff --git a/include/c_tokenizer.h b/include/c_tokenizer.h index f08246c09..ce89f0ba8 100644 --- a/include/c_tokenizer.h +++ b/include/c_tokenizer.h @@ -28,7 +28,7 @@ extern "C" { tokenizer_t tokenizer( const char* s, const char* delimiters, int empties ); const char* free_tokenizer( tokenizer_t* tokenizer ); const char* tokenize( tokenizer_t* tokenizer ); -char * mysql_query_digest_and_first_comment(char *s , int len , char **first_comment); +char * mysql_query_digest_and_first_comment(char *s , int len , char **first_comment, char *buf); void c_split_2(const char *in, const char *del, char **out1, char **out2); #ifdef __cplusplus } diff --git a/include/mysql_connection.h b/include/mysql_connection.h index 2c91b6af9..40828c05f 100644 --- a/include/mysql_connection.h +++ b/include/mysql_connection.h @@ -150,7 +150,13 @@ class MySQL_Connection { void async_free_result(); - bool IsActiveTransaction(); + bool IsActiveTransaction() { + bool ret=false; + if (mysql) { + ret = (mysql->server_status & SERVER_STATUS_IN_TRANS); + } + return ret; + } bool IsAutoCommit(); bool MultiplexDisabled(); void ProcessQueryAndSetStatusFlags(char *query_digest_text); diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h index cdbb336f1..f6eeaa482 100644 --- a/include/proxysql_structs.h +++ b/include/proxysql_structs.h @@ -352,8 +352,10 @@ class MySQL_HostGroups_Manager; #ifndef PROXYSQL_STRUCTS #define PROXYSQL_STRUCTS +#define QUERY_DIGEST_BUF 128 struct __SQP_query_parser_t { + char buf[QUERY_DIGEST_BUF]; uint64_t digest; uint64_t digest_total; char *digest_text; diff --git a/lib/Query_Processor.cpp b/lib/Query_Processor.cpp index e47f06770..02d939d4e 100644 --- a/lib/Query_Processor.cpp +++ b/lib/Query_Processor.cpp @@ -656,8 +656,15 @@ Query_Processor_Output * Query_Processor::process_mysql_query(MySQL_Session *ses if (qi) { qp=(SQP_par_t *)&qi->QueryParserArgs; } +#define stackbuffer_size 128 + char stackbuffer[stackbuffer_size]; unsigned int len=size-sizeof(mysql_hdr)-1; - char *query=(char *)l_alloc(len+1); + char *query=NULL; + if (len < stackbuffer_size) { + query=stackbuffer; + } else { + query=(char *)l_alloc(len+1); + } memcpy(query,(char *)ptr+sizeof(mysql_hdr)+1,len); query[len]=0; if (__sync_add_and_fetch(&version,0) > _thr_SQP_version) { @@ -940,7 +947,11 @@ __internal_loop: __exit_process_mysql_query: // FIXME : there is too much data being copied around - l_free(len+1,query); + if (len < stackbuffer_size) { + // query is in the stack + } else { + l_free(len+1,query); + } if (sess->mirror==false) { // we process comments only on original queries, not on mirrors if (qp && qp->first_comment) { // we have a comment to parse @@ -1002,7 +1013,7 @@ void Query_Processor::query_parser_init(SQP_par_t *qp, char *query, int query_le qp->first_comment=NULL; qp->query_prefix=NULL; if (mysql_thread___query_digests) { - qp->digest_text=mysql_query_digest_and_first_comment(query, query_length, &qp->first_comment); + qp->digest_text=mysql_query_digest_and_first_comment(query, query_length, &qp->first_comment, ((query_length < QUERY_DIGEST_BUF) ? qp->buf : NULL)); // the hash is computed only up to query_digests_max_digest_length bytes int digest_text_length=strnlen(qp->digest_text, mysql_thread___query_digests_max_digest_length); qp->digest=SpookyHash::Hash64(qp->digest_text, digest_text_length, 0); @@ -1517,7 +1528,9 @@ bool Query_Processor::query_parser_first_comment(Query_Processor_Output *qpo, ch void Query_Processor::query_parser_free(SQP_par_t *qp) { if (qp->digest_text) { - free(qp->digest_text); + if (qp->digest_text != qp->buf) { + free(qp->digest_text); + } qp->digest_text=NULL; } if (qp->first_comment) { diff --git a/lib/c_tokenizer.c b/lib/c_tokenizer.c index 9ab89c526..4d8e7d201 100644 --- a/lib/c_tokenizer.c +++ b/lib/c_tokenizer.c @@ -165,7 +165,7 @@ static char is_digit_string(char *f, char *t) } -char *mysql_query_digest_and_first_comment(char *s, int _len, char **first_comment){ +char *mysql_query_digest_and_first_comment(char *s, int _len, char **first_comment, char *buf){ int i = 0; char cur_comment[FIRST_COMMENT_MAX_LENGTH]; @@ -177,8 +177,10 @@ char *mysql_query_digest_and_first_comment(char *s, int _len, char **first_comme if (_len > mysql_thread___query_digests_max_query_length) { len = mysql_thread___query_digests_max_query_length; } - char *r = (char *) malloc(len + SIZECHAR); - + char *r = buf; + if (r==NULL) { + r = (char *) malloc(len + SIZECHAR); + } char *p_r = r; char *p_r_t = r; diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp index 46f0dfc7c..0dd4afe01 100644 --- a/lib/mysql_connection.cpp +++ b/lib/mysql_connection.cpp @@ -1396,6 +1396,7 @@ void MySQL_Connection::async_free_result() { } } +/* bool MySQL_Connection::IsActiveTransaction() { bool ret=false; if (mysql) { @@ -1403,6 +1404,7 @@ bool MySQL_Connection::IsActiveTransaction() { } return ret; } +*/ bool MySQL_Connection::IsAutoCommit() { bool ret=false;