From 215625b14300c50c99682c47af25a10eab1bce7e Mon Sep 17 00:00:00 2001
From: unknown <anozdrin/alik@quad.>
Date: Tue, 12 Feb 2008 20:59:09 +0300
Subject: [PATCH] Fix for Bug#31222: com_% global status counters behave
 randomly with mysql_change_user.

The problem was that global status variables were not updated
in THD::check_user(), so thread statistics were lost after
COM_CHANGE_USER.

The fix is to update global status variables with the thread ones
before preparing the thread for new user.


mysql-test/r/change_user.result:
  Update result file.
mysql-test/t/change_user.test:
  Add a test case for Bug#31222: com_% global status counters
  behave randomly with mysql_change_user.
sql/sql_class.cc:
  Update global status variables when we're handling
  COM_CHANGE_USER for a thread.
---
 mysql-test/r/change_user.result |  7 +++++++
 mysql-test/t/change_user.test   | 28 ++++++++++++++++++++++++++++
 sql/sql_class.cc                |  4 ++++
 3 files changed, 39 insertions(+)

diff --git a/mysql-test/r/change_user.result b/mysql-test/r/change_user.result
index 28b55dfd5e..4cfaf0e90e 100644
--- a/mysql-test/r/change_user.result
+++ b/mysql-test/r/change_user.result
@@ -44,3 +44,10 @@ IS_FREE_LOCK('bug31418')
 SELECT IS_USED_LOCK('bug31418');
 IS_USED_LOCK('bug31418')
 NULL
+FLUSH STATUS;
+SHOW GLOBAL STATUS LIKE 'com_select';
+Variable_name	Value
+Com_select	112
+SHOW GLOBAL STATUS LIKE 'com_select';
+Variable_name	Value
+Com_select	112
diff --git a/mysql-test/t/change_user.test b/mysql-test/t/change_user.test
index d0cdfc8a74..eec2a6f39d 100644
--- a/mysql-test/t/change_user.test
+++ b/mysql-test/t/change_user.test
@@ -33,3 +33,31 @@ SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID();
 --change_user
 SELECT IS_FREE_LOCK('bug31418');
 SELECT IS_USED_LOCK('bug31418');
+
+#
+# Bug#31222: com_% global status counters behave randomly with
+# mysql_change_user.
+#
+
+FLUSH STATUS;
+
+--disable_result_log
+--disable_query_log
+
+let $i = 100;
+
+while ($i)
+{
+  dec $i;
+
+  SELECT 1;
+}
+
+--enable_query_log
+--enable_result_log
+
+SHOW GLOBAL STATUS LIKE 'com_select';
+
+--change_user
+
+SHOW GLOBAL STATUS LIKE 'com_select';
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5180cafc77..5bdde06657 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -769,6 +769,10 @@ void THD::init_for_queries()
 
 void THD::change_user(void)
 {
+  pthread_mutex_lock(&LOCK_status);
+  add_to_status(&global_status_var, &status_var);
+  pthread_mutex_unlock(&LOCK_status);
+
   cleanup();
   killed= NOT_KILLED;
   cleanup_done= 0;
-- 
2.30.9