diff options
author | V Narayanan <v.narayanan@sun.com> | 2009-12-03 16:48:02 +0530 |
---|---|---|
committer | V Narayanan <v.narayanan@sun.com> | 2009-12-03 16:48:02 +0530 |
commit | 21aaf8dded17341805afd72539bc7606ebb0b46a (patch) | |
tree | be9cb37a33ba0768627bad6cd8993618a017ac7a | |
parent | 40ec012c905be0262ba5c36bbccfa0db0105e31f (diff) | |
download | mariadb-git-21aaf8dded17341805afd72539bc7606ebb0b46a.tar.gz |
WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order
Introduce a flag that will enable the REPLACE
command to work correctly with an underlying
storage engine that does not report unique key
conflicts in the ascending order.
sql/handler.h:
WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order
Adds the flag that will be set by a
SE that does not report unique key
conflicts in the ascending order.
sql/sql_insert.cc:
WL#4454 change sql_insert.cc::last_uniq_key to match keys in any order
modifies the function used for a last row
replace optimization to check for the
HA_DUPLICATE_KEY_NOT_IN_ORDER flag.
-rw-r--r-- | sql/handler.h | 23 | ||||
-rw-r--r-- | sql/sql_insert.cc | 17 |
2 files changed, 40 insertions, 0 deletions
diff --git a/sql/handler.h b/sql/handler.h index 05a9e13653c..8e8f417739e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -127,6 +127,29 @@ */ #define HA_BINLOG_ROW_CAPABLE (LL(1) << 34) #define HA_BINLOG_STMT_CAPABLE (LL(1) << 35) +/* + When a multiple key conflict happens in a REPLACE command mysql + expects the conflicts to be reported in the ascending order of + key names. + + For e.g. + + CREATE TABLE t1 (a INT, UNIQUE (a), b INT NOT NULL, UNIQUE (b), c INT NOT + NULL, INDEX(c)); + + REPLACE INTO t1 VALUES (1,1,1),(2,2,2),(2,1,3); + + MySQL expects the conflict with 'a' to be reported before the conflict with + 'b'. + + If the underlying storage engine does not report the conflicting keys in + ascending order, it causes unexpected errors when the REPLACE command is + executed. + + This flag helps the underlying SE to inform the server that the keys are not + ordered. +*/ +#define HA_DUPLICATE_KEY_NOT_IN_ORDER (LL(1) << 36) /* Set of all binlog flags. Currently only contain the capabilities diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index b1c7c7f647e..988c91e3168 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1322,6 +1322,23 @@ bool mysql_prepare_insert(THD *thd, TABLE_LIST *table_list, static int last_uniq_key(TABLE *table,uint keynr) { + /* + When an underlying storage engine informs that the unique key + conflicts are not reported in the ascending order by setting + the HA_DUPLICATE_KEY_NOT_IN_ORDER flag, we cannot rely on this + information to determine the last key conflict. + + The information about the last key conflict will be used to + do a replace of the new row on the conflicting row, rather + than doing a delete (of old row) + insert (of new row). + + Hence check for this flag and disable replacing the last row + by returning 0 always. Returning 0 will result in doing + a delete + insert always. + */ + if (table->file->ha_table_flags() & HA_DUPLICATE_KEY_NOT_IN_ORDER) + return 0; + while (++keynr < table->s->keys) if (table->key_info[keynr].flags & HA_NOSAME) return 0; |