Bug #53830 !table || (!table->read_set || bitmap_is_set(table->read_set, field_index))
Submitted: 20 May 2010 4:14 Modified: 14 Oct 2010 15:27
Reporter: Shane Bester (Platinum Quality Contributor) Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: DML Severity:S1 (Critical)
Version:5.1.43sp1-debug,5.1.46-debug, 5.5.3-debug OS:Any
Assigned to: Alexey Kopytov CPU Architecture:Any
Tags: regression

[20 May 2010 4:14] Shane Bester
Description:
Version: '5.1.46-enterprise-gpl-advanced-debug-log'  socket: ''  port: 3306  MySQL Enterprise Server - Advanced Edition Debug (GPL)
Assertion failed: !table || (!table->read_set || bitmap_is_set(table->read_set, field_index)), file .\field.cc, line 3723

mysqld-debug.exe!my_sigabrt_handler()[mysqld.cc:2049]
mysqld-debug.exe!raise()[winsig.c:590]
mysqld-debug.exe!abort()[abort.c:71]
mysqld-debug.exe!_wassert()[assert.c:212]
mysqld-debug.exe!Field_long::val_int()[field.cc:3723]
mysqld-debug.exe!Item_field::val_int()[item.cc:2039]
mysqld-debug.exe!Arg_comparator::compare_int_signed()[item_cmpfunc.cc:1459]
mysqld-debug.exe!Arg_comparator::compare()[item_cmpfunc.h:81]
mysqld-debug.exe!Item_func_eq::val_int()[item_cmpfunc.cc:1866]
mysqld-debug.exe!Item::val_bool()[item.cc:184]
mysqld-debug.exe!Item_cond_and::val_int()[item_cmpfunc.cc:4397]
mysqld-debug.exe!SQL_SELECT::skip_record()[opt_range.h:711]
mysqld-debug.exe!mysql_update()[sql_update.cc:474]
mysqld-debug.exe!mysql_execute_command()[sql_parse.cc:3067]
mysqld-debug.exe!mysql_parse()[sql_parse.cc:5971]
mysqld-debug.exe!dispatch_command()[sql_parse.cc:1233]
mysqld-debug.exe!do_command()[sql_parse.cc:874]
mysqld-debug.exe!handle_one_connection()[sql_connect.cc:1127]
mysqld-debug.exe!pthread_start()[my_winthread.c:85]
mysqld-debug.exe!_callthreadstart()[thread.c:293]
mysqld-debug.exe!_threadstart()[thread.c:277]

How to repeat:
drop table if exists `t1`;
create table `t1` (`a` int,`b` int,`c` int,`d` int,
primary key (`a`,`b`,`c`),key (`b`,`d`)) engine=innodb;
insert into `t1` values (0,77,2,3);
update `t1` set `d`=0 where `b`=77 and `c` in (25);

Suggested fix:
on debug build:

drop table if exists `t1`;
create table `t1` (`a` int,`b` int,`c` int,`d` int,
primary key (`a`,`b`,`c`),key (`b`,`d`)) engine=innodb;
insert into `t1` values (0,77,2,3);
update `t1` set `d`=0 where `b`=77 and `c` in (25);
[20 May 2010 4:17] MySQL Verification Team
5.0.91-debug is not affected
[20 May 2010 5:29] MySQL Verification Team
Verified as described with 5.1.43sp1-debug on linux x86_64
[20 May 2010 15:43] Valeriy Kravchuk
No crash with non-debug binaries at least on Windows for me:

C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -proot -P3310 test
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.46-community MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> drop table if exists `t1`;
Query OK, 0 rows affected (0.28 sec)

mysql> create table `t1` (`a` int,`b` int,`c` int,`d` int,
    -> primary key (`a`,`b`,`c`),key (`b`,`d`)) engine=innodb;
Query OK, 0 rows affected (0.19 sec)

mysql> insert into `t1` values (0,77,2,3);
Query OK, 1 row affected (0.06 sec)

mysql> update `t1` set `d`=0 where `b`=77 and `c` in (25);
Query OK, 0 rows affected (0.05 sec)
Rows matched: 0  Changed: 0  Warnings: 0
[25 May 2010 14:44] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/109195

3394 Alexey Kopytov	2010-05-25
      Bug #53830: !table || (!table->read_set ||
                   bitmap_is_set(table->read_set, field_index))
      
      UPDATE on an InnoDB table modifying the same index that is used
      to satisfy the WHERE condition could trigger a debug assertion
      under some circumstances.
      
      Since for engines with the HA_PRIMARY_KEY_IN_READ_INDEX flag
      set results of an index scan on a secondary index are appended
      by the primary key value, if a query involves only columns from
      the primary key and a secondary index, the latter is considered
      to be covering.
      
      That tricks mysql_update() to mark for reading only columns
      from the secondary index when it does an index scan to retrieve
      rows to update in case a part of that key is also being
      updated. However, there may be other columns in WHERE that are
      part of the primary key, but not the secondary one.
      
      What we actually want to do in this case is to add index
      columns to the existing WHERE columns bitmap rather than
      replace it.
     @ mysql-test/r/innodb_mysql.result
        Test case for bug #53830.
     @ mysql-test/t/innodb_mysql.test
        Test case for bug #53830.
     @ sql/sql_update.cc
        Add index columns to the read_set bitmap, don't replace it.
     @ sql/table.cc
        Added a new add_read_columns_used_by_index() function to 
        st_table.
     @ sql/table.h
        Added a new add_read_columns_used_by_index() function to 
        st_table.
[25 May 2010 15:11] Ryan Mack
Hi Alexey,

Does this bug have any effect on the correctness of such queries in non-debug builds?

Thank you,

Ryan
[25 May 2010 17:23] Alexey Kopytov
Hi Ryan,

No, it does not. The storage engine still provided data for the missing columns, since they were a part of the primary key. It's just that the debug assertion is not smart enough to detect this. The best way to silence the assertion is just to mark those columns in read_set explicitly.
[2 Jun 2010 8:49] Bugs System
Pushed into 5.1.48 (revid:georgi.kodinov@oracle.com-20100602084411-2yu607bslbmgufl3) (version source revid:alexey.kopytov@sun.com-20100527101427-uinq51zcw3sz7b16) (merge vers: 5.1.47) (pib:16)
[4 Jun 2010 2:01] Paul DuBois
Noted in 5.1.48 changelog.

UPDATE on an InnoDB table modifying the same index that was used to
satisfy the WHERE condition could trigger a debug assertion under
some circumstances. 

Setting report to Need Merge pending further pushes.
[17 Jun 2010 6:12] Bugs System
Pushed into 5.5.5-m3 (revid:alexey.kopytov@sun.com-20100615145247-8bj0vmuqlotbqsn9) (version source revid:alexey.kopytov@sun.com-20100527100844-oggbnd0znbqxkz1s) (merge vers: 5.5.5-m3) (pib:16)
[17 Jun 2010 6:16] Bugs System
Pushed into mysql-next-mr (revid:alik@sun.com-20100615150216-cubqoyn1fj9b6a2p) (version source revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh) (pib:16)
[18 Jun 2010 1:29] Paul DuBois
Noted in 5.5.5 changelog.
[14 Oct 2010 8:30] Bugs System
Pushed into mysql-5.1-telco-7.0 5.1.51-ndb-7.0.20 (revid:martin.skold@mysql.com-20101014082627-jrmy9xbfbtrebw3c) (version source revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh) (merge vers: 5.5.5-m3) (pib:21)
[14 Oct 2010 8:46] Bugs System
Pushed into mysql-5.1-telco-6.3 5.1.51-ndb-6.3.39 (revid:martin.skold@mysql.com-20101014083757-5qo48b86d69zjvzj) (version source revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh) (merge vers: 5.5.5-m3) (pib:21)
[14 Oct 2010 9:00] Bugs System
Pushed into mysql-5.1-telco-6.2 5.1.51-ndb-6.2.19 (revid:martin.skold@mysql.com-20101014084420-y54ecj85j5we27oa) (version source revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh) (merge vers: 5.5.5-m3) (pib:21)
[14 Oct 2010 15:27] Jon Stephens
Already documented in the 5.1.48 changelog; no new changelog entries required. setting back to Closed state.