Commit 463ac89d authored by unknown's avatar unknown
Browse files

Fixed BUG#9680: Wrong error from cascading update

  Applied 9680.patch (by Osku Salerma)

parent 4f9e66da
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -367,8 +367,11 @@ enum ha_base_keytype {
                                          given value */
#define HA_ERR_RBR_LOGGING_FAILED 161  /* Row-based binlogging of row failed */
#define HA_ERR_DROP_INDEX_FK      162  /* Index needed in foreign key constr. */
#define HA_ERR_FOREIGN_DUPLICATE_KEY 163 /* Upholding foreign key constraints
                                            would lead to a duplicate key
                                            error in some other table. */

#define HA_ERR_LAST               162  /* Copy last error no */
#define HA_ERR_LAST               163  /* Copy last error no */

/* Add error numbers before HA_ERR_LAST and change it accordingly. */
#define HA_ERR_ERRORS            (HA_ERR_LAST - HA_ERR_FIRST + 1)
+18 −0
Original line number Diff line number Diff line
@@ -2758,3 +2758,21 @@ e varchar(255) character set utf8,
key (a,b,c,d,e)) engine=innodb;
ERROR 42000: Specified key was too long; max key length is 3072 bytes
End of 5.0 tests
CREATE TABLE t1 (
field1 varchar(8) NOT NULL DEFAULT '',
field2 varchar(8) NOT NULL DEFAULT '',
PRIMARY KEY  (field1, field2)
) ENGINE=InnoDB;
CREATE TABLE t2 (
field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
FOREIGN KEY (field1) REFERENCES t1 (field1)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('old', 'somevalu');
INSERT INTO t1 VALUES ('other', 'anyvalue');
INSERT INTO t2 VALUES ('old');
INSERT INTO t2 VALUES ('other');
UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';
ERROR 23000: Upholding foreign key constraints for table 't1', entry 'other-somevalu', key 1 would lead to a duplicate entry
DROP TABLE t2;
DROP TABLE t1;
+29 −0
Original line number Diff line number Diff line
@@ -1715,3 +1715,32 @@ create table t1 (a varchar(255) character set utf8,
                 key (a,b,c,d,e)) engine=innodb;

--echo End of 5.0 tests

#
# Test that cascading updates leading to duplicate keys give the correct
# error message (bug #9680)
#

CREATE TABLE t1 (
  field1 varchar(8) NOT NULL DEFAULT '',
  field2 varchar(8) NOT NULL DEFAULT '',
  PRIMARY KEY  (field1, field2)
) ENGINE=InnoDB;

CREATE TABLE t2 (
  field1 varchar(8) NOT NULL DEFAULT '' PRIMARY KEY,
  FOREIGN KEY (field1) REFERENCES t1 (field1)
    ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;

INSERT INTO t1 VALUES ('old', 'somevalu');
INSERT INTO t1 VALUES ('other', 'anyvalue');

INSERT INTO t2 VALUES ('old');
INSERT INTO t2 VALUES ('other');

--error ER_FOREIGN_DUPLICATE_KEY
UPDATE t1 SET field1 = 'other' WHERE field2 = 'somevalu';

DROP TABLE t2;
DROP TABLE t1;
+4 −0
Original line number Diff line number Diff line
@@ -465,6 +465,10 @@ convert_error_code_to_mysql(

    		return(HA_ERR_FOUND_DUPP_KEY);

  	} else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {

		return(HA_ERR_FOREIGN_DUPLICATE_KEY);

 	} else if (error == (int) DB_RECORD_NOT_FOUND) {

    		return(HA_ERR_NO_ACTIVE_RECORD);
+27 −2
Original line number Diff line number Diff line
@@ -358,6 +358,7 @@ static int ha_init_errors(void)
  SETMSG(HA_ERR_TABLE_EXIST,            ER(ER_TABLE_EXISTS_ERROR));
  SETMSG(HA_ERR_NO_CONNECTION,          "Could not connect to storage engine");
  SETMSG(HA_ERR_TABLE_DEF_CHANGED,      ER(ER_TABLE_DEF_CHANGED));
  SETMSG(HA_ERR_FOREIGN_DUPLICATE_KEY,  "FK constraint would lead to duplicate key");

  /* Register the error messages for use with my_error(). */
  return my_error_register(errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -1868,6 +1869,29 @@ void handler::print_error(int error, myf errflag)
    textno=ER_DUP_KEY;
    break;
  }
  case HA_ERR_FOREIGN_DUPLICATE_KEY:
  {
    uint key_nr= get_dup_key(error);
    if ((int) key_nr >= 0)
    {
      /* Write the key in the error message */
      char key[MAX_KEY_LENGTH];
      String str(key,sizeof(key),system_charset_info);
      /* Table is opened and defined at this point */
      key_unpack(&str,table,(uint) key_nr);
      uint max_length= MYSQL_ERRMSG_SIZE-(uint) strlen(ER(ER_FOREIGN_DUPLICATE_KEY));
      if (str.length() >= max_length)
      {
        str.length(max_length-4);
        str.append(STRING_WITH_LEN("..."));
      }
      my_error(ER_FOREIGN_DUPLICATE_KEY, MYF(0), table_share->table_name.str,
        str.c_ptr(), key_nr+1);
      DBUG_VOID_RETURN;
    }
    textno= ER_DUP_KEY;
    break;
  }
  case HA_ERR_NULL_IN_SPATIAL:
    textno= ER_UNKNOWN_ERROR;
    break;
@@ -2003,8 +2027,9 @@ uint handler::get_dup_key(int error)
{
  DBUG_ENTER("handler::get_dup_key");
  table->file->errkey  = (uint) -1;
  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE ||
      error == HA_ERR_NULL_IN_SPATIAL || error == HA_ERR_DROP_INDEX_FK)
  if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOREIGN_DUPLICATE_KEY ||
      error == HA_ERR_FOUND_DUPP_UNIQUE || error == HA_ERR_NULL_IN_SPATIAL ||
      error == HA_ERR_DROP_INDEX_FK)
    info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK);
  DBUG_RETURN(table->file->errkey);
}
Loading