Commit f985e787 authored by Kristofer Pettersson's avatar Kristofer Pettersson

Bug#24289 Status Variable "Questions" gets wrong values with Stored Routines

                 
When running Stored Routines the Status Variable "Questions" was wrongly
incremented. According to the manual it should contain the "number of
statements that clients have sent to the server"
              
Introduced a new status variable 'questions' to replace the query_id
variable which currently corresponds badly with the number of statements
sent by the client.
            
The new behavior is ment to be backward compatible with 4.0 and at the
same time work with new features in a similar way.
            
This is a backport from 6.0

mysql-test/r/status2.result:
  Added test case
mysql-test/t/status2.test:
  Added test case
sql/mysqld.cc:
  Introduced a new status variable 'questions' to replace the query_id
  variable which currently corresponds badly with the number of statements
  sent by the client.
sql/sql_class.h:
  Introduced a new status variable 'questions' to replace the query_id
  variable which currently corresponds badly with the number of statements
  sent by the client.
sql/sql_parse.cc:
  To be backward compatible with 4.0 and at the same time extend the 
  interpretation of the Question variable, it should be increased on
  all COM-commands but COM_STATISTICS, COM_PING, COM_STMT_PREPARE,
  COM_STMT_CLOSE and COM_STMT_RESET.
  Since COM_QUERY can process multiple statements, there has to be an
  extra increase there as well.
sql/sql_show.cc:
  Removed deprecated SHOW_QUESTION status code.
sql/structs.h:
  Removed deprecated SHOW_QUESTION status code.
