Commit 96836990 authored by evgen@moonbone.local's avatar evgen@moonbone.local

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.
parent 5092f7ab
...@@ -705,3 +705,15 @@ use bug21774_1; ...@@ -705,3 +705,15 @@ use bug21774_1;
INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1;
DROP DATABASE bug21774_1; DROP DATABASE bug21774_1;
DROP DATABASE bug21774_2; 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;
...@@ -265,4 +265,17 @@ INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1; ...@@ -265,4 +265,17 @@ INSERT INTO bug21774_2.t1 SELECT t1.* FROM t1;
DROP DATABASE bug21774_1; DROP DATABASE bug21774_1;
DROP DATABASE bug21774_2; 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;
...@@ -701,6 +701,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -701,6 +701,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char* packet, uint packet_length); char* packet, uint packet_length);
void log_slow_statement(THD *thd); void log_slow_statement(THD *thd);
bool check_dup(const char *db, const char *name, TABLE_LIST *tables); 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); bool table_cache_init(void);
void table_cache_free(void); void table_cache_free(void);
......
...@@ -1186,23 +1186,29 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) ...@@ -1186,23 +1186,29 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info)
goto before_trg_err; goto before_trg_err;
if ((error=table->file->update_row(table->record[1],table->record[0]))) if ((error=table->file->update_row(table->record[1],table->record[0])))
{ {
if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore) if ((error == HA_ERR_FOUND_DUPP_KEY) && info->ignore)
{ {
table->file->restore_auto_increment(); table->file->restore_auto_increment();
goto ok_or_after_trg_err; goto ok_or_after_trg_err;
} }
goto err; goto err;
} }
info->updated++; if ((table->file->table_flags() & HA_PARTIAL_COLUMN_READ) ||
compare_record(table, query_id))
{
info->updated++;
if (table->next_number_field) 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 && trg_error= (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE)); TRG_ACTION_AFTER,
info->copied++; TRUE));
info->copied++;
}
goto ok_or_after_trg_err; goto ok_or_after_trg_err;
} }
else /* DUP_REPLACE */ else /* DUP_REPLACE */
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
/* Return 0 if row hasn't changed */ /* 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) if (table->s->blob_fields + table->s->varchar_fields == 0)
return cmp_record(table,record[1]); return cmp_record(table,record[1]);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment