DELIMITER $$ CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `account`.`role_getDescendents`(vSelf INT) BEGIN /** * Gets the identifiers of all the subroles implemented by a role (Including * itself). * * @param vSelf The role identifier * @table tmp.role Subroles implemented by the role */ DECLARE vIsRoot BOOL; DROP TEMPORARY TABLE IF EXISTS tmp.role, parents, childs; CREATE TEMPORARY TABLE tmp.role (UNIQUE (id)) ENGINE = MEMORY SELECT vSelf AS id; CREATE TEMPORARY TABLE parents ENGINE = MEMORY SELECT vSelf AS id; CREATE TEMPORARY TABLE childs LIKE parents; REPEAT DELETE FROM childs; INSERT INTO childs SELECT DISTINCT r.inheritsFrom id FROM parents p JOIN roleInherit r ON r.role = p.id LEFT JOIN tmp.role t ON t.id = r.inheritsFrom WHERE t.id IS NULL; DELETE FROM parents; INSERT INTO parents SELECT * FROM childs; INSERT INTO tmp.role SELECT * FROM childs; UNTIL ROW_COUNT() <= 0 END REPEAT; -- If it is root all the roles are added SELECT COUNT(*) > 0 INTO vIsRoot FROM tmp.role t JOIN role r ON r.id = t.id WHERE r.`name` = 'root'; IF vIsRoot THEN INSERT IGNORE INTO tmp.role (id) SELECT id FROM role; END IF; -- Cleaning DROP TEMPORARY TABLE parents, childs; END$$ DELIMITER ;