| 36406 |
amit |
1 |
-- Migration: Scheme Item Windowing (BRD Scheme-Item-Windowing)
|
|
|
2 |
-- Adds surrogate PK, audit columns, unique constraint, and safety triggers to fofo.scheme_item
|
|
|
3 |
|
|
|
4 |
-- Step 1: Add surrogate PK and audit columns
|
|
|
5 |
ALTER TABLE fofo.scheme_item
|
|
|
6 |
DROP PRIMARY KEY,
|
|
|
7 |
ADD COLUMN id BIGINT AUTO_INCREMENT PRIMARY KEY FIRST,
|
|
|
8 |
ADD COLUMN updated_by INT NULL,
|
|
|
9 |
ADD COLUMN updated_on TIMESTAMP NULL DEFAULT NULL;
|
|
|
10 |
|
|
|
11 |
-- Step 2: Backfill audit columns from existing data
|
|
|
12 |
UPDATE fofo.scheme_item SET updated_on = create_timestamp WHERE updated_on IS NULL;
|
|
|
13 |
|
|
|
14 |
-- Step 3: Add unique key on the 4-column business key
|
|
|
15 |
ALTER TABLE fofo.scheme_item
|
|
|
16 |
ADD UNIQUE KEY uk_scheme_item_window (catalog_id, scheme_id, start_date, end_date);
|
|
|
17 |
|
|
|
18 |
-- Step 4: Add index for date-driven lookups
|
|
|
19 |
CREATE INDEX idx_scheme_item_date_lookup ON fofo.scheme_item (catalog_id, scheme_id, start_date, end_date);
|
|
|
20 |
|
|
|
21 |
-- Step 4b: Drop the legacy 2-column unique constraint that survived the
|
|
|
22 |
-- DROP PRIMARY KEY in step 1. Without this, the old uniqueness on
|
|
|
23 |
-- (scheme_id, catalog_id) still blocks multiple windows for the same
|
|
|
24 |
-- (scheme, catalog) pair — defeating the whole windowing feature.
|
|
|
25 |
ALTER TABLE fofo.scheme_item DROP INDEX scheme_catalog;
|
|
|
26 |
|
|
|
27 |
-- Step 5: Safety triggers (MySQL 5.7 — CHECK constraints are parsed but ignored)
|
|
|
28 |
|
|
|
29 |
DELIMITER $$
|
|
|
30 |
|
|
|
31 |
CREATE TRIGGER trg_scheme_item_bi BEFORE INSERT ON fofo.scheme_item
|
|
|
32 |
FOR EACH ROW
|
|
|
33 |
BEGIN
|
|
|
34 |
DECLARE v_scheme_start DATETIME;
|
|
|
35 |
DECLARE v_scheme_end DATETIME;
|
|
|
36 |
DECLARE v_overlap_cnt INT;
|
|
|
37 |
|
|
|
38 |
-- Validate start <= end
|
|
|
39 |
IF NEW.start_date IS NOT NULL AND NEW.end_date IS NOT NULL AND NEW.start_date > NEW.end_date THEN
|
|
|
40 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: start_date must be <= end_date';
|
|
|
41 |
END IF;
|
|
|
42 |
|
|
|
43 |
-- Validate containment within parent scheme window
|
|
|
44 |
IF NEW.start_date IS NOT NULL AND NEW.end_date IS NOT NULL THEN
|
|
|
45 |
SELECT start_date_time, end_date_time INTO v_scheme_start, v_scheme_end
|
|
|
46 |
FROM catalog.scheme WHERE id = NEW.scheme_id;
|
|
|
47 |
|
|
|
48 |
IF NEW.start_date < v_scheme_start OR NEW.end_date > v_scheme_end THEN
|
|
|
49 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: window outside parent scheme window';
|
|
|
50 |
END IF;
|
|
|
51 |
|
|
|
52 |
-- Validate non-overlap within same (catalog_id, scheme_id)
|
|
|
53 |
SELECT COUNT(*) INTO v_overlap_cnt FROM fofo.scheme_item
|
|
|
54 |
WHERE catalog_id = NEW.catalog_id
|
|
|
55 |
AND scheme_id = NEW.scheme_id
|
|
|
56 |
AND NEW.start_date < end_date
|
|
|
57 |
AND NEW.end_date > start_date;
|
|
|
58 |
|
|
|
59 |
IF v_overlap_cnt > 0 THEN
|
|
|
60 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: window overlaps existing row';
|
|
|
61 |
END IF;
|
|
|
62 |
END IF;
|
|
|
63 |
END$$
|
|
|
64 |
|
|
|
65 |
CREATE TRIGGER trg_scheme_item_bu BEFORE UPDATE ON fofo.scheme_item
|
|
|
66 |
FOR EACH ROW
|
|
|
67 |
BEGIN
|
|
|
68 |
DECLARE v_scheme_start DATETIME;
|
|
|
69 |
DECLARE v_scheme_end DATETIME;
|
|
|
70 |
DECLARE v_overlap_cnt INT;
|
|
|
71 |
|
|
|
72 |
-- Validate start <= end
|
|
|
73 |
IF NEW.start_date IS NOT NULL AND NEW.end_date IS NOT NULL AND NEW.start_date > NEW.end_date THEN
|
|
|
74 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: start_date must be <= end_date';
|
|
|
75 |
END IF;
|
|
|
76 |
|
|
|
77 |
-- Validate containment within parent scheme window
|
|
|
78 |
IF NEW.start_date IS NOT NULL AND NEW.end_date IS NOT NULL THEN
|
|
|
79 |
SELECT start_date_time, end_date_time INTO v_scheme_start, v_scheme_end
|
|
|
80 |
FROM catalog.scheme WHERE id = NEW.scheme_id;
|
|
|
81 |
|
|
|
82 |
IF NEW.start_date < v_scheme_start OR NEW.end_date > v_scheme_end THEN
|
|
|
83 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: window outside parent scheme window';
|
|
|
84 |
END IF;
|
|
|
85 |
|
|
|
86 |
-- Validate non-overlap within same (catalog_id, scheme_id), excluding self
|
|
|
87 |
SELECT COUNT(*) INTO v_overlap_cnt FROM fofo.scheme_item
|
|
|
88 |
WHERE catalog_id = NEW.catalog_id
|
|
|
89 |
AND scheme_id = NEW.scheme_id
|
|
|
90 |
AND id <> NEW.id
|
|
|
91 |
AND NEW.start_date < end_date
|
|
|
92 |
AND NEW.end_date > start_date;
|
|
|
93 |
|
|
|
94 |
IF v_overlap_cnt > 0 THEN
|
|
|
95 |
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'scheme_item: window overlaps existing row';
|
|
|
96 |
END IF;
|
|
|
97 |
END IF;
|
|
|
98 |
END$$
|
|
|
99 |
|
|
|
100 |
DELIMITER ;
|