diff --git a/storage/innodb_plugin/include/rem0cmp.h b/storage/innodb_plugin/include/rem0cmp.h index 072f742..82a70aa 100644 --- a/storage/innodb_plugin/include/rem0cmp.h +++ b/storage/innodb_plugin/include/rem0cmp.h @@ -148,7 +148,9 @@ cmp_rec_rec_simple( const rec_t* rec2, /*!< in: physical record */ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */ - const dict_index_t* index); /*!< in: data dictionary index */ + const dict_index_t* index, /*!< in: data dictionary index */ + ibool* null_eq);/*!< out: set to true if + found matching null values */ /*************************************************************//** This function is used to compare two physical records. Only the common first fields are compared, and if an externally stored field is diff --git a/storage/innodb_plugin/rem/rem0cmp.c b/storage/innodb_plugin/rem/rem0cmp.c index e6dab0b..5c2bcbb 100644 --- a/storage/innodb_plugin/rem/rem0cmp.c +++ b/storage/innodb_plugin/rem/rem0cmp.c @@ -706,7 +706,9 @@ cmp_rec_rec_simple( const rec_t* rec2, /*!< in: physical record */ const ulint* offsets1,/*!< in: rec_get_offsets(rec1, ...) */ const ulint* offsets2,/*!< in: rec_get_offsets(rec2, ...) */ - const dict_index_t* index) /*!< in: data dictionary index */ + const dict_index_t* index, /*!< in: data dictionary index */ + ibool* null_eq)/*!< out: set to true if + found matching null values */ { ulint rec1_f_len; /*!< length of current field in rec1 */ const byte* rec1_b_ptr; /*!< pointer to the current byte @@ -727,6 +729,10 @@ cmp_rec_rec_simple( ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2)); + if (null_eq) { + *null_eq = 0; + } + for (cur_field = 0; cur_field < n_uniq; cur_field++) { ulint cur_bytes; @@ -753,6 +759,9 @@ cmp_rec_rec_simple( || rec2_f_len == UNIV_SQL_NULL) { if (rec1_f_len == rec2_f_len) { + if (null_eq) { + *null_eq = 1; + } goto next_field; diff --git a/storage/innodb_plugin/row/row0merge.c b/storage/innodb_plugin/row/row0merge.c index 88a2770..77233ae 100644 --- a/storage/innodb_plugin/row/row0merge.c +++ b/storage/innodb_plugin/row/row0merge.c @@ -1075,11 +1075,13 @@ row_merge_cmp( record to be compared */ const ulint* offsets1, /*!< in: first record offsets */ const ulint* offsets2, /*!< in: second record offsets */ - const dict_index_t* index) /*!< in: index */ + const dict_index_t* index, /*!< in: index */ + ibool* null_eq) /*!< out: set to true if + found matching null values */ { int cmp; - cmp = cmp_rec_rec_simple(mrec1, mrec2, offsets1, offsets2, index); + cmp = cmp_rec_rec_simple(mrec1, mrec2, offsets1, offsets2, index, null_eq); #ifdef UNIV_DEBUG if (row_merge_print_cmp) { @@ -1445,11 +1447,13 @@ corrupt: } while (mrec0 && mrec1) { + ibool null_eq = 0; switch (row_merge_cmp(mrec0, mrec1, - offsets0, offsets1, index)) { + offsets0, offsets1, index, + &null_eq)) { case 0: if (UNIV_UNLIKELY - (dict_index_is_unique(index))) { + (dict_index_is_unique(index) && !null_eq)) { innobase_rec_to_mysql(table, mrec0, index, offsets0); mem_heap_free(heap);