views:

52

answers:

0

MySQL Bug #11472 confirms that when rows of a tableB are updated/deleted indirectly as a result of a FK constraint (relating tableA), triggers on tableB are not executed.

How can I workaround this bug? I found a messy workaround, but would like to hear the SO communities suggestions as well.

In this example joins has a FK to users and also cars. In this scenario, when a user is deleted, both the join and the car ought be deleted as well. To delete the car a trigger is created on joins to simulate the cascade.

CREATE TABLE `users` (
  `id` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `cars` (
  `id` varchar(10) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

CREATE TABLE `joins` (
  `user_id` varchar(10) NOT NULL,
  `car_id` varchar(10) NOT NULL,
  PRIMARY KEY (`user_id`,`car_id`),
  FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE,
  FOREIGN KEY (`car_id`) REFERENCES `cars` (`id`)
) ENGINE=InnoDB;

CREATE TRIGGER `on_delete_cascade_car`
  AFTER DELETE ON `joins`
FOR EACH ROW
  DELETE FROM `cars` WHERE `id` = OLD.`car_id`;

INSERT INTO users (`id`) VALUES ('Alice'), ('Bob');
INSERT INTO cars (`id`) VALUES ('Audi'), ('BMW');
INSERT INTO joins (`user_id`, `car_id`) VALUES ('Alice','Audi'), ('Bob','BMW');

-- delete a user (to show failed cascade) and a join (to show working trigger)
DELETE FROM users WHERE id = 'Alice';
DELETE FROM joins WHERE user_id = 'Bob';

-- shows cascade and direct delete worked
SELECT * FROM joins;
-- shows direct delete of Alice worked
SELECT * FROM users;
-- trigger deleted BMW when Bob|BMW join was directly deleted, but not Audi following cascaded delete
SELECT * FROM cars;