diff --git a/lib/set_parser.cpp b/lib/set_parser.cpp index 335217c0d..ce2197b30 100644 --- a/lib/set_parser.cpp +++ b/lib/set_parser.cpp @@ -137,7 +137,7 @@ std::string SetParser::parse_character_set() { std::map> result; - const string pattern="((charset)|(character +set))(?: )(\\S+)"; + const string pattern="((charset)|(character +set))(?: )(?:'?)([^'|\\s]*)(?:'?)"; re2::RE2 re(pattern, *opt2); string var; string value1, value2, value3, value4; diff --git a/test/tap/tests/set_testing-t.cpp b/test/tap/tests/set_testing-t.cpp index a681ef9a9..3abcbe040 100644 --- a/test/tap/tests/set_testing-t.cpp +++ b/test/tap/tests/set_testing-t.cpp @@ -1,3 +1,13 @@ +/** + * @file set_testing-t.cpp + * @brief This file tests multiple settings combinations for MySQL variables, and checks that they are + * actually being tracked correctly. + * @details The test input is a 'csv' file with name 'set_testing-t.csv'. The file format consists in + * two primary columns which specifies the variables to set (first) and the expected result of setting + * those variables (second), and an optional third column which hold variables that shouldn't be checked + * anymore after the 'SET STATEMENTS' from the same line are executed. + */ + #include #include #include @@ -35,6 +45,7 @@ using nlohmann::json; struct TestCase { std::string command; json expected_vars; + json reset_vars; }; std::vector testCases; @@ -45,18 +56,27 @@ int readTestCases(const std::string& fileName) { FILE* fp = fopen(fileName.c_str(), "r"); if (!fp) return 0; - char buf[MAX_LINE], col1[MAX_LINE], col2[MAX_LINE]; + char buf[MAX_LINE], col1[MAX_LINE], col2[MAX_LINE], col3[MAX_LINE] = {0}; int n = 0; for(;;) { if (fgets(buf, sizeof(buf), fp) == NULL) break; - n = sscanf(buf, " \"%[^\"]\", \"%[^\"]\"", col1, col2); + n = sscanf(buf, " \"%[^\"]\", \"%[^\"]\", \"%[^\"]\"", col1, col2, col3); if (n == 0) break; char *p = col2; while(*p++) if(*p == '\'') *p = '\"'; json vars = json::parse(col2); - testCases.push_back({col1, vars}); + + p = col3; + while(col3[0] != 0 && *p++) if(*p == '\'') *p = '\"'; + + json reset_vars; + if (p != col3) { + reset_vars = json::parse(col3); + } + + testCases.push_back({col1, vars, reset_vars}); } fclose(fp); @@ -363,6 +383,8 @@ void queryInternalStatus(MYSQL *mysql, json& j) { } } +std::vector forgotten_vars {}; + void * my_conn_thread(void *arg) { g_seed = time(NULL) ^ getpid() ^ pthread_self(); unsigned int select_OK=0; @@ -488,12 +510,24 @@ void * my_conn_thread(void *arg) { json proxysql_vars; queryInternalStatus(mysql, proxysql_vars); + if (!testCases[r2].reset_vars.empty()) { + for (const auto& var : testCases[r2].reset_vars) { + if (std::find(forgotten_vars.begin(), forgotten_vars.end(), var) == forgotten_vars.end()) { + forgotten_vars.push_back(var); + } + } + } + bool testPassed = true; int variables_tested = 0; for (auto& el : vars.items()) { auto k = mysql_vars.find(el.key()); auto s = proxysql_vars["conn"].find(el.key()); + if (std::find(forgotten_vars.begin(), forgotten_vars.end(), el.key()) != forgotten_vars.end()) { + continue; + } + if (k == mysql_vars.end()) fprintf(stderr, "Variable %s->%s in mysql resultset was not found.\nmysql data : %s\nproxysql data: %s\ncsv data %s\n", el.value().dump().c_str(), el.key().c_str(), mysql_vars.dump().c_str(), proxysql_vars.dump().c_str(), vars.dump().c_str()); diff --git a/test/tap/tests/set_testing-t.csv b/test/tap/tests/set_testing-t.csv index beccbd8e3..4882048ec 100644 --- a/test/tap/tests/set_testing-t.csv +++ b/test/tap/tests/set_testing-t.csv @@ -63,3 +63,19 @@ "set wsrep_sync_wait=0", "{'wsrep_sync_wait':'0'}" "set group_concat_max_len=2048", "{'group_concat_max_len':'2048'}" "set group_concat_max_len=4096", "{'group_concat_max_len':'4096'}" +"set tx_isolation='READ-COMMITTED', group_concat_max_len=4096", "{'transaction_isolation':'READ-COMMITTED', 'group_concat_max_len':'4096'}" +"set tx_isolation='READ-COMMITTED', group_concat_max_len=2048, net_write_timeout=30", "{'transaction_isolation':'READ-COMMITTED', 'group_concat_max_len':'2048', 'net_write_timeout':'30'}" +"SET character_set_database='utf8mb4', max_join_size=10000; ", "{'character_set_database':'utf8mb4', 'max_join_size':'10000'}" +"SET character_set_database='utf8mb4', max_join_size=10000, session_track_gtids=OWN_GTID; ", "{'character_set_database':'utf8mb4', 'max_join_size':'10000', 'session_track_gtids':'OWN_GTID'}" +"SET sql_select_limit=3030, session_track_gtids=OWN_GTID; SET max_join_size=10000; ", "{'sql_select_limit':'3030', 'max_join_size':'10000', 'session_track_gtids':'OWN_GTID'}" +"SET sql_mode='NO_ENGINE_SUBSTITUTION', sql_select_limit=3030, session_track_gtids=OWN_GTID; SET max_join_size=10000; ", "{'sql_mode':'NO_ENGINE_SUBSTITUTION','sql_select_limit':'3030', 'max_join_size':'10000', 'session_track_gtids':'OWN_GTID'}" +"SET character_set_client='utf8', sql_select_limit=3030, max_join_size=18446744073709551615", "{'character_set_client':'utf8', 'sql_select_limit':'3030', 'max_join_size':'18446744073709551615'}" +"SET sql_select_limit=3030, character_set_client='latin1', max_join_size=10000", "{'sql_select_limit':'3030', 'character_set_client':'latin1', 'max_join_size':'10000'}" +"SET session_track_gtids=OFF", "{'session_track_gtids':'OFF'}" +"SET time_zone='+04:00', sql_mode='NO_ENGINE_SUBSTITUTION', character_set_client='latin1', max_join_size=10000", "{'time_zone':'+04:00', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'character_set_client':'latin1', 'max_join_size':'10000'}" +"SET character_set_results='binary', sql_mode='NO_ENGINE_SUBSTITUTION', character_set_client='latin1', max_join_size=10000", "{'character_set_results':'binary', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'character_set_client':'latin1', 'max_join_size':'10000'}" +"SET character_set_results='binary', max_join_size=10000, sql_mode='NO_ENGINE_SUBSTITUTION', character_set_client='latin1'; ", "{'character_set_results':'binary', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'character_set_client':'latin1', 'max_join_size':'10000'}" +"SET CHARACTER SET utf8", "{'character_set_results':'utf8', 'character_set_client':'utf8'}", "['character_set_connection', 'collation_connection']" +"SET CHARACTER SET 'utf8'", "{'character_set_results':'utf8', 'character_set_client':'utf8'}", "['character_set_connection', 'collation_connection']" +"SET time_zone='+04:00', sql_mode='NO_ENGINE_SUBSTITUTION', max_join_size=10000; SET CHARACTER SET 'latin1'", "{'time_zone':'+04:00', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'max_join_size':'10000', 'character_set_results':'latin1', 'character_set_client':'latin1'}", "['character_set_connection', 'collation_connection']" +"SET time_zone='+04:00', sql_mode='NO_ENGINE_SUBSTITUTION', max_join_size=10000; SET CHARSET 'latin1'", "{'time_zone':'+04:00', 'sql_mode':'NO_ENGINE_SUBSTITUTION', 'max_join_size':'10000', 'character_set_results':'latin1', 'character_set_client':'latin1'}", "['character_set_connection', 'collation_connection']"