parent eb3c0806
#
# Bug#24289 Status Variable "Questions" gets wrong values with Stored Routines
#
FLUSH STATUS;
DROP TABLE IF EXISTS t1,t2;
DROP PROCEDURE IF EXISTS p1;
DROP FUNCTION IF EXISTS f1;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
DECLARE foo INTEGER;
DECLARE bar INTEGER;
SET foo=1;
SET bar=2;
RETURN foo;
END $$
CREATE PROCEDURE p1()
BEGIN
SELECT 1;
END $$
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
INSERT INTO t1 VALUES (1);
Assert Questions == 9
SHOW STATUS LIKE 'Questions';
Variable_name Value
Questions 9
SELECT f1();
f1()
1
Assert Questions == 11
SHOW STATUS LIKE 'Questions';
Variable_name Value
Questions 11
CALL p1();
1
1
Assert Questions == 13
SHOW STATUS LIKE 'Questions';
Variable_name Value
Questions 13
SELECT 1;
1
1
Assert Questions == 15
SHOW STATUS LIKE 'Questions';
Variable_name Value
Questions 15
FLUSH STATUS;
SELECT 1;
1
1
Assert Questions == 16
SHOW STATUS LIKE 'Questions';
Variable_name Value
Questions 16
Global status updated; Assert diff == 5
FLUSH STATUS;
SELECT 5;
5
5
DROP TABLE t1,t2;
DROP PROCEDURE p1;
DROP FUNCTION f1;
End of 6.0 tests
--echo #
--echo # Bug#24289 Status Variable "Questions" gets wrong values with Stored Routines
--echo #
# The bogus connection below is needed to make the gobal statement count
# deterministic when the test is run for the first time.
connect (con1,localhost,root,,);
connection con1;
connection default;
disconnect con1;
FLUSH STATUS;
--disable_warnings
DROP TABLE IF EXISTS t1,t2;
DROP PROCEDURE IF EXISTS p1;
DROP FUNCTION IF EXISTS f1;
--enable_warnings
DELIMITER $$;
CREATE FUNCTION f1() RETURNS INTEGER
BEGIN
DECLARE foo INTEGER;
DECLARE bar INTEGER;
SET foo=1;
SET bar=2;
RETURN foo;
END $$
CREATE PROCEDURE p1()
BEGIN
SELECT 1;
END $$
DELIMITER ;$$
CREATE TABLE t1 (c1 INT);
CREATE TABLE t2 (c1 INT);
INSERT INTO t1 VALUES (1);
--echo Assert Questions == 9
SHOW STATUS LIKE 'Questions';
SELECT f1();
--echo Assert Questions == 11
SHOW STATUS LIKE 'Questions';
CALL p1();
--echo Assert Questions == 13
SHOW STATUS LIKE 'Questions';
SELECT 1;
--echo Assert Questions == 15
SHOW STATUS LIKE 'Questions';
connect (con1,localhost,root,,);
connection con1;
FLUSH STATUS;
let $org_questions= `SHOW GLOBAL STATUS LIKE 'questions'`;
SELECT 1;
connection default;
disconnect con1;
--echo Assert Questions == 16
SHOW STATUS LIKE 'Questions';
--echo Global status updated; Assert diff == 5
FLUSH STATUS;
let $new_questions= `SHOW GLOBAL STATUS LIKE 'questions'`;
--disable_log
let $diff= `SELECT SUBSTRING('$new_questions',10)-SUBSTRING('$org_questions',10)`;
--enable_log
eval SELECT $diff;
DROP TABLE t1,t2;
DROP PROCEDURE p1;
DROP FUNCTION f1;
--echo End of 6.0 tests
...@@ -6573,7 +6573,9 @@ struct show_var_st status_vars[]= { ...@@ -6573,7 +6573,9 @@ struct show_var_st status_vars[]= {
{"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST}, {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_CONST},
{"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST}, {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_CONST},
#endif /*HAVE_QUERY_CACHE*/ #endif /*HAVE_QUERY_CACHE*/
{"Questions", (char*) 0, SHOW_QUESTION}, {"Questions", (char*) offsetof(STATUS_VAR, questions),
SHOW_LONG_STATUS},
{"Rpl_status", (char*) 0, SHOW_RPL_STATUS}, {"Rpl_status", (char*) 0, SHOW_RPL_STATUS},
{"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS}, {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
{"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS}, {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
......
...@@ -664,10 +664,17 @@ typedef struct system_status_var ...@@ -664,10 +664,17 @@ typedef struct system_status_var
ulong com_stmt_fetch; ulong com_stmt_fetch;
ulong com_stmt_reset; ulong com_stmt_reset;
ulong com_stmt_close; ulong com_stmt_close;
/*
Number of statements sent from the client
*/
ulong questions;
/* /*
Status variables which it does not make sense to add to IMPORTANT!
global status variable counter SEE last_system_status_var DEFINITION BELOW.
Below 'last_system_status_var' are all variables which doesn't make any
sense to add to the /global/ status variable counter.
*/ */
double last_query_cost; double last_query_cost;
} STATUS_VAR; } STATUS_VAR;
...@@ -678,7 +685,7 @@ typedef struct system_status_var ...@@ -678,7 +685,7 @@ typedef struct system_status_var
counter counter
*/ */
#define last_system_status_var com_stmt_close #define last_system_status_var questions
void free_tmp_table(THD *thd, TABLE *entry); void free_tmp_table(THD *thd, TABLE *entry);
......
...@@ -1690,8 +1690,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1690,8 +1690,24 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->set_time(); thd->set_time();
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_id= global_query_id; thd->query_id= global_query_id;
if (command != COM_STATISTICS && command != COM_PING)
switch( command ) {
/* Ignore these statements. */
case COM_STATISTICS:
case COM_PING:
break;
/* Only increase id on these statements but don't count them. */
case COM_STMT_PREPARE:
case COM_STMT_CLOSE:
case COM_STMT_RESET:
next_query_id(); next_query_id();
break;
/* Increase id and count all other statements. */
default:
statistic_increment(thd->status_var.questions, &LOCK_status);
next_query_id();
}
thread_running++; thread_running++;
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
VOID(pthread_mutex_unlock(&LOCK_thread_count)); VOID(pthread_mutex_unlock(&LOCK_thread_count));
...@@ -1896,6 +1912,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1896,6 +1912,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
VOID(pthread_mutex_lock(&LOCK_thread_count)); VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length; thd->query_length= length;
thd->query= next_packet; thd->query= next_packet;
/*
Count each statement from the client.
*/
statistic_increment(thd->status_var.questions, &LOCK_status);
thd->query_id= next_query_id(); thd->query_id= next_query_id();
thd->set_time(); /* Reset the query start time. */ thd->set_time(); /* Reset the query start time. */
/* TODO: set thd->lex->sql_command to SQLCOM_END here */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
......
...@@ -1520,9 +1520,6 @@ static bool show_status_array(THD *thd, const char *wild, ...@@ -1520,9 +1520,6 @@ static bool show_status_array(THD *thd, const char *wild,
nr= (long) (thd->query_start() - server_start_time); nr= (long) (thd->query_start() - server_start_time);
end= int10_to_str(nr, buff, 10); end= int10_to_str(nr, buff, 10);
break; break;
case SHOW_QUESTION:
end= int10_to_str((long) thd->query_id, buff, 10);
break;
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
case SHOW_RPL_STATUS: case SHOW_RPL_STATUS:
end= strmov(buff, rpl_status_type[(int)rpl_status]); end= strmov(buff, rpl_status_type[(int)rpl_status]);
......
...@@ -170,7 +170,7 @@ enum SHOW_TYPE ...@@ -170,7 +170,7 @@ enum SHOW_TYPE
SHOW_UNDEF, SHOW_UNDEF,
SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
SHOW_DOUBLE_STATUS, SHOW_DOUBLE_STATUS,
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUESTION, SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME,
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS, SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
SHOW_VARS, SHOW_VARS,
#ifdef HAVE_OPENSSL #ifdef HAVE_OPENSSL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment