List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:April 25 2012 12:37pm
Subject:bzr push into mysql-trunk branch (mattias.jonsson:3739 to 3740) Bug#13008220
View as plain text  
 3740 Mattias Jonsson	2012-04-23
      Bug#13008220: HANDLER SQL STATEMENT CAN MISS TO
      INITIALIZE FOR RANDOM READ
      
      When doing index scans and then swithing to
      random scans, without restart, ha_rnd_init
      is not called, when using the HANDLER SQL
      interface.
      
      Fixed by ensuring that when switching between
      index and random scans there will always be a call to
      ha_index/rnd_end and then ha_index/rnd_init.
      
      Also checking return values from ha_index/rnd_init/end.
      
      (updated with DBUG_ASSERT from reviewers suggestion).

    modified:
      mysql-test/include/handler.inc
      mysql-test/r/handler_innodb.result
      mysql-test/r/handler_myisam.result
      mysql-test/t/handler_myisam.test
      sql/sql_handler.cc
 3739 Vasil Dimov	2012-04-25
      Non-functional change: fix the names of DICT_STAT_PERSISTEN_ON/OFF macros

    modified:
      storage/innobase/include/dict0mem.h
      storage/innobase/include/dict0stats.ic
=== modified file 'mysql-test/include/handler.inc'
--- a/mysql-test/include/handler.inc	revid:vasil.dimov@stripped
+++ b/mysql-test/include/handler.inc	revid:mattias.jonsson@stripped
@@ -1839,3 +1839,34 @@ HANDLER t1 READ FIRST WHERE f1() = 1;
 HANDLER t1 CLOSE;
 DROP FUNCTION f1;
 DROP TABLE t1;
+
+--echo #
+--echo # Bug#13008220 HANDLER SQL STATEMENT CAN MISS TO INITIALIZE
+--echo #              FOR RANDOM READ
+--echo #
+
+CREATE TABLE t1(a INT, b INT, KEY b(b));
+INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30);
+HANDLER t1 OPEN;
+HANDLER t1 READ b FIRST;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ b FIRST;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ FIRST;
+HANDLER t1 READ b FIRST;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ b NEXT;
+HANDLER t1 CLOSE;
+DROP TABLE t1;

=== modified file 'mysql-test/r/handler_innodb.result'
--- a/mysql-test/r/handler_innodb.result	revid:vasil.dimov@stripped
+++ b/mysql-test/r/handler_innodb.result	revid:mattias.jonsson@stripped
@@ -1744,3 +1744,70 @@ ERROR 42000: This version of MySQL doesn
 HANDLER t1 CLOSE;
 DROP FUNCTION f1;
 DROP TABLE t1;
+#
+# Bug#13008220 HANDLER SQL STATEMENT CAN MISS TO INITIALIZE
+#              FOR RANDOM READ
+#
+CREATE TABLE t1(a INT, b INT, KEY b(b));
+INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30);
+HANDLER t1 OPEN;
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ NEXT;
+a	b
+1	10
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ b NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+3	30
+HANDLER t1 READ FIRST;
+a	b
+2	20
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ NEXT;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+4	40
+HANDLER t1 READ NEXT;
+a	b
+3	30
+HANDLER t1 READ NEXT;
+a	b
+HANDLER t1 READ b NEXT;
+a	b
+1	10
+HANDLER t1 READ b NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+3	30
+HANDLER t1 READ b NEXT;
+a	b
+4	40
+HANDLER t1 READ b NEXT;
+a	b
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+1	10
+HANDLER t1 CLOSE;
+DROP TABLE t1;

=== modified file 'mysql-test/r/handler_myisam.result'
--- a/mysql-test/r/handler_myisam.result	revid:vasil.dimov@stripped
+++ b/mysql-test/r/handler_myisam.result	revid:mattias.jonsson@stripped
@@ -1741,6 +1741,73 @@ HANDLER t1 CLOSE;
 DROP FUNCTION f1;
 DROP TABLE t1;
 #
+# Bug#13008220 HANDLER SQL STATEMENT CAN MISS TO INITIALIZE
+#              FOR RANDOM READ
+#
+CREATE TABLE t1(a INT, b INT, KEY b(b));
+INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30);
+HANDLER t1 OPEN;
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ NEXT;
+a	b
+1	10
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ b NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+3	30
+HANDLER t1 READ FIRST;
+a	b
+2	20
+HANDLER t1 READ b FIRST;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ NEXT;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
+4	40
+HANDLER t1 READ NEXT;
+a	b
+3	30
+HANDLER t1 READ NEXT;
+a	b
+HANDLER t1 READ b NEXT;
+a	b
+1	10
+HANDLER t1 READ b NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+3	30
+HANDLER t1 READ b NEXT;
+a	b
+4	40
+HANDLER t1 READ b NEXT;
+a	b
+HANDLER t1 READ NEXT;
+a	b
+2	20
+HANDLER t1 READ b NEXT;
+a	b
+1	10
+HANDLER t1 CLOSE;
+DROP TABLE t1;
+#
 # BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash 
 #
 CREATE TABLE t1 AS SELECT 1 AS f1;
