2

I have a simple MySQL database with some foreign keys on certain table columns. Some of the foreign key columns are set to ON DELETE SET NULL, and it seems to work fine. However, for one of the tables, I can't configure ON DELETE SET NULL - I can only configure ON DELETE CASCADE.

The initial tables look like this:

CREATE TABLE sessions(
session_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_sessions(name))
COLLATE utf8_unicode_ci;

CREATE TABLE blocks(
block_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_blocks(name))
COLLATE utf8_unicode_ci;

CREATE TABLE edot(
edah_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
name varchar(50) NOT NULL,
UNIQUE KEY uk_edot(name))
COLLATE utf8_unicode_ci;

CREATE TABLE campers(
camper_id int NOT NULL AUTO_INCREMENT PRIMARY KEY,
edah_id int,
FOREIGN KEY fk_edah_id(edah_id) REFERENCES edot(edah_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
first varchar(50) NOT NULL,
last varchar(50) NOT NULL,
email varchar(50) NOT NULL,
needs_first_choice bool DEFAULT 0,
active bool NOT NULL DEFAULT 1)
COLLATE utf8_unicode_ci;

The above all works fine. The problem comes when I try to do this:

CREATE TABLE block_instances(
block_id int NOT NULL,
FOREIGN KEY fk_block_id(block_id) REFERENCES blocks(block_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE SET NULL
ON UPDATE CASCADE,
PRIMARY KEY pk_block_instances(block_id, session_id))
COLLATE utf8_unicode_ci;

This returns

ERROR 1005 (HY000): Can't create table 'chugbot_db.block_instances' (errno: 150)

The error goes away if I change the second ON DELETE SET NULL to ON DELETE CASCADE:

CREATE TABLE block_instances(
block_id int NOT NULL,
FOREIGN KEY fk_block_id(block_id) REFERENCES blocks(block_id)
ON DELETE CASCADE
ON UPDATE CASCADE,
session_id int,
FOREIGN KEY fk_session_id(session_id) REFERENCES sessions(session_id)
ON DELETE **CASCADE**
ON UPDATE CASCADE,
PRIMARY KEY pk_block_instances(block_id, session_id))
COLLATE utf8_unicode_ci;

works fine.

Can anyone tell me what is wrong with using ON DELETE SET NULL in the block_instances table here? It seems exactly the same as the ON DELETE SET NULL in the campers table.

David Lobron
  • 1,039
  • 2
  • 12
  • 21
  • 2
    Is the column session_id nullable ? – Daan Dec 03 '15 at 15:31
  • Yes, it should be. Per the SQL above, it does not have a NOT NULL constraint. – David Lobron Dec 03 '15 at 15:44
  • @DavidLobron the point here is that the target table's column (`sessions.session_id`) must be nullable if you want it to be `SET NULL` on `CASCADE`. – Jiri Tousek Dec 03 '15 at 15:46
  • @JiriTousek: The session_id int NOT NULL is in the original table, but not the referring table. I think that should be fine. The table that works, "campers" has "ON DELETE SET NULL" on session_id, and it's fine. But when I try to do the same thing in block_instances, it fails - I don't understand why. – David Lobron Dec 03 '15 at 15:47
  • @DavidLobron I stand corrected, I got the FK direction confused. – Jiri Tousek Dec 03 '15 at 15:48
  • @DavidLobron advice from [another question](http://stackoverflow.com/a/18180299/5375403): run `SHOW ENGINE INNODB STATUS;` and then look for "LATEST FOREIGN KEY ERROR" in the output. Should give use some more useful info. – Jiri Tousek Dec 03 '15 at 15:58
  • @JiriTousek: Thanks! I did that, and the error is reported as "You have defined a SET NULL condition though some of the columns are defined as NOT NULL." I'm still confused, though, because the FK column is definitely allowed to be NULL (I even updated my SQL to explicitly label it NULL, but the error persists). – David Lobron Dec 03 '15 at 17:20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/96909/discussion-between-david-lobron-and-jiri-tousek). – David Lobron Dec 03 '15 at 17:26

1 Answers1

0

This turned out to be a bug in MySQL:

http://bugs.mysql.com/bug.php?id=80052

David Lobron
  • 1,039
  • 2
  • 12
  • 21