Bug #33376 Write set for table not set correctly when inserting an empty set
Submitted: 19 Dec 2007 17:35 Modified: 13 Jan 2012 9:26
Reporter: Mats Kindahl Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Row Based Replication ( RBR ) Severity:S2 (Serious)
Version:5.1, 6.0 bzr OS:Any
Assigned to: Assigned Account CPU Architecture:Any
Tags: disabled

[19 Dec 2007 17:35] Mats Kindahl
Description:
When trying to insert an empty set into column with an not null set, the write_set bit is clear instead of set. This affects row-based replication, since it relies on the read_set and write_set being correctly set.

How to repeat:
Execute the following code, while inspecting the write_set for the table. Suggest to place a breakpoint at ha_write_row(), or a function below it (unpack_row is called by ha_write_row, and this is where the problem surfaces).

    create table t1 (a set('a') not null);
    insert into t1 values ();

Suggested fix:
Set the bit in the write_set for the column even when inserting an empty set.
[20 Dec 2007 12:53] Sergei Golubchik
I'm not sure it's a bug. perhaps a bit is set in write_set only for those columns (on INSERT) that are set explicitly ? others are set to default values implicitly
[22 Aug 2008 6:23] Sveta Smirnova
Thank you for the report.

Sergei, according to http://forge.mysql.com/worklog/task.php?id=3281:

>  table->write_set contains a bitmap over all columns that will be updated
>  in the query. write_row() and update_row() only needs to update these
>  columns.
>  The above bitmaps should now be up to date in all context
>  (including ALTER TABLE, filesort()).

but

>  field->query_id is removed. One should instead instead check
>  table->read_set and table->write_set if a field is used in the query.

So is not clear if this behavior is expected.
[29 Aug 2008 9:43] Mats Kindahl
As I understand it, the default values are currently maintained, and specifically filled in, by the server and not by the storage engine. In other words, the storage engine cannot distinguish between values that were set explicitly or those that were set because they had a default. IMHO, forcing the storage engine writer to both check the table definition (if there is a default when the bit is clear) and the write_set seems to complicate matter unnecessarily.
[8 Sep 2008 9:40] Sveta Smirnova
Thank you for the feedback.

Verified as described:

$cat >t/bug33376.test
create table t1 (a set('a') not null);
insert into t1 values ();
insert into t1 values ('a');

$./mysql-test-run.pl --manual-gdb --record bug33376
...

$gdb ...
....
(gdb) b  handler::ha_write_row
Breakpoint 2 at 0x839e566: file handler.cc, line 4464.
(gdb) b write_record
Breakpoint 3 at 0x831489d: file sql_insert.cc, line 1327.
(gdb) c
Continuing.

Breakpoint 2, handler::ha_write_row (this=0x8edde50, buf=0x8ee1018 "e####031") at handler.cc:4464
4464      Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
(gdb) c
Continuing.

Breakpoint 2, handler::ha_write_row (this=0x8ed1548, buf=0x8ed4710 "g####031") at handler.cc:4464
4464      Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
(gdb) c
Continuing.

Breakpoint 3, write_record (thd=0x8e787d8, table=0x8ee4738, info=0xb7437380) at sql_insert.cc:1327
1327      int error, trg_error= 0;
(gdb) c
Continuing.

Breakpoint 2, handler::ha_write_row (this=0x8ee55e0, buf=0x8ee56f0 "#") at handler.cc:4464
4464      Log_func *log_func= Write_rows_log_event::binlog_row_logging_function;
(gdb) p this->table->in_use->query
$1 = 0x8ed5218 "insert into t1 values ()"
(gdb)  p (uint)(((uchar*)(this->table->write_set)->bitmap)[0/8]& (1 << ((0) & 7)))
$2 = 0
(gdb) c
Continuing.
...
[8 Oct 2008 23:00] Bugs System
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
[12 Oct 2008 9:37] Sveta Smirnova
Mats, please provide feedback requested.
[24 Oct 2008 8:57] Mats Kindahl
The test that Sveta does is correct, but I am starting to question what the intended behavior is supposed to be.

Assign it to me in the meantime and I will take a closer look.
[25 Nov 2008 13:39] Sergey Vojtovich
See also BUG#33670.
[28 May 2009 21:44] Sveta Smirnova
Bug #41616 was marked as duplicate of this one.
[4 May 2010 9:22] Luis Soares
See also: BUG#53386.