diff --git a/include/proxysql_debug.h b/include/proxysql_debug.h index c6416497e..569f92e00 100644 --- a/include/proxysql_debug.h +++ b/include/proxysql_debug.h @@ -1,14 +1,3 @@ - -/* -#ifdef DEBUG -#ifndef DEBUG_EXTERN -#define DEBUG_EXTERN -extern debug_level *gdbg_lvl; -extern int gdbg; -#endif -#endif -*/ - #ifndef __PROXYSQL_DEBUG_H #define __PROXYSQL_DEBUG_H @@ -46,7 +35,6 @@ class Timer { #ifdef DEBUG #define PROXY_TRACE() { proxy_debug(PROXY_DEBUG_GENERIC,10,"TRACE\n"); } -//#define PROXY_TRACE2() { proxy_info("TRACE\n"); } #define PROXY_TRACE2() #else #define PROXY_TRACE() @@ -64,7 +52,6 @@ class Timer { } \ } while (0) #elif defined(__linux__) -//#ifdef SYS_gettid #define proxy_debug(module, verbosity, fmt, ...) \ do { if (GloVars.global.gdbg) { \ proxy_debug_func(module, verbosity, syscall(SYS_gettid), __FILE__, __LINE__, __func__ , fmt, ## __VA_ARGS__); \ @@ -76,9 +63,6 @@ class Timer { #define proxy_debug(module, verbosity, fmt, ...) #endif /* DEBUG */ -/* -#ifdef DEBUG -*/ #define proxy_error(fmt, ...) \ do { \ time_t __timer; \ @@ -111,23 +95,7 @@ class Timer { strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", &__tm_info); \ proxy_error_func(0, "%s %s:%d:%s(): [ERROR] " fmt, __buffer, fi, li, fu , ## __VA_ARGS__); \ } while(0) -/* -#else -#define proxy_error(fmt, ...) \ - do { \ - time_t __timer; \ - char __buffer[25]; \ - struct tm *__tm_info; \ - time(&__timer); \ - __tm_info = localtime(&__timer); \ - strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", __tm_info); \ - proxy_error_func("%s [ERROR] " fmt , __buffer , ## __VA_ARGS__); \ - } while(0) -#endif -*/ -/* -#ifdef DEBUG -*/ + #define proxy_warning(fmt, ...) \ do { \ time_t __timer; \ @@ -150,20 +118,6 @@ class Timer { proxy_error_func(ecode, "%s %s:%d:%s(): [WARNING] " fmt, __buffer, __FILE__, __LINE__, __func__ , ## __VA_ARGS__); \ } while(0) -/* -#else -#define proxy_warning(fmt, ...) \ - do { \ - time_t __timer; \ - char __buffer[25]; \ - struct tm *__tm_info; \ - time(&__timer); \ - __tm_info = localtime(&__timer); \ - strftime(__buffer, 25, "%Y-%m-%d %H:%M:%S", __tm_info); \ - proxy_error_func("%s [WARNING] " fmt , __buffer , ## __VA_ARGS__); \ - } while(0) -#endif -*/ #ifdef DEBUG #define proxy_info(fmt, ...) \ do { \ @@ -211,13 +165,26 @@ class Timer { #endif #ifdef DEBUG -//void *debug_logger(); #endif +#define NULL_DB_MSG "The pointer to sqlite3 database is NULL. Cannot get error message." + #define ASSERT_SQLITE_OK(rc, db) \ do { \ if (rc!=SQLITE_OK) { \ - proxy_error("SQLite3 error with return code %d. Error message: %s. Shutting down.\n", rc, db?(*proxy_sqlite3_errmsg)(db->get_db()):"The pointer to sqlite3 database is null. Cannot get error message."); \ + proxy_error( \ + "SQLite3 error. Shutting down rc=%d msg='%s'\n", \ + rc, db ? (*proxy_sqlite3_errmsg)(db->get_db()) : NULL_DB_MSG); \ + assert(0); \ + } \ + } while(0) + +#define ASSERT_SQLITE3_OK(rc, db) \ + do { \ + if (rc!=SQLITE_OK) { \ + proxy_error( \ + "SQLite3 error. Shutting down rc=%d msg='%s'\n", \ + rc, db ? (*proxy_sqlite3_errmsg)(db) : NULL_DB_MSG); \ assert(0); \ } \ } while(0) @@ -243,7 +210,7 @@ SQLite3_result* proxysql_get_message_stats(bool reset=false); */ void proxysql_init_debug_prometheus_metrics(); - +class SQLite3DB; /** * @brief Set or unset if Admin has debugdb_disk fully initialized */ @@ -251,4 +218,4 @@ void proxysql_set_admin_debugdb_disk(SQLite3DB *_db); void proxysql_set_admin_debug_output(unsigned int _do); -#endif +#endif // DEBUG diff --git a/lib/debug.cpp b/lib/debug.cpp index 4f3755c9c..08729b166 100644 --- a/lib/debug.cpp +++ b/lib/debug.cpp @@ -15,37 +15,16 @@ using std::string; using std::unordered_map; #ifdef DEBUG -#ifdef DEBUG_EXTERN -#undef DEBUG_EXTERN -#endif /* DEBUG_EXTERN */ -#endif /* DEBUG */ - -#ifndef CLOCK_MONOTONIC -#define CLOCK_MONOTONIC SYSTEM_CLOCK -#endif // CLOCK_MONOTONIC -#ifdef DEBUG __thread unsigned long long pretime=0; static pthread_mutex_t debug_mutex; static pthread_rwlock_t filters_rwlock; static SQLite3DB * debugdb_disk = NULL; sqlite3_stmt *statement1=NULL; static unsigned int debug_output = 1; -#endif /* DEBUG */ - -/* -static inline unsigned long long debug_monotonic_time() { - struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); - return (((unsigned long long) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000); -} -*/ #define DEBUG_MSG_MAXSIZE 1024 -#ifdef DEBUG - - /** * @brief Contains all filters related to debug. * @details The convention for key value is `filename:line:function`. This key structure also applies also @@ -58,7 +37,6 @@ static inline unsigned long long debug_monotonic_time() { std::set* debug_filters = nullptr; static bool filter_debug_entry(const char *__file, int __line, const char *__func) { - //pthread_mutex_lock(&debug_mutex); pthread_rwlock_rdlock(&filters_rwlock); bool to_filter = false; if (debug_filters && debug_filters->size()) { // if the set is empty we aren't performing any filter, so we won't search @@ -99,7 +77,6 @@ static bool filter_debug_entry(const char *__file, int __line, const char *__fun } } } - //pthread_mutex_unlock(&debug_mutex); pthread_rwlock_unlock(&filters_rwlock); return to_filter; } @@ -107,19 +84,16 @@ static bool filter_debug_entry(const char *__file, int __line, const char *__fun // we use this function to sent the filters to Admin // we hold here the lock on filters_rwlock void proxy_debug_get_filters(std::set& f) { - //pthread_mutex_lock(&debug_mutex); pthread_rwlock_rdlock(&filters_rwlock); if (debug_filters) { f = *debug_filters; } pthread_rwlock_unlock(&filters_rwlock); - //pthread_mutex_unlock(&debug_mutex); } // we use this function to get the filters from Admin // we hold here the lock on filters_rwlock void proxy_debug_load_filters(std::set& f) { - //pthread_mutex_lock(&debug_mutex); pthread_rwlock_wrlock(&filters_rwlock); if (debug_filters) { debug_filters->erase(debug_filters->begin(), debug_filters->end()); @@ -128,11 +102,19 @@ void proxy_debug_load_filters(std::set& f) { debug_filters = new std::set(f); } pthread_rwlock_unlock(&filters_rwlock); - //pthread_mutex_unlock(&debug_mutex); } // REMINDER: This function should always save/restore 'errno', otherwise it could influence error handling. -void proxy_debug_func(enum debug_module module, int verbosity, int thr, const char *__file, int __line, const char *__func, const char *fmt, ...) { +void proxy_debug_func( + enum debug_module module, + int verbosity, + int thr, + const char *__file, + int __line, + const char *__func, + const char *fmt, + ... +) { int saved_errno = errno; assert(module quote_symbol = {"\"", "'", "`"}; vector var_patterns = {}; @@ -198,19 +185,9 @@ void SetParser::generateRE_parse1v2() { string vp = "NULL"; // NULL var_patterns.push_back(vp); - //vp = "\\w+"; // single word - //var_patterns.push_back(vp); + { string vp0 = "(?:\\w|\\d)+"; // single word with letters and digits , for example utf8mb4 and latin1 - //var_patterns.push_back(vp); -/* - string vp1 = "(?:" + vp0 + "(?:," + vp0 + ")*)"; // multiple words (letters and digits) separated by commas WITHOUT any spaces between words . Used also for sql_mode , example: ONLY_FULL_GROUP_BY,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO - //var_patterns.push_back(vp1); // do NOT add without quote - for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { - string s = *it + vp1 + *it; - var_patterns.push_back(s); // add with quote - } -*/ string vp2 = "(?:" + vp0 + "(?:-" + vp0 + ")*)"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used also for transaction isolation var_patterns.push_back(vp2); for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { @@ -218,12 +195,6 @@ void SetParser::generateRE_parse1v2() { var_patterns.push_back(s); // add with quote } } - //vp = "(?:\\w|\\d)+(?:-|\\w|\\d+)*"; // multiple words (letters and digits) separated by dash, WITHOUT any spaces between words . Used ialso for transaction isolation - //var_patterns.push_back(vp); -// for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { -// string s = *it + vp + *it; -// var_patterns.push_back(s); // add with quote -// } vp = "\\w+(?:,\\w+)+"; // multiple words separated by commas, WITHOUT any spaces between words // NOTE: we do not use multiple words without quotes @@ -268,7 +239,6 @@ void SetParser::generateRE_parse1v2() { vp = "(?:| *(?:\\+|\\-) *)\\d+(?:|\\.\\d+)"; // a signed or unsigned integer or decimal , N7 = merge of N3 and N6 var_patterns.push_back(vp); - { // time_zone in numeric format: // - +/- sign @@ -297,8 +267,6 @@ void SetParser::generateRE_parse1v2() { var_patterns.push_back(s); // add with quote } - - string var_value = "("; for (auto it = var_patterns.begin(); it != var_patterns.end(); it++) { string s = "(?:" + *it + ")"; @@ -317,9 +285,6 @@ void SetParser::generateRE_parse1v2() { parse1v2_opt2->set_case_sensitive(false); parse1v2_opt2->set_longest_match(false); - - - string var_1_0 = "(?:@\\w+|\\w+)"; // @name|name string var_1 = "(" + var_1_0 + "|`" + var_1_0 + "`)"; // var_1_0|`var_1_0` var_1 = SESSION_P1 + var_1; @@ -328,9 +293,6 @@ void SetParser::generateRE_parse1v2() { string name_value = "("; for (auto it = quote_symbol.begin(); it != quote_symbol.end(); it++) { string s = "(?:" + *it + charset_name + *it + ")"; - //auto it2 = it; - //it2++; - //if (it2 != quote_symbol.end()) s += "|"; name_value += s; } @@ -344,22 +306,7 @@ void SetParser::generateRE_parse1v2() { } #endif -#ifdef PARSERDEBUG -// delete opt2; -// return result; -#endif - -/* -#define QUOTES "(?:'|\"|`)?" -#define SPACES " *" -#define NAMES "(NAMES)" -#define NAME_VALUE "((?:\\w|\\d)+)" -*/ - - - //const std::string pattern="(?:" NAMES SPACES QUOTES NAME_VALUE QUOTES "(?: +COLLATE +" QUOTES NAME_VALUE QUOTES "|)" "|" SESSION_P1 VAR_P1 SPACES "(?:|:)=" SPACES QUOTES VAR_VALUE_P1 QUOTES ") *,? *"; const std::string pattern="(?:" NAMES SPACES + name_value + "(?: +COLLATE +" + name_value + "|)" "|" + var_1 + SPACES "(?:|:)=" SPACES + var_value + ") *,? *"; - //const std::string pattern=var_1 + SPACES "(?:|:)=" SPACES + var_value; #ifdef DEBUG VALGRIND_DISABLE_ERROR_REPORTING; #endif // DEBUG @@ -368,7 +315,6 @@ VALGRIND_DISABLE_ERROR_REPORTING; cout << pattern << endl; } #endif - //re2::RE2 re(pattern, *opt2); parse1v2_pattern = pattern; parse1v2_re = new re2::RE2(parse1v2_pattern, *parse1v2_opt2); parse1v2_init = true; @@ -460,16 +406,8 @@ std::map> SetParser::parse2() { std::map> result; -// regex used: -// SET(?: +)(|SESSION +)TRANSACTION(?: +)(?:(?:(ISOLATION(?: +)LEVEL)(?: +)(REPEATABLE(?: +)READ|READ(?: +)COMMITTED|READ(?: +)UNCOMMITTED|SERIALIZABLE))|(?:(READ)(?: +)(WRITE|ONLY))) -/* -#define SESSION_P2 "(|SESSION)" -#define VAR_P2 "(ISOLATION LEVEL|READ)" -//#define VAR_VALUE "((?:[\\w/\\d:\\+\\-]|,)+)" -//#define VAR_VALUE "((?:CONCAT\\((?:(REPLACE|CONCAT)\\()+@@sql_mode,(?:(?:'|\\w|,| |\"|\\))+(?:\\)))|(?:[@\\w/\\d:\\+\\-]|,)+|(?:)))" -#define VAR_VALUE_P2 "(((?:CONCAT\\()*(?:((?: )*REPLACE|IFNULL|CONCAT)\\()+(?: )*(?:NULL|@OLD_SQL_MODE|@@sql_mode),(?:(?:'|\\w|,| |\"|\\))+(?:\\))*)|(?:[@\\w/\\d:\\+\\-]|,)+|(?:)))" -*/ - //const std::string pattern="(?:" NAMES SPACES QUOTES NAME_VALUE QUOTES "(?: +COLLATE +" QUOTES NAME_VALUE QUOTES "|)" "|" SESSION_P1 VAR_P1 SPACES "(?:|:)=" SPACES QUOTES VAR_VALUE_P1 QUOTES ") *,? *"; + // Regex used: + // SET(?: +)(|SESSION +)TRANSACTION(?: +)(?:(?:(ISOLATION(?: +)LEVEL)(?: +)(REPEATABLE(?: +)READ|READ(?: +)COMMITTED|READ(?: +)UNCOMMITTED|SERIALIZABLE))|(?:(READ)(?: +)(WRITE|ONLY))) const std::string pattern="(|SESSION) *TRANSACTION(?: +)(?:(?:(ISOLATION(?: +)LEVEL)(?: +)(REPEATABLE(?: +)READ|READ(?: +)COMMITTED|READ(?: +)UNCOMMITTED|SERIALIZABLE))|(?:(READ)(?: +)(WRITE|ONLY)))"; re2::RE2 re(pattern, *opt2); std::string var;