List:Commits« Previous MessageNext Message »
From:Nirbhay Choubey Date:October 2 2010 6:44pm
Subject:bzr commit into mysql-5.1-bugteam branch (nirbhay.choubey:3520)
Bug#39828
View as plain text  
#At file:///home/nirbhay/Project/mysql/repo/wl/mysql-5.1-bugteam-39828/ based on revid:georgi.kodinov@stripped

 3520 Nirbhay Choubey	2010-10-03
      Bug#39828 : Autoinc wraps around when offset and increment > 1
      
      Auto increment value wraps when performing a bulk insert with
      auto_increment_increment and auto_increment_offset greater than
      one. Howerer, the initial investigation showed that same bug can
      be reproduced even if just auto_increment_increment is greater 
      than one. The bug report also reports of an assertion failure on
      a debug server.
      
      The wrapping of autoinc column happend in update_auto_increment
      function as it failed to check for overflow of next autoinc value
      to be inserted into the column in case of bulk insert. 
      
      Fixed by placing checks for overflow.
     @ mysql-test/suite/innodb/r/innodb-autoinc.result
        Bug #39828 : Autoinc wraps around when offset and increment > 1
     @ mysql-test/suite/innodb/t/innodb-autoinc.test
        Bug #39828 : Autoinc wraps around when offset and increment > 1
     @ mysql-test/suite/innodb_plugin/r/innodb-autoinc.result
        Bug #39828 : Autoinc wraps around when offset and increment > 1
     @ mysql-test/suite/innodb_plugin/t/innodb-autoinc.test
        Bug #39828 : Autoinc wraps around when offset and increment > 1
     @ sql/handler.cc
        Bug #39828 : Autoinc wraps around when offset and increment > 1
        
        Added a condition to check for overflow of 'nr' returned from
        compute_next_insert_id. Apart from that, added one more condition
        towards the beginning of handler::update_auto_increment to check
        if next_insert_id is lesser than insert_id_for_cur_row, which
        inturn will avoid overflowing of autoinc value in case of 
        bulk (multi-valued) insert.

    modified:
      mysql-test/suite/innodb/r/innodb-autoinc.result
      mysql-test/suite/innodb/t/innodb-autoinc.test
      mysql-test/suite/innodb_plugin/r/innodb-autoinc.result
      mysql-test/suite/innodb_plugin/t/innodb-autoinc.test
      sql/handler.cc
=== modified file 'mysql-test/suite/innodb/r/innodb-autoinc.result'
--- a/mysql-test/suite/innodb/r/innodb-autoinc.result	2010-04-12 11:56:24 +0000
+++ b/mysql-test/suite/innodb/r/innodb-autoinc.result	2010-10-02 18:44:54 +0000
@@ -471,17 +471,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	2
 auto_increment_offset	10
-INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551603
-18446744073709551604
-18446744073709551606
-18446744073709551608
-18446744073709551610
-18446744073709551612
-18446744073709551614
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
@@ -504,13 +499,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	5
 auto_increment_offset	7
-INSERT INTO t1 VALUES (NULL),(NULL);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551603
-18446744073709551607
-18446744073709551612
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
@@ -572,12 +566,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	65535
 auto_increment_offset	65535
-INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 VALUES (NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551610
-18446744073709551615
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;

=== modified file 'mysql-test/suite/innodb/t/innodb-autoinc.test'
--- a/mysql-test/suite/innodb/t/innodb-autoinc.test	2010-04-12 11:56:24 +0000
+++ b/mysql-test/suite/innodb/t/innodb-autoinc.test	2010-10-02 18:44:54 +0000
@@ -279,6 +279,9 @@ DROP TABLE t1;
 
 #
 # Check for overflow handling when increment and offser are > 1
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -291,26 +294,16 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't, it seems to be
-# a MySQL server bug. It wraps around to 0 for the last value.
-# See MySQL Bug# 39828
-#
-# Instead of wrapping around, it asserts when MySQL is compiled --with-debug
-# (see sql/handler.cc:handler::update_auto_increment()).  Don't test for
-# overflow until Bug #39828 is fixed.
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-#INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
-#else
-INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 
 #
 # Check for overflow handling when increment and offset are odd numbers
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -323,20 +316,8 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't. It fails with
-# a duplicate entry message because of a MySQL server bug, it wraps
-# around.  See MySQL Bug# 39828, once MySQL fix the bug we can replace
-# the ER_DUP_ENTRY, 1062 below with the appropriate error message
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-# Still need to fix this error code, error should mention overflow
-#-- error ER_DUP_ENTRY,1062
-#INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
-#else
-INSERT INTO t1 VALUES (NULL),(NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 
@@ -362,6 +343,9 @@ DROP TABLE t1;
 #
 # Check for overflow handling when increment and offset are very
 # large numbers 2^60
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -374,20 +358,8 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't. It wraps around
-# and the autoinc values look bogus too.
-# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
-# code expected test.
-# -- error ER_AUTOINC_READ_FAILED,1467
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-#-- error ER_AUTOINC_READ_FAILED,1467
-#INSERT INTO t1 VALUES (NULL),(NULL);
-#else
-INSERT INTO t1 VALUES (NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 

=== modified file 'mysql-test/suite/innodb_plugin/r/innodb-autoinc.result'
--- a/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result	2010-04-09 12:56:51 +0000
+++ b/mysql-test/suite/innodb_plugin/r/innodb-autoinc.result	2010-10-02 18:44:54 +0000
@@ -471,17 +471,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	2
 auto_increment_offset	10
-INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551603
-18446744073709551604
-18446744073709551606
-18446744073709551608
-18446744073709551610
-18446744073709551612
-18446744073709551614
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
@@ -504,13 +499,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	5
 auto_increment_offset	7
-INSERT INTO t1 VALUES (NULL),(NULL);
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551603
-18446744073709551607
-18446744073709551612
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
@@ -572,12 +566,12 @@ SHOW VARIABLES LIKE "%auto_inc%";
 Variable_name	Value
 auto_increment_increment	65535
 auto_increment_offset	65535
-INSERT INTO t1 VALUES (NULL);
+INSERT INTO t1 VALUES (NULL),(NULL);
+ERROR HY000: Failed to read auto-increment value from storage engine
 SELECT * FROM t1;
 c1
 1
 18446744073709551610
-18446744073709551615
 DROP TABLE t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;

=== modified file 'mysql-test/suite/innodb_plugin/t/innodb-autoinc.test'
--- a/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test	2010-08-06 09:35:17 +0000
+++ b/mysql-test/suite/innodb_plugin/t/innodb-autoinc.test	2010-10-02 18:44:54 +0000
@@ -281,6 +281,9 @@ DROP TABLE t1;
 
 #
 # Check for overflow handling when increment and offser are > 1
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -293,26 +296,16 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=2, @@SESSION.AUTO_INCREMENT_OFFSET=10;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't, it seems to be
-# a MySQL server bug. It wraps around to 0 for the last value.
-# See MySQL Bug# 39828
-#
-# Instead of wrapping around, it asserts when MySQL is compiled --with-debug
-# (see sql/handler.cc:handler::update_auto_increment()).  Don't test for
-# overflow until Bug #39828 is fixed.
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-#INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
-#else
-INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 
 #
 # Check for overflow handling when increment and offset are odd numbers
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -325,20 +318,8 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=5, @@SESSION.AUTO_INCREMENT_OFFSET=7;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't. It fails with
-# a duplicate entry message because of a MySQL server bug, it wraps
-# around.  See MySQL Bug# 39828, once MySQL fix the bug we can replace
-# the ER_DUP_ENTRY, 1062 below with the appropriate error message
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-# Still need to fix this error code, error should mention overflow
-#-- error ER_DUP_ENTRY,1062
-#INSERT INTO t1 VALUES (NULL),(NULL), (NULL);
-#else
-INSERT INTO t1 VALUES (NULL),(NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 
@@ -364,6 +345,9 @@ DROP TABLE t1;
 #
 # Check for overflow handling when increment and offset are very
 # large numbers 2^60
+#
+# Bug #39828 : Autoinc wraps around when offset and increment > 1
+#
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1, @@SESSION.AUTO_INCREMENT_OFFSET=1;
 SET @@INSERT_ID=1;
 SHOW VARIABLES LIKE "%auto_inc%";
@@ -376,20 +360,8 @@ INSERT INTO t1 VALUES (18446744073709551
 SELECT * FROM t1;
 SET @@SESSION.AUTO_INCREMENT_INCREMENT=1152921504606846976, @@SESSION.AUTO_INCREMENT_OFFSET=1152921504606846976;
 SHOW VARIABLES LIKE "%auto_inc%";
-# This should fail because of overflow but it doesn't. It wraps around
-# and the autoinc values look bogus too.
-# See MySQL Bug# 39828, once MySQL fix the bug we can enable the error
-# code expected test.
-# -- error ER_AUTOINC_READ_FAILED,1467
-#
-# Since this asserts when compiled --with-debug, we can't properly test this
-# until Bug #39828 is fixed.  For now, this test is meaningless.
-#if Bug #39828 is fixed
-#-- error ER_AUTOINC_READ_FAILED,1467
-#INSERT INTO t1 VALUES (NULL),(NULL);
-#else
-INSERT INTO t1 VALUES (NULL);
-#endif
+-- error ER_AUTOINC_READ_FAILED
+INSERT INTO t1 VALUES (NULL),(NULL);
 SELECT * FROM t1;
 DROP TABLE t1;
 

=== modified file 'sql/handler.cc'
--- a/sql/handler.cc	2010-04-14 09:53:59 +0000
+++ b/sql/handler.cc	2010-10-02 18:44:54 +0000
@@ -2317,11 +2317,17 @@ prev_insert_id(ulonglong nr, struct syst
 
 int handler::update_auto_increment()
 {
-  ulonglong nr, nb_reserved_values;
+  ulonglong nr, nb_reserved_values, nr_old;
   bool append= FALSE;
   THD *thd= table->in_use;
   struct system_variables *variables= &thd->variables;
   DBUG_ENTER("handler::update_auto_increment");
+  
+  /*
+    Perform an overflow check on next_insert_id.
+  */
+  if ((insert_id_for_cur_row) && (insert_id_for_cur_row > next_insert_id))
+    DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED);
 
   /*
     next_insert_id is a "cursor" into the reserved interval, it may go greater
@@ -2341,6 +2347,12 @@ int handler::update_auto_increment()
     */
     adjust_next_insert_id_after_explicit_value(nr);
     insert_id_for_cur_row= 0; // didn't generate anything
+
+    /*
+      Check for the overflow of next_insert_id.
+    */
+    if (next_insert_id < nr)
+      auto_inc_interval_for_cur_row.replace(0, 0, 0);
     DBUG_RETURN(0);
   }
 
@@ -2396,6 +2408,12 @@ int handler::update_auto_increment()
         DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED);  // Mark failure
 
       /*
+        nr_old will be used to store nr's value, which inturn will be
+        compared with nr's value returned from compute_next_insert_id().
+      */
+      nr_old= nr;
+
+      /*
         That rounding below should not be needed when all engines actually
         respect offset and increment in get_auto_increment(). But they don't
         so we still do it. Wonder if for the not-first-in-index we should do
@@ -2404,6 +2422,9 @@ int handler::update_auto_increment()
         will not help as we inserted no row).
       */
       nr= compute_next_insert_id(nr-1, variables);
+
+      if (nr < nr_old)
+        DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED);
     }
 
     if (table->s->next_number_keypart == 0)


Attachment: [text/bzr-bundle]
Thread
bzr commit into mysql-5.1-bugteam branch (nirbhay.choubey:3520)Bug#39828Nirbhay Choubey2 Oct
Re: bzr commit into mysql-5.1-bugteam branch (nirbhay.choubey:3520)Bug#39828Guilhem Bichot16 Oct