List:Internals« Previous MessageNext Message »
From:Timothy P Clark Date:May 5 2008 6:15pm
Subject:Handling duplicates for REPLACE
View as plain text  
The storage engine that I am developing handles error reporting for
duplicate key values differently than MySQL expects. Specifically, when a
row causes duplicate value conflicts with multiple keys, only the last key
that caused the dup error is known. However, MySQL expects the keys to be
reported in ascending order.

For example, for the following sequence:
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'. Our storage engine always reports 'b' before 'a'.

This causes a problem in sql_insert.cc::write_record() when a REPLACE
command is executed, because the loop that retries the replace after a
duplicate key error depends on the ascending key order. As a result, the
REPLACE command above will fail for our storage engine and return "ERROR
1062 (23000): Duplicate entry '1' for key 'b'".

I have a possible workaround, which is to always set handler::errkey to 0
when (thd_sql_command() == SQLCOM_REPLACE*). This seems to work for the
limited set of operations that I have tried and a quick inspection of
write_row leads me to believe that this should be OK. Can anyone convince
me that this is a bad idea?

Thank you,
Tim Clark

Thread
Handling duplicates for REPLACETimothy P Clark5 May 2008
  • re: Handling duplicates for REPLACEMichael Widenius6 May 2008
  • Re: Handling duplicates for REPLACESergei Golubchik6 May 2008
    • Re: Handling duplicates for REPLACESergei Golubchik7 Jul 2008
      • Re: Handling duplicates for REPLACETimothy P Clark7 Jul 2008