Commit 976f0a39 authored by unknown's avatar unknown
Browse files

Bug#19978: INSERT .. ON DUPLICATE erroneously reports some records were

updated.

INSERT ... ON DUPLICATE KEY UPDATE reports that a record was updated when
the duplicate key occurs even if the record wasn't actually changed
because the update values are the same as those in the record.

Now the compare_record() function is used to check whether the record was
changed and the update of a record reported only if the record differs
from the original one.


sql/sql_update.cc:
  Bug#19978: INSERT .. ON DUPLICATE erroneously reports some records were
  updated.
  The compare_record() function was changed to non-static one.
sql/sql_insert.cc:
  Bug#19978: INSERT .. ON DUPLICATE erroneously reports some records were
  updated.
  Now the compare_record() function is used to check whether the record was
  changed and the update of a record reported only if the record differs
  from the original one.
sql/mysql_priv.h:
  Bug#19978: INSERT .. ON DUPLICATE erroneously reports some records were
  updated.
  Added the prototype of the compare_record() function.
mysql-test/t/insert_select.test:
  Added a test case for bug#19978: INSERT .. ON DUPLICATE erroneously reports
  some records were updated.
mysql-test/r/insert_select.result:
  Added a test case for bug#19978: INSERT .. ON DUPLICATE erroneously reports
  some records were updated.
parent c35ceeca
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -705,3 +705,15 @@ use bug21774_1;
INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1;
DROP DATABASE bug21774_1;
DROP DATABASE bug21774_2;
USE test;
create table t1(f1 int primary key, f2 int);
insert into t1 values (1,1);
affected rows: 1
insert into t1 values (1,1) on duplicate key update f2=1;
affected rows: 0
insert into t1 values (1,1) on duplicate key update f2=2;
affected rows: 2
select * from t1;
f1	f2
1	2
drop table t1;
+13 −0
Original line number Diff line number Diff line
@@ -265,4 +265,17 @@ INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1;

DROP DATABASE bug21774_1;
DROP DATABASE bug21774_2;
USE test;

#
# Bug#19978: INSERT .. ON DUPLICATE erroneously reports some records were
#            updated.
#
create table t1(f1 int primary key, f2 int);
--enable_info
insert into t1 values (1,1);
insert into t1 values (1,1) on duplicate key update f2=1;
insert into t1 values (1,1) on duplicate key update f2=2;
--disable_info
select * from t1;
drop table t1;
+1 −0
Original line number Diff line number Diff line
@@ -701,6 +701,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
		      char* packet, uint packet_length);
void log_slow_statement(THD *thd);
bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
bool compare_record(TABLE *table, query_id_t query_id);

bool table_cache_init(void);
void table_cache_free(void);
+16 −10
Original line number Diff line number Diff line
@@ -1194,15 +1194,21 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
          }
          goto err;
        }
        if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) ||
            compare_record(table, query_id))
        {
          info->updated++;

          if (table->next_number_field)
          table->file->adjust_next_insert_id_after_explicit_value(table->next_number_field->val_int());
            table->file->adjust_next_insert_id_after_explicit_value(
              table->next_number_field->val_int());

          trg_error= (table->triggers &&
                      table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
                                                      TRG_ACTION_AFTER, TRUE));
                                                        TRG_ACTION_AFTER,
                                                        TRUE));
          info->copied++;
        }
        goto ok_or_after_trg_err;
      }
      else /* DUP_REPLACE */
+1 −1
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@

/* Return 0 if row hasn't changed */

static bool compare_record(TABLE *table, query_id_t query_id)
bool compare_record(TABLE *table, query_id_t query_id)
{
  if (table->s->blob_fields + table->s->varchar_fields == 0)
    return cmp_record(table,record[1]);