@@ -1820,6 +1887,12 @@ HANDLER t1 READ b NEXT;
 a	b
 HANDLER t1 READ NEXT;
 a	b
+2	20
+HANDLER t1 READ NEXT;
+a	b
+1	10
+HANDLER t1 READ NEXT;
+a	b
 4	40
 HANDLER t1 READ NEXT;
 a	b

=== modified file 'mysql-test/t/handler_myisam.test'
--- a/mysql-test/t/handler_myisam.test	revid:vasil.dimov@stripped
+++ b/mysql-test/t/handler_myisam.test	revid:mattias.jonsson@stripped
@@ -78,6 +78,8 @@ HANDLER t1 READ b NEXT;
 HANDLER t1 READ NEXT;
 HANDLER t1 READ NEXT;
 HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
+HANDLER t1 READ NEXT;
 HANDLER t1 CLOSE;
 
 HANDLER t1 OPEN;

=== modified file 'sql/sql_handler.cc'
--- a/sql/sql_handler.cc	revid:vasil.dimov@stripped
+++ b/sql/sql_handler.cc	revid:mattias.jonsson@stripped
@@ -668,18 +668,19 @@ retry:
   {
     switch (mode) {
     case RNEXT:
-      if (table->file->inited != handler::NONE)
+      if (m_key_name)
       {
-        if (m_key_name)
+        if (table->file->inited == handler::INDEX)
         {
           /* Check if we read from the same index. */
           DBUG_ASSERT((uint) keyno == table->file->get_index());
           error= table->file->ha_index_next(table->record[0]);
+          break;
         }
-        else
-        {
-          error= table->file->ha_rnd_next(table->record[0]);
-        }
+      }
+      else if (table->file->inited == handler::RND)
+      {
+        error= table->file->ha_rnd_next(table->record[0]);
         break;
       }
       /* else fall through */
@@ -687,8 +688,8 @@ retry:
       if (m_key_name)
       {
         table->file->ha_index_or_rnd_end();
-        table->file->ha_index_init(keyno, 1);
-        error= table->file->ha_index_first(table->record[0]);
+        if (!(error= table->file->ha_index_init(keyno, 1)))
+          error= table->file->ha_index_first(table->record[0]);
       }
       else
       {
@@ -702,7 +703,7 @@ retry:
       DBUG_ASSERT(m_key_name != 0);
       /* Check if we read from the same index. */
       DBUG_ASSERT((uint) keyno == table->file->get_index());
-      if (table->file->inited != handler::NONE)
+      if (table->file->inited == handler::INDEX)
       {
         error= table->file->ha_index_prev(table->record[0]);
         break;
@@ -710,15 +711,22 @@ retry:
       /* else fall through */
     case RLAST:
       DBUG_ASSERT(m_key_name != 0);
-      table->file->ha_index_or_rnd_end();
-      table->file->ha_index_init(keyno, 1);
-      error= table->file->ha_index_last(table->record[0]);
+      if (!(error= table->file->ha_index_or_rnd_end()) &&
+          !(error= table->file->ha_index_init(keyno, 1)))
+        error= table->file->ha_index_last(table->record[0]);
       mode=RPREV;
       break;
     case RNEXT_SAME:
       /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...)  */
       DBUG_ASSERT(m_key_name != 0);
-      error= table->file->ha_index_next_same(table->record[0], key, key_len);
+      /* Continue scan, or start a new scan if no previous index scan */
+      if (table->file->inited == handler::INDEX ||
+          (!(error= table->file->ha_index_or_rnd_end()) &&
+           !(error= table->file->ha_index_init(keyno, 1))))
+      {
+        DBUG_ASSERT((uint) keyno == table->file->get_index());
+        error= table->file->ha_index_next_same(table->record[0], key, key_len);
+      }
       break;
     case RKEY:
     {
@@ -755,11 +763,12 @@ retry:
 
       if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(key_len))))
 	goto err;
-      table->file->ha_index_or_rnd_end();
-      table->file->ha_index_init(keyno, 1);
+      if ((error= table->file->ha_index_or_rnd_end()))
+        break;
       key_copy(key, table->record[0], table->key_info + keyno, key_len);
-      error= table->file->ha_index_read_map(table->record[0],
-                                            key, keypart_map, m_rkey_mode);
+      if (!(error= table->file->ha_index_init(keyno, 1)))
+        error= table->file->ha_index_read_map(table->record[0],
+                                              key, keypart_map, m_rkey_mode);
       mode=rkey_to_rnext[(int)m_rkey_mode];
       break;
     }

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (mattias.jonsson:3739 to 3740) Bug#13008220Mattias Jonsson25 Apr