Repository: sysown/proxysql (language: cpp)

Issue:
FR: Port 'v1.4.14-show-warnings' branch into v2.1.1 and add new mysql-variable to control it
- [x] A clear description of the issue

Branch 'v1.4.14-show-warnings' should be ported into v2.1.1 together with a mysql-variable that allows enabling / disabling it. This variable should be 'false' by default.

- [x] ProxySQL version

- v2.1.1


Discussion / hints:

Fix patch:
diff --git a/include/MySQL_Thread.h b/include/MySQL_Thread.h
index 5295300aa8..5b40f09047 100644
--- a/include/MySQL_Thread.h
+++ b/include/MySQL_Thread.h
@@ -515,6 +515,7 @@ class MySQL_Threads_Handler
 		bool client_session_track_gtid;
 		bool enable_client_deprecate_eof;
 		bool enable_server_deprecate_eof;
+		bool log_mysql_warnings_enabled;
 	} variables;
 	struct {
 		unsigned int mirror_sessions_current;
diff --git a/include/proxysql_structs.h b/include/proxysql_structs.h
index 3a9762bdf9..ab93fc863b 100644
--- a/include/proxysql_structs.h
+++ b/include/proxysql_structs.h
@@ -197,6 +197,7 @@ enum session_status {
 	SETTING_VARIABLE,
 	SETTING_MULTIPLE_VARIABLES,
 	SETTING_SET_NAMES,
+	SHOW_WARNINGS,
 	session_status___NONE // special marker
 };
 
@@ -793,6 +794,7 @@ __thread char * mysql_thread___default_variables[SQL_NAME_LAST];
 __thread int mysql_thread___query_digests_grouping_limit;
 __thread bool mysql_thread___enable_client_deprecate_eof;
 __thread bool mysql_thread___enable_server_deprecate_eof;
+__thread bool mysql_thread___log_mysql_warnings_enabled;
 
 /* variables used for Query Cache */
 __thread int mysql_thread___query_cache_size_MB;
@@ -944,6 +946,7 @@ extern __thread char * mysql_thread___default_variables[SQL_NAME_LAST];
 extern __thread int mysql_thread___query_digests_grouping_limit;
 extern __thread bool mysql_thread___enable_client_deprecate_eof;
 extern __thread bool mysql_thread___enable_server_deprecate_eof;
+extern __thread bool mysql_thread___log_mysql_warnings_enabled;
 
 /* variables used for Query Cache */
 extern __thread int mysql_thread___query_cache_size_MB;
diff --git a/lib/MySQL_Session.cpp b/lib/MySQL_Session.cpp
index fad92a13a3..e576e25c12 100644
--- a/lib/MySQL_Session.cpp
+++ b/lib/MySQL_Session.cpp
@@ -4464,6 +4464,16 @@ int MySQL_Session::handler() {
 							assert(0);
 							break;
 					}
+
+					if (mysql_thread___log_mysql_warnings_enabled) {
+						auto warn_no = mysql_warning_count(myconn->mysql);
+						if (warn_no > 0) {
+							myconn->async_state_machine=ASYNC_IDLE;
+							myds->DSS=STATE_MARIADB_GENERIC;
+							NEXT_IMMEDIATE(SHOW_WARNINGS);
+						}
+					}
+
 					RequestEnd(myds);
 					finishQuery(myds,myconn,prepared_stmt_with_no_params);
 				} else {
@@ -4562,6 +4572,33 @@ int MySQL_Session::handler() {
 			}
 			break;
 
+		case SHOW_WARNINGS:
+			{
+				MySQL_Data_Stream *myds=mybe->server_myds;
+				MySQL_Connection *myconn=myds->myconn;
+				int pre_rc = myconn->async_query(mybe->server_myds->revents,(char *)"show warnings", strlen((char *)"show warnings"));
+				if (pre_rc==0) {
+					int myerr=mysql_errno(myconn->mysql);
+
+					RequestEnd(myds);
+					writeout();
+
+					handler_ret = 0;
+					return handler_ret;
+					if ( myerr > 0 ) {
+						char sqlstate[10];
+						sprintf(sqlstate,"%s",mysql_sqlstate(mybe->server_myds->myconn->mysql));
+						RequestEnd(mybe->server_myds);
+						break;
+					}
+					mybe->server_myds->myconn->async_free_result();
+					NEXT_IMMEDIATE(PROCESSING_QUERY);
+				} else {
+					goto handler_again;
+				}
+			}
+			break;
+
 		case CONNECTING_SERVER:
 			{
 				int rc=0;
diff --git a/lib/MySQL_Thread.cpp b/lib/MySQL_Thread.cpp
index fb0b70c860..605eabd27a 100644
--- a/lib/MySQL_Thread.cpp
+++ b/lib/MySQL_Thread.cpp
@@ -439,6 +439,7 @@ static char * mysql_thread_variables_names[]= {
 	(char *)"have_compress",
 	(char *)"client_found_rows",
 	(char *)"interfaces",
+	(char *)"log_mysql_warnings_enabled",
 	(char *)"monitor_enabled",
 	(char *)"monitor_history",
 	(char *)"monitor_connect_interval",
@@ -1160,6 +1161,7 @@ MySQL_Threads_Handler::MySQL_Threads_Handler() {
 	variables.query_digests_grouping_limit = 3;
 	variables.enable_client_deprecate_eof=true;
 	variables.enable_server_deprecate_eof=true;
+	variables.log_mysql_warnings_enabled=false;
 	// status variables
 	status_variables.mirror_sessions_current=0;
 	__global_MySQL_Thread_Variables_version=1;
@@ -1484,6 +1486,7 @@ int MySQL_Threads_Handler::get_variable_int(const char *name) {
 		case 'l':
 			if (!strcmp(name,"long_query_time")) return (int)variables.long_query_time;
 			if (!strcmp(name,"log_unhealthy_connections")) return (int)variables.log_unhealthy_connections;
+			if (!strcmp(name,"log_mysql_warnings_enabled")) return (int)variables.log_mysql_warnings_enabled;
 			break;
 		case 'm':
 			if (name[3]=='_') {
@@ -1902,6 +1905,9 @@ char * MySQL_Threads_Handler::get_variable(char *name) {	// this is the public f
 	if (!strcasecmp(name,"enable_server_deprecate_eof")) {
 		return strdup((variables.enable_server_deprecate_eof ? "true" : "false"));
 	}
+	if (!strcasecmp(name,"log_mysql_warnings_enabled")) {
+		return strdup((variables.log_mysql_warnings_enabled? "true" : "false"));
+	}
 	if (!strcasecmp(name,"throttle_connections_per_sec_to_hostgroup")) {
 		sprintf(intbuf,"%d",variables.throttle_connections_per_sec_to_hostgroup);
 		return strdup(intbuf);
@@ -3599,6 +3605,17 @@ bool MySQL_Threads_Handler::set_variable(char *name, const char *value) {	// thi
 		}
 		return false;
 	}
+	if (!strcasecmp(name,"log_mysql_warnings_enabled")) {
+		if (strcasecmp(value,"true")==0 || strcasecmp(value,"1")==0) {
+			variables.log_mysql_warnings_enabled=true;
+			return true;
+		}
+		if (strcasecmp(value,"false")==0 || strcasecmp(value,"0")==0) {
+			variables.log_mysql_warnings_enabled=false;
+			return true;
+		}
+		return false;
+	}
 	return false;
 }
 
@@ -5098,6 +5115,7 @@ void MySQL_Thread::refresh_variables() {
 	mysql_thread___default_reconnect=(bool)GloMTH->get_variable_int((char *)"default_reconnect");
 	mysql_thread___enable_client_deprecate_eof=(bool)GloMTH->get_variable_int((char *)"enable_client_deprecate_eof");
 	mysql_thread___enable_server_deprecate_eof=(bool)GloMTH->get_variable_int((char *)"enable_server_deprecate_eof");
+	mysql_thread___log_mysql_warnings_enabled=(bool)GloMTH->get_variable_int((char *)"log_mysql_warnings_enabled");
 #ifdef DEBUG
 	mysql_thread___session_debug=(bool)GloMTH->get_variable_int((char *)"session_debug");
 #endif /* DEBUG */
diff --git a/lib/mysql_connection.cpp b/lib/mysql_connection.cpp
index 54697b229d..0e72ac60f1 100644
--- a/lib/mysql_connection.cpp
+++ b/lib/mysql_connection.cpp
@@ -1420,6 +1420,9 @@ MDB_ASYNC_ST MySQL_Connection::handler(short event) {
 			} else {
 				async_fetch_row_start=false;
 				if (mysql_row) {
+					if (myds && myds->sess && myds->sess->status == SHOW_WARNINGS) {
+						proxy_warning("MySQL Warning. Level: [%s], Code: [%s], Message: [%s]\n", mysql_row[0], mysql_row[1], mysql_row[2]);
+					}
 					unsigned int br=MyRS->add_row(mysql_row);
 					__sync_fetch_and_add(&parent->bytes_recv,br);
 					myds->sess->thread->status_variables.stvar[st_var_queries_backends_bytes_recv]+=br;


Test patch: