li7y/migrations/20240806120210_item_class_unlimited_depth.up.sql

51 lines
1.2 KiB
MySQL
Raw Permalink Normal View History

-- SPDX-FileCopyrightText: 2024 Simon Bruder <simon@sbruder.de>
--
-- SPDX-License-Identifier: AGPL-3.0-or-later
DROP TRIGGER prevent_item_class_recursion ON item_classes;
DROP FUNCTION check_item_class_recursion_depth;
CREATE FUNCTION check_item_class_cycle()
RETURNS TRIGGER AS $$
BEGIN
IF NEW.parent IS NULL THEN
RETURN NEW;
END IF;
IF NEW.id = NEW.parent THEN
RAISE EXCEPTION 'Cycle detected';
END IF;
IF (WITH RECURSIVE cte AS (
SELECT id, parent
FROM item_classes
WHERE id = NEW.parent
UNION ALL
SELECT item_classes.id, item_classes.parent
FROM item_classes, cte
WHERE item_classes.id = cte.parent
)
SELECT 1
FROM cte
WHERE parent = NEW.id
LIMIT 1) THEN
RAISE EXCEPTION 'Cycle detected';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER prevent_item_class_cycle
BEFORE INSERT OR UPDATE ON item_classes
FOR EACH ROW
EXECUTE FUNCTION check_item_class_cycle();
CREATE RECURSIVE VIEW item_class_tree (id, parents) AS (
SELECT id, ARRAY[]::UUID[] AS parents FROM item_classes WHERE parent IS NULL
UNION ALL
SELECT item_classes.id, item_class_tree.parents || item_classes.parent FROM item_classes, item_class_tree WHERE item_classes.parent = item_class_tree.id
);