Bug #22327 Foreign key constraint fails when it shouldn't
Submitted: 13 Sep 2006 23:08 Modified: 14 Sep 2006 19:43
Reporter: Akita Bright-Holloway Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server Severity:S2 (Serious)
Version:5.0.24a OS:Linux (linux, freebsd)
Assigned to: CPU Architecture:Any

[13 Sep 2006 23:08] Akita Bright-Holloway
Description:
Foreign key constraint fails when it shouldn't, but only when statements are executed from within a function and there is existing data in table `a`, and not in table b.

In example, the following similar bits of code work (presuming the tables and functions from the 'How to repeat' section have been loaded')

   select ins();

This works by it self. Its only when the prior INSERT INTO a (`a_id`) VALUES (1); has been executed does it fail.

  
  INSERT INTO a (`a_id`) VALUES (1);

  INSERT INTO a () VALUES ();
  SELECT last_insert_id() INTO @new_a_id;

  INSERT INTO b () VALUES ();
  SELECT last_insert_id() INTO @new_b_id;

  INSERT INTO a_to_b (a_id     , b_id    ) 
    VALUES           (@new_a_id , @new_b_id);

This also works. (which is essentially just expanding the execution of function `ins`). Note that the initial insert into `a` that breaks the call to `ins` is still there.

Additionally, data in table `b` doesn't seem to cause a problem, since 

  INSERT INTO b (`b_id`) VALUES (1);
  select ins();

works. Also, it seems as if there is no problem if there is data in both tables a and be, since 

  INSERT INTO a (`a_id`) VALUES (1);
  INSERT INTO b (`b_id`) VALUES (1);
  select ins();

works.

How to repeat:
CREATE TABLE a (
  `a_id`   INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY(a_id)
) ENGINE=InnoDB;

CREATE TABLE b (
  `b_id`    INT NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (b_id)
) ENGINE=InnoDB;

CREATE TABLE a_to_b (
  `a_id`   INT NOT NULL,
  `b_id`   INT NOT NULL,
  
  INDEX  (a_id),
  INDEX  (b_id),
  FOREIGN KEY (a_id) REFERENCES a(a_id),
  FOREIGN KEY (b_id) REFERENCES b(b_id)
) ENGINE=InnoDB;

DELIMITER |

CREATE FUNCTION ins()
    RETURNS INT 
    LANGUAGE SQL
    BEGIN
      DECLARE new_a_id INT ;
      DECLARE new_b_id INT ;

      INSERT INTO a () VALUES ();
      SELECT last_insert_id() INTO new_a_id;

      INSERT INTO b () VALUES ();
      SELECT last_insert_id() INTO new_b_id;

      INSERT INTO a_to_b (a_id     , b_id    ) 
         VALUES          (new_a_id , new_b_id);

      RETURN new_a_id;
    END |

DELIMITER ;

/* Time to have an error */
INSERT INTO a (`a_id`) VALUES (1);
select ins();
[14 Sep 2006 14:53] Akita Bright-Holloway
Error persists through version 5.0.24a as well, in case that was a question.
[14 Sep 2006 19:43] Sveta Smirnova
Please do not submit the same bug more than once. An existing bug report already describes this very problem. Even if you feel that your issue is somewhat different, the resolution is likely
to be the same. Because of this, we hope you add your comments to the original bug instead.

Thank you for your interest in MySQL.

Duplicates bug #21726