diff options
author | evgen@moonbone.local <> | 2007-02-07 00:46:03 +0300 |
---|---|---|
committer | evgen@moonbone.local <> | 2007-02-07 00:46:03 +0300 |
commit | 968369906efe7fa628caeb0e15731770161e7e7c (patch) | |
tree | 56c0e739bcc59645b6b36a4c468a1034d31858df | |
parent | 5092f7ab269c75273c791201eb0cc803a2f456ee (diff) | |
download | mariadb-git-968369906efe7fa628caeb0e15731770161e7e7c.tar.gz |
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.
-rw-r--r-- | mysql-test/r/insert_select.result | 12 | ||||
-rw-r--r-- | mysql-test/t/insert_select.test | 13 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_insert.cc | 26 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
5 files changed, 43 insertions, 11 deletions
diff --git a/mysql-test/r/insert_select.result b/mysql-test/r/insert_select.result index 1453d25ac75..82cc1b036a7 100644 --- a/mysql-test/r/insert_select.result +++ b/mysql-test/r/insert_select.result @@ -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; diff --git a/mysql-test/t/insert_select.test b/mysql-test/t/insert_select.test index 404d67390ab..6302d5f1dae 100644 --- a/mysql-test/t/insert_select.test +++ b/mysql-test/t/insert_select.test @@ -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; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ce5df434295..1ffcad12414 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -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); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index fb59aeea8e7..1ea01b07166 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1186,23 +1186,29 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) goto before_trg_err; 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(); goto ok_or_after_trg_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) - table->file->adjust_next_insert_id_after_explicit_value(table->next_number_field->val_int()); + if (table->next_number_field) + 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)); - info->copied++; + trg_error= (table->triggers && + table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, + TRG_ACTION_AFTER, + TRUE)); + info->copied++; + } goto ok_or_after_trg_err; } else /* DUP_REPLACE */ diff --git a/sql/sql_update.cc b/sql/sql_update.cc index b85c617b12d..04d341b5f67 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -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]); |