diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index 261e3292f4d..6004c3d082b 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -820,3 +820,31 @@ Execute select '000 001 002 003 004 005 006 007 008 009010 011 012 013 014 015 0 Query set global general_log = off deallocate prepare long_query; set global general_log = @old_general_log_state; +SET @old_slow_log_state = @@global.slow_query_log; +SET SESSION long_query_time = 0; +SET GLOBAL slow_query_log = ON; +FLUSH LOGS; +TRUNCATE TABLE mysql.slow_log; +CREATE TABLE t1 (f1 SERIAL,f2 INT, f3 INT, PRIMARY KEY(f1), KEY(f2)); +INSERT INTO t1 VALUES (1,1,1); +INSERT INTO t1 VALUES (2,2,2); +INSERT INTO t1 VALUES (3,3,3); +INSERT INTO t1 VALUES (4,4,4); +SELECT SQL_NO_CACHE 'Bug#31700 - SCAN',f1,f2,f3 FROM t1 WHERE f3=4; +Bug#31700 - SCAN f1 f2 f3 +Bug#31700 - SCAN 4 4 4 +SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3 FROM t1 WHERE f2=3; +Bug#31700 - KEY f1 f2 f3 +Bug#31700 - KEY 3 3 3 +SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3 FROM t1 WHERE f1=2; +Bug#31700 - PK f1 f2 f3 +Bug#31700 - PK 2 2 2 +SELECT start_time, rows_examined, rows_sent, sql_text FROM mysql.slow_log WHERE sql_text LIKE '%Bug#31700%' ORDER BY start_time; +start_time rows_examined rows_sent sql_text +TIMESTAMP 4 1 SELECT SQL_NO_CACHE 'Bug#31700 - SCAN',f1,f2,f3 FROM t1 WHERE f3=4 +TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3 FROM t1 WHERE f2=3 +TIMESTAMP 1 1 SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3 FROM t1 WHERE f1=2 +DROP TABLE t1; +TRUNCATE TABLE mysql.slow_log; +SET GLOBAL slow_query_log = @old_slow_log_state; +SET SESSION long_query_time =@old_long_query_time; diff --git a/mysql-test/t/log_tables.test b/mysql-test/t/log_tables.test index 12098b4543b..39bf8029a7c 100644 --- a/mysql-test/t/log_tables.test +++ b/mysql-test/t/log_tables.test @@ -924,3 +924,34 @@ set global general_log = off; select command_type, argument from mysql.general_log; deallocate prepare long_query; set global general_log = @old_general_log_state; + +# +# Bug #31700: thd->examined_row_count not incremented for 'const' type queries +# +SET @old_slow_log_state = @@global.slow_query_log; + +SET SESSION long_query_time = 0; +SET GLOBAL slow_query_log = ON; +FLUSH LOGS; +TRUNCATE TABLE mysql.slow_log; + +# Let there be three columns, unique, non-unique, and non-indexed: +CREATE TABLE t1 (f1 SERIAL,f2 INT, f3 INT, PRIMARY KEY(f1), KEY(f2)); +INSERT INTO t1 VALUES (1,1,1); +INSERT INTO t1 VALUES (2,2,2); +INSERT INTO t1 VALUES (3,3,3); +INSERT INTO t1 VALUES (4,4,4); + +SELECT SQL_NO_CACHE 'Bug#31700 - SCAN',f1,f2,f3 FROM t1 WHERE f3=4; +SELECT SQL_NO_CACHE 'Bug#31700 - KEY', f1,f2,f3 FROM t1 WHERE f2=3; +SELECT SQL_NO_CACHE 'Bug#31700 - PK', f1,f2,f3 FROM t1 WHERE f1=2; + +--replace_column 1 TIMESTAMP +SELECT start_time, rows_examined, rows_sent, sql_text FROM mysql.slow_log WHERE sql_text LIKE '%Bug#31700%' ORDER BY start_time; + +DROP TABLE t1; + +TRUNCATE TABLE mysql.slow_log; + +SET GLOBAL slow_query_log = @old_slow_log_state; +SET SESSION long_query_time =@old_long_query_time; diff --git a/sql/sql_class.h b/sql/sql_class.h index 0a045885593..2e842c0c5d7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1365,9 +1365,20 @@ public: ulonglong limit_found_rows; ulonglong options; /* Bitmap of states */ - longlong row_count_func; /* For the ROW_COUNT() function */ - ha_rows cuted_fields, - sent_row_count, examined_row_count; + longlong row_count_func; /* For the ROW_COUNT() function */ + ha_rows cuted_fields; + + /* + number of rows we actually sent to the client, including "synthetic" + rows in ROLLUP etc. + */ + ha_rows sent_row_count; + + /* + number of rows we read, sent or not, including in create_sort_index() + */ + ha_rows examined_row_count; + /* The set of those tables whose fields are referenced in all subqueries of the query. @@ -1403,7 +1414,11 @@ public: /* Statement id is thread-wide. This counter is used to generate ids */ ulong statement_id_counter; ulong rand_saved_seed1, rand_saved_seed2; - ulong row_count; // Row counter, mainly for errors and warnings + /* + Row counter, mainly for errors and warnings. Not increased in + create_sort_index(); may differ from examined_row_count. + */ + ulong row_count; pthread_t real_id; /* For debugging */ my_thread_id thread_id; uint tmp_table, global_read_lock; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 469bf526d37..f7f0cf63384 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -10665,6 +10665,15 @@ do_select(JOIN *join,List *fields,TABLE *table,Procedure *procedure) error= (*end_select)(join, 0, 0); if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT) error= (*end_select)(join, 0, 1); + + /* + If we don't go through evaluate_join_record(), do the counting + here. join->send_records is increased on success in end_send(), + so we don't touch it here. + */ + join->examined_rows++; + join->thd->row_count++; + DBUG_ASSERT(join->examined_rows <= 1); } else if (join->send_row_on_empty_set()) {