summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorevgen@moonbone.local <>2007-02-07 00:46:03 +0300
committerevgen@moonbone.local <>2007-02-07 00:46:03 +0300
commit968369906efe7fa628caeb0e15731770161e7e7c (patch)
tree56c0e739bcc59645b6b36a4c468a1034d31858df
parent5092f7ab269c75273c791201eb0cc803a2f456ee (diff)
downloadmariadb-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.result12
-rw-r--r--mysql-test/t/insert_select.test13
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_insert.cc26
-rw-r--r--sql/sql_update.cc2
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]);