diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index 70bd082d1eabc..24530ab3475e2 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3490,3 +3490,36 @@ prepare stmt from "update t1 set f03 = ?"; execute stmt using default; drop table t1; # End of 10.6 test +# +# MDEV-40874 Difference in affected row count on UPDATE ... SET col=DEFAULT +# +# A NULL row set back to its NULL default is unchanged and must report +# Changed: 0, identically for every engine. compare_record() used to +# compare the undefined data bytes of a NULL field, so stale bytes made +# the row look changed. +create table t1 (c decimal(8,3)) engine=InnoDB; +affected rows: 0 +insert into t1 values (null); +affected rows: 1 +update t1 set c=default; +affected rows: 0 +info: Rows matched: 1 Changed: 0 Warnings: 0 +drop table t1; +affected rows: 0 +create table t1 (c decimal(8,3)) engine=Aria; +affected rows: 0 +insert into t1 values (null); +affected rows: 1 +update t1 set c=default; +affected rows: 0 +info: Rows matched: 1 Changed: 0 Warnings: 0 +# A real change is still detected +update t1 set c=1.5; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +# Setting DEFAULT (NULL) over a non-NULL value is a change +update t1 set c=default; +affected rows: 1 +info: Rows matched: 1 Changed: 1 Warnings: 0 +drop table t1; +# End of 10.11 test diff --git a/mysql-test/main/default.test b/mysql-test/main/default.test index 2e67d31d06b84..7fda567e811c0 100644 --- a/mysql-test/main/default.test +++ b/mysql-test/main/default.test @@ -2193,3 +2193,29 @@ execute stmt using default; drop table t1; --echo # End of 10.6 test + +--echo # +--echo # MDEV-40874 Difference in affected row count on UPDATE ... SET col=DEFAULT +--echo # +--echo # A NULL row set back to its NULL default is unchanged and must report +--echo # Changed: 0, identically for every engine. compare_record() used to +--echo # compare the undefined data bytes of a NULL field, so stale bytes made +--echo # the row look changed. +--source include/have_innodb.inc +--source include/have_maria.inc +--enable_info +create table t1 (c decimal(8,3)) engine=InnoDB; +insert into t1 values (null); +update t1 set c=default; +drop table t1; +create table t1 (c decimal(8,3)) engine=Aria; +insert into t1 values (null); +update t1 set c=default; +--echo # A real change is still detected +update t1 set c=1.5; +--echo # Setting DEFAULT (NULL) over a non-NULL value is a change +update t1 set c=default; +--disable_info +drop table t1; + +--echo # End of 10.11 test diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a50b52456474a..a62e1e54b871f 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -96,6 +96,8 @@ bool compare_record(const TABLE *table) if (((table->record[0][null_byte_index]) & field->null_bit) != ((table->record[1][null_byte_index]) & field->null_bit)) return TRUE; + if (field->is_null()) + continue; } if (field->cmp_binary_offset(table->s->rec_buff_length)) return TRUE; @@ -121,6 +123,7 @@ bool compare_record(const TABLE *table) { Field *field= *ptr; if (field->has_explicit_value() && !field->vcol_info && + !field->is_null() && field->cmp_binary_offset(table->s->rec_buff_length)) return TRUE; } diff --git a/sql/table.cc b/sql/table.cc index d46d81b451204..e2d0a179b73e1 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -3467,7 +3467,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write, share->last_null_bit_pos= null_bit_pos; share->null_bytes_for_compare= null_bits_are_used ? share->null_bytes : 0; share->can_cmp_whole_record= (share->blob_fields == 0 && - share->varchar_fields == 0); + share->varchar_fields == 0 && + !null_bits_are_used); data_start= share->default_values; data_end= data_start + share->reclength;