From: Date: January 19 2005 8:15am Subject: bk commit into 5.0 tree (jan:1.1812) List-Archive: http://lists.mysql.com/internals/20859 Message-Id: <200501190715.j0J7FxOR026220@hundin.mysql.fi> Below is the list of changes that have just been committed into a local 5.0 repository of jan. When jan does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://www.mysql.com/doc/I/n/Installing_source_tree.html ChangeSet 1.1812 05/01/19 09:15:50 jan@stripped +2 -0 Fixed a bug: deadlock without any locking, simple select and update (Bug #7975). sql/ha_innodb.cc 1.146 05/01/19 09:15:08 jan@stripped +15 -4 INSERT ON DUPLICATE KEY UPDATE will also update duplicate key and we should take X-lock in this case for duplicate key records. innobase/row/row0ins.c 1.58 05/01/19 09:15:08 jan@stripped +23 -18 If the SQL-query will update or replace duplicate key row we take X-lcok for duplicate row. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: jan # Host: hundin.mysql.fi # Root: /home/jan/orig/mysql-5.0 --- 1.57/innobase/row/row0ins.c Wed Jan 12 18:21:37 2005 +++ 1.58/innobase/row/row0ins.c Wed Jan 19 09:15:08 2005 @@ -51,14 +51,19 @@ chars count */ /********************************************************************** -This function returns true if SQL-query in the current thread +This function returns true if + +1) SQL-query in the current thread is either REPLACE or LOAD DATA INFILE REPLACE. + +2) SQL-query in the current thread +is INSERT ON DUPLICATE KEY UPDATE. + NOTE that /mysql/innobase/row/row0ins.c must contain the prototype for this function ! */ ibool -innobase_query_is_replace(void); -/*===========================*/ +innobase_query_is_update(void); /************************************************************************* Creates an insert node struct. */ @@ -1610,12 +1615,12 @@ offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); - if (innobase_query_is_replace()) { + if (innobase_query_is_update()) { - /* The manual defines the REPLACE semantics that it - is either an INSERT or DELETE(s) for duplicate key - + INSERT. Therefore, we should take X-lock for - duplicates */ + /* If the SQL-query will update or replace + duplicate key we will take X-lock for + duplicates ( REPLACE, LOAD DATAFILE REPLACE, + INSERT ON DUPLICATE KEY UPDATE). */ err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY, rec, index, offsets, thr); @@ -1733,12 +1738,12 @@ sure that in roll-forward we get the same duplicate errors as in original execution */ - if (innobase_query_is_replace()) { + if (innobase_query_is_update()) { - /* The manual defines the REPLACE semantics - that it is either an INSERT or DELETE(s) - for duplicate key + INSERT. Therefore, we - should take X-lock for duplicates */ + /* If the SQL-query will update or replace + duplicate key we will take X-lock for + duplicates ( REPLACE, LOAD DATAFILE REPLACE, + INSERT ON DUPLICATE KEY UPDATE). */ err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP,rec,cursor->index, @@ -1772,12 +1777,12 @@ offsets = rec_get_offsets(rec, cursor->index, offsets, ULINT_UNDEFINED, &heap); - /* The manual defines the REPLACE semantics that it - is either an INSERT or DELETE(s) for duplicate key - + INSERT. Therefore, we should take X-lock for - duplicates. */ + if (innobase_query_is_update()) { - if (innobase_query_is_replace()) { + /* If the SQL-query will update or replace + duplicate key we will take X-lock for + duplicates ( REPLACE, LOAD DATAFILE REPLACE, + INSERT ON DUPLICATE KEY UPDATE). */ err = row_ins_set_exclusive_rec_lock( LOCK_REC_NOT_GAP, rec, --- 1.145/sql/ha_innodb.cc Sat Jan 15 14:37:05 2005 +++ 1.146/sql/ha_innodb.cc Wed Jan 19 09:15:08 2005 @@ -6116,13 +6116,19 @@ extern "C" { /********************************************************************** -This function returns true if SQL-query in the current thread +This function returns true if + +1) SQL-query in the current thread is either REPLACE or LOAD DATA INFILE REPLACE. + +2) SQL-query in the current thread +is INSERT ON DUPLICATE KEY UPDATE. + NOTE that /mysql/innobase/row/row0ins.c must contain the prototype for this function ! */ ibool -innobase_query_is_replace(void) +innobase_query_is_update(void) /*===========================*/ { THD* thd; @@ -6134,9 +6140,14 @@ ( thd->lex->sql_command == SQLCOM_LOAD && thd->lex->duplicates == DUP_REPLACE )) { return true; - } else { - return false; } + + if ( thd->lex->sql_command == SQLCOM_INSERT && + thd->lex->duplicates == DUP_UPDATE ) { + return true; + } + + return false; } }