From 062381efd4fbe1a907d4a74354ff85a9da7e9004 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 12 Oct 2021 15:40:51 +0200 Subject: [PATCH 1/4] Fixed crashes in 'MySQL_Session::get_pkts_from_client' when 'mysql-query_digests' are disabled #3655 --- lib/MySQL_Session.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 82a14fb1c..3113b5c7b 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -3539,15 +3539,27 @@ __get_pkts_from_client: // =================================================== if (session_type != PROXYSQL_SESSION_CLICKHOUSE) { const char *qd = CurrentQuery.get_digest_text(); - if ( - (strncasecmp((char *)"USE",qd,3)==0) - && - ( - (strncasecmp((char *)"USE ",qd,4)==0) - || - (strncasecmp((char *)"USE`",qd,4)==0) - ) - ) { + bool use_db_query = false; + + if (qd != NULL) { + if ( + (strncasecmp((char *)"USE",qd,3)==0) + && + ( + (strncasecmp((char *)"USE ",qd,4)==0) + || + (strncasecmp((char *)"USE`",qd,4)==0) + ) + ) { + use_db_query = true; + } + } else { + if (pkt.size > (5+4) && strncasecmp((char *)"USE ", (char *)pkt.ptr+5, 4) == 0) { + use_db_query = true; + } + } + + if (use_db_query) { handler___status_WAITING_CLIENT_DATA___STATE_SLEEP___MYSQL_COM_QUERY_USE_DB(&pkt); if (mirror == false) { From 9d33b56a3b3157732b216e9d626312c67abf0037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Tue, 12 Oct 2021 15:42:08 +0200 Subject: [PATCH 2/4] Performed some changes to 'USE_with_comment' test for checking behavior when 'mysql-query_digests' is 'false' #3655 --- .../reg_test_3493-USE_with_comment-t.cpp | 144 +++++++++++------- 1 file changed, 85 insertions(+), 59 deletions(-) diff --git a/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp b/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp index 79c89f0e8..8116f94eb 100644 --- a/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp +++ b/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp @@ -6,12 +6,15 @@ * test performs the following actions: * * 1. Open a MYSQL connection to ProxySQL. - * 2. Drops and creates a new database called 'reg_test_3493_use_comment'. - * 3. Checks the currently selected database in **a new backend database - * connection** by means of the connection annotation - * "create_new_connection=1". This way it's ensured that ProxySQL is - * properly keeping track of the database selected in the issued 'USE' - * statement. + * 2. Drops and creates multiple databases called 'reg_test_3493_use_comment-N'. + * 3. Performs a 'USE' statement in the connection. + * 3. Checks the currently selected database in **a new backend database connection** by means of the + * connection annotation "create_new_connection=1". This way it's ensured that ProxySQL is properly keeping + * track of the database selected in the issued 'USE' statement. + * 4. Perform the exact same test with 'mysql-query_digests=0'. This just ensures that ProxySQL is properly + * executing the 'USE' statement in the backend connection, tracking MAY not be perform, depending on + * whether the query fails to be parsed or not, but since 'create_new_connection' annotation shouldn't have + * any effect, queries will be executed in the same backend connection, and thus, test should succeed. */ #include @@ -40,57 +43,7 @@ void parse_result_json_column(MYSQL_RES *result, json& j) { std::vector> db_query; -int main(int argc, char** argv) { - CommandLine cl; - - if (cl.getEnv()) { - diag("Failed to get the required environmental variables."); - return -1; - } - - MYSQL* proxysql_mysql = mysql_init(NULL); - - db_query.push_back(std::make_pair("reg_test_3493_use_comment", "/*+ placeholder_comment */ USE reg_test_3493_use_comment")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-a1`", "USE /*+ placeholder_comment */ `reg_test_3493_use_comment-a1`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_1", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment_1`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_2", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment_2`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_3", "USE /*+ placeholder_comment */`reg_test_3493_use_comment_3`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_4", " USE /*+ placeholder_comment */ reg_test_3493_use_comment_4")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_5", "USE/*+ placeholder_comment */ reg_test_3493_use_comment_5")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_6", "USE /*+ placeholder_comment */reg_test_3493_use_comment_6")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-1`", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment-1`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-2`", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment-2`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-3`", "USE /*+ placeholder_comment */`reg_test_3493_use_comment-3`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-4`", "/*+ placeholder_comment */USE `reg_test_3493_use_comment-4`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-5`", "USE/*+ placeholder_comment */`reg_test_3493_use_comment-5`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-6`", "/* comment */USE`reg_test_3493_use_comment-6`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-7`", "USE`reg_test_3493_use_comment-7`")); - - plan(db_query.size()); - - if ( - !mysql_real_connect( - proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0 - ) - ) { - fprintf( - stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, - mysql_error(proxysql_mysql) - ); - return EXIT_FAILURE; - } - - // Prepare the DB for the test - for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { - // MYSQL_QUERY(proxysql_mysql, "DROP DATABASE IF EXISTS reg_test_3493_use_comment"); - // MYSQL_QUERY(proxysql_mysql, "CREATE DATABASE reg_test_3493_use_comment"); - std::string s = ""; - s = "DROP DATABASE IF EXISTS " + it->first; - MYSQL_QUERY(proxysql_mysql, s.c_str()); - s = "CREATE DATABASE " + it->first; - MYSQL_QUERY(proxysql_mysql, s.c_str()); - } - +int test_use_queries(MYSQL* proxysql_mysql) { for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { int i = 0; int err = mysql_query(proxysql_mysql, it->second.c_str()); @@ -130,14 +83,13 @@ int main(int argc, char** argv) { diag("Invalid 'MYSQL_RES' returned from 'SELECT DATABASE()'"); return EXIT_FAILURE; } - MYSQL_ROW row = mysql_fetch_row(result); if (row == nullptr) { diag("Invalid 'MYSQL_ROW' returned from 'SELECT DATABASE()'"); return EXIT_FAILURE; } - std::string database_name { row[0] }; + mysql_free_result(result); if (it->first[0] == '`') { database_name = "`" + database_name + "`"; @@ -150,6 +102,79 @@ int main(int argc, char** argv) { ); } + return EXIT_SUCCESS; +} + +int main(int argc, char** argv) { + CommandLine cl; + + if (cl.getEnv()) { + diag("Failed to get the required environmental variables."); + return -1; + } + + MYSQL* proxysql_mysql = mysql_init(NULL); + + db_query.push_back(std::make_pair("reg_test_3493_use_comment", "/*+ placeholder_comment */ USE reg_test_3493_use_comment")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-a1`", "USE /*+ placeholder_comment */ `reg_test_3493_use_comment-a1`")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_1", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment_1`")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_2", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment_2`")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_3", "USE /*+ placeholder_comment */`reg_test_3493_use_comment_3`")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_4", " USE /*+ placeholder_comment */ reg_test_3493_use_comment_4")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_5", "USE/*+ placeholder_comment */ reg_test_3493_use_comment_5")); + db_query.push_back(std::make_pair("reg_test_3493_use_comment_6", "USE /*+ placeholder_comment */reg_test_3493_use_comment_6")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-1`", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment-1`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-2`", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment-2`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-3`", "USE /*+ placeholder_comment */`reg_test_3493_use_comment-3`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-4`", "/*+ placeholder_comment */USE `reg_test_3493_use_comment-4`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-5`", "USE/*+ placeholder_comment */`reg_test_3493_use_comment-5`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-6`", "/* comment */USE`reg_test_3493_use_comment-6`")); + db_query.push_back(std::make_pair("`reg_test_3493_use_comment-7`", "USE`reg_test_3493_use_comment-7`")); + + plan(db_query.size() * 2); + + if ( + !mysql_real_connect( + proxysql_mysql, cl.host, cl.username, cl.password, NULL, cl.port, NULL, 0 + ) + ) { + fprintf( + stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, + mysql_error(proxysql_mysql) + ); + return EXIT_FAILURE; + } + + MYSQL* proxysql_admin = mysql_init(NULL); + if (!proxysql_admin) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return EXIT_FAILURE; + } + + if (!mysql_real_connect(proxysql_admin, cl.host, cl.admin_username, cl.admin_password, NULL, cl.admin_port, NULL, 0)) { + fprintf(stderr, "File %s, line %d, Error: %s\n", __FILE__, __LINE__, mysql_error(proxysql_admin)); + return EXIT_FAILURE; + } + + // Prepare the DB for the test + for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + std::string s = ""; + s = "DROP DATABASE IF EXISTS " + it->first; + MYSQL_QUERY(proxysql_mysql, s.c_str()); + s = "CREATE DATABASE " + it->first; + MYSQL_QUERY(proxysql_mysql, s.c_str()); + } + + MYSQL_QUERY(proxysql_admin, "SET mysql-query_digests='true'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + // Check 'USE' statements are being properly parsed and tracked when 'mysql-query_digests' is 'ENABLED'. + test_use_queries(proxysql_mysql); + + MYSQL_QUERY(proxysql_admin, "SET mysql-query_digests='false'"); + MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); + // Check 'USE' statements are being properly executed when 'mysql-query_digests' is 'DISABLED'. + test_use_queries(proxysql_mysql); + // Drop created database for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { std::string s = ""; @@ -157,6 +182,7 @@ int main(int argc, char** argv) { MYSQL_QUERY(proxysql_mysql, s.c_str()); } mysql_close(proxysql_mysql); + mysql_close(proxysql_admin); return exit_status(); } From dc4bf3cccea80b4a15d18decea23703fe26c9309 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 18 Oct 2021 13:11:22 +0200 Subject: [PATCH 3/4] Added 'schemaname' to userinfo for 'PROXYSQL INTERNAL SESSION' command #3655 --- lib/MySQL_Session.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp index 3113b5c7b..7d9559001 100644 --- a/lib/MySQL_Session.cpp +++ b/lib/MySQL_Session.cpp @@ -960,6 +960,7 @@ void MySQL_Session::generate_proxysql_internal_session_json(json &j) { j["qpo"]["retries"] = qpo->retries; j["qpo"]["max_lag_ms"] = qpo->max_lag_ms; j["client"]["userinfo"]["username"] = ( client_myds->myconn->userinfo->username ? client_myds->myconn->userinfo->username : "" ); + j["client"]["userinfo"]["schemaname"] = ( client_myds->myconn->userinfo->schemaname ? client_myds->myconn->userinfo->schemaname : "" ); #ifdef DEBUG j["client"]["userinfo"]["password"] = ( client_myds->myconn->userinfo->password ? client_myds->myconn->userinfo->password : "" ); #endif From 03ae9dea641ac1a26ce63eadb0ac8050f5b8f8e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20Jaramago=20Fern=C3=A1ndez?= Date: Mon, 18 Oct 2021 13:14:44 +0200 Subject: [PATCH 4/4] Improved test logic including when 'schemaname' should differ from 'SELECT DATABASE()' for 'mysql-query_digests=0' #3655 --- .../reg_test_3493-USE_with_comment-t.cpp | 143 +++++++++++++----- 1 file changed, 104 insertions(+), 39 deletions(-) diff --git a/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp b/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp index 8116f94eb..1e45ca19a 100644 --- a/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp +++ b/test/tap/tests/reg_test_3493-USE_with_comment-t.cpp @@ -10,11 +10,12 @@ * 3. Performs a 'USE' statement in the connection. * 3. Checks the currently selected database in **a new backend database connection** by means of the * connection annotation "create_new_connection=1". This way it's ensured that ProxySQL is properly keeping - * track of the database selected in the issued 'USE' statement. + * track of the database selected in the issued 'USE' statement via 'PROXYSQL INTERNAL SESSION'. * 4. Perform the exact same test with 'mysql-query_digests=0'. This just ensures that ProxySQL is properly - * executing the 'USE' statement in the backend connection, tracking MAY not be perform, depending on - * whether the query fails to be parsed or not, but since 'create_new_connection' annotation shouldn't have - * any effect, queries will be executed in the same backend connection, and thus, test should succeed. + * executing the 'USE' statement in the backend connection, expected tracking failures are verified for + * the listed cases, since 'create_new_connection' annotation shouldn't have any effect, queries will be + * executed in the same backend connection, because of this, 'SELECT DATABASE()' should still return the + * same database as specified via 'USE' statement. */ #include @@ -41,16 +42,45 @@ void parse_result_json_column(MYSQL_RES *result, json& j) { } } -std::vector> db_query; +int get_session_schemaname(MYSQL* proxysql, std::string& schemaname) { + int res = EXIT_FAILURE; -int test_use_queries(MYSQL* proxysql_mysql) { - for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { - int i = 0; - int err = mysql_query(proxysql_mysql, it->second.c_str()); + json j_status; + int query_res = mysql_query(proxysql, "PROXYSQL INTERNAL SESSION"); + if (query_res) { + return query_res; + } + + MYSQL_RES* tr_res = mysql_store_result(proxysql); + parse_result_json_column(tr_res, j_status); + mysql_free_result(tr_res); + + try { + schemaname = j_status["client"]["userinfo"]["schemaname"]; + res = EXIT_SUCCESS; + } catch (const std::exception& e) { + diag("Exception while trying to access 'schemaname' from 'PROXYSQL INTERNAL SESSION': '%s'", e.what()); + res = EXIT_FAILURE; + } + + return res; +} + +std::vector> db_query {}; + +int test_use_queries(MYSQL* proxysql_mysql, bool enabled_digests) { + int i = 0; + + for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + const std::string& name = std::get<0>(*it); + const std::string& query = std::get<1>(*it); + const bool should_match = std::get<2>(*it); + + int err = mysql_query(proxysql_mysql, query.c_str()); if (err) { diag( "'USE' command failed with error code '%d' and error '%s' for query: %s", - err, mysql_error(proxysql_mysql), it->second.c_str() + err, mysql_error(proxysql_mysql), query.c_str() ); return EXIT_FAILURE; } @@ -78,6 +108,7 @@ int test_use_queries(MYSQL* proxysql_mysql) { assert(0); } i++; + MYSQL_RES* result = mysql_store_result(proxysql_mysql); if (result == nullptr) { diag("Invalid 'MYSQL_RES' returned from 'SELECT DATABASE()'"); @@ -91,15 +122,45 @@ int test_use_queries(MYSQL* proxysql_mysql) { std::string database_name { row[0] }; mysql_free_result(result); - if (it->first[0] == '`') { + if (name[0] == '`') { database_name = "`" + database_name + "`"; } - ok( - database_name == it->first, - "Selected DB name should be equal to actual DB name: (Exp: '%s') == (Act: '%s')", - it->first.c_str(), - database_name.c_str() - ); + + std::string cur_tracked_schema {}; + err = get_session_schemaname(proxysql_mysql, cur_tracked_schema); + if (err != EXIT_SUCCESS) { + diag("'get_session_schemaname' failed with error: %d", err); + return EXIT_FAILURE; + } + + if (name[0] == '`') { + cur_tracked_schema = "`" + cur_tracked_schema + "`"; + } + + if (enabled_digests == true) { + ok( + database_name == name && cur_tracked_schema == name, + "Selected and tracked DB names should be equal to actual DB name: " + "(Exp_SEL: '%s') == (Act_SEL: '%s'), (Exp_TRACKED: '%s') == (Act_TRACKED: '%s')", + name.c_str(), database_name.c_str(), name.c_str(), cur_tracked_schema.c_str() + ); + } else { + if (should_match == true) { + ok( + database_name == name && cur_tracked_schema == name, + "Selected and tracked DB names should be equal to actual DB name: " + "(Exp_SEL: '%s') == (Act_SEL: '%s'), (Exp_TRACKED: '%s') == (Act_TRACKED: '%s')", + name.c_str(), database_name.c_str(), name.c_str(), cur_tracked_schema.c_str() + ); + } else { + ok( + database_name == name && cur_tracked_schema != name, + "Selected DB name should be equal to actual DB name, but tracked DB name should differ: " + "(Exp_SEL: '%s') == (Act_SEL: '%s'), (Exp_TRACKED: '%s') == (Act_TRACKED: '%s')", + name.c_str(), database_name.c_str(), name.c_str(), cur_tracked_schema.c_str() + ); + } + } } return EXIT_SUCCESS; @@ -115,21 +176,21 @@ int main(int argc, char** argv) { MYSQL* proxysql_mysql = mysql_init(NULL); - db_query.push_back(std::make_pair("reg_test_3493_use_comment", "/*+ placeholder_comment */ USE reg_test_3493_use_comment")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-a1`", "USE /*+ placeholder_comment */ `reg_test_3493_use_comment-a1`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_1", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment_1`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_2", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment_2`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_3", "USE /*+ placeholder_comment */`reg_test_3493_use_comment_3`")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_4", " USE /*+ placeholder_comment */ reg_test_3493_use_comment_4")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_5", "USE/*+ placeholder_comment */ reg_test_3493_use_comment_5")); - db_query.push_back(std::make_pair("reg_test_3493_use_comment_6", "USE /*+ placeholder_comment */reg_test_3493_use_comment_6")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-1`", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment-1`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-2`", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment-2`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-3`", "USE /*+ placeholder_comment */`reg_test_3493_use_comment-3`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-4`", "/*+ placeholder_comment */USE `reg_test_3493_use_comment-4`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-5`", "USE/*+ placeholder_comment */`reg_test_3493_use_comment-5`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-6`", "/* comment */USE`reg_test_3493_use_comment-6`")); - db_query.push_back(std::make_pair("`reg_test_3493_use_comment-7`", "USE`reg_test_3493_use_comment-7`")); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment", "/*+ placeholder_comment */ USE reg_test_3493_use_comment", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-a1`", "USE /*+ placeholder_comment */ `reg_test_3493_use_comment-a1`", true)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_1", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment_1`", false)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_2", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment_2`", false)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_3", "USE /*+ placeholder_comment */`reg_test_3493_use_comment_3`", true)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_4", " USE /*+ placeholder_comment */ reg_test_3493_use_comment_4", false)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_5", "USE/*+ placeholder_comment */ reg_test_3493_use_comment_5", false)); + db_query.push_back(std::make_tuple("reg_test_3493_use_comment_6", "USE /*+ placeholder_comment */reg_test_3493_use_comment_6", true)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-1`", " USE /*+ placeholder_comment */ `reg_test_3493_use_comment-1`", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-2`", "USE/*+ placeholder_comment */ `reg_test_3493_use_comment-2`", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-3`", "USE /*+ placeholder_comment */`reg_test_3493_use_comment-3`", true)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-4`", "/*+ placeholder_comment */USE `reg_test_3493_use_comment-4`", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-5`", "USE/*+ placeholder_comment */`reg_test_3493_use_comment-5`", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-6`", "/* comment */USE`reg_test_3493_use_comment-6`", false)); + db_query.push_back(std::make_tuple("`reg_test_3493_use_comment-7`", "USE`reg_test_3493_use_comment-7`", false)); plan(db_query.size() * 2); @@ -157,28 +218,32 @@ int main(int argc, char** argv) { } // Prepare the DB for the test - for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + const std::string& name = std::get<0>(*it); + std::string s = ""; - s = "DROP DATABASE IF EXISTS " + it->first; + s = "DROP DATABASE IF EXISTS " + name; MYSQL_QUERY(proxysql_mysql, s.c_str()); - s = "CREATE DATABASE " + it->first; + s = "CREATE DATABASE " + name; MYSQL_QUERY(proxysql_mysql, s.c_str()); } MYSQL_QUERY(proxysql_admin, "SET mysql-query_digests='true'"); MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); // Check 'USE' statements are being properly parsed and tracked when 'mysql-query_digests' is 'ENABLED'. - test_use_queries(proxysql_mysql); + test_use_queries(proxysql_mysql, true); MYSQL_QUERY(proxysql_admin, "SET mysql-query_digests='false'"); MYSQL_QUERY(proxysql_admin, "LOAD MYSQL VARIABLES TO RUNTIME"); // Check 'USE' statements are being properly executed when 'mysql-query_digests' is 'DISABLED'. - test_use_queries(proxysql_mysql); + test_use_queries(proxysql_mysql, false); // Drop created database - for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + for (std::vector>::iterator it = db_query.begin(); it != db_query.end() ; it++) { + const std::string& name = std::get<0>(*it); + std::string s = ""; - s = "DROP DATABASE IF EXISTS " + it->first; + s = "DROP DATABASE IF EXISTS " + name; MYSQL_QUERY(proxysql_mysql, s.c_str()); } mysql_close(proxysql_mysql);