Het kan worden gemaakt om te werken, de trigger die de verplaatsing doet, hoeft alleen voor elke partitie te worden gedefinieerd, niet voor de hele tabel. Dus begin zoals je deed voor tabeldefinities en de INSERT-trigger
CREATE TABLE records (
record varchar(64) NOT NULL,
active boolean default TRUE
);
CREATE TABLE active_records (CHECK (active)) INHERITS (records);
CREATE TABLE inactive_records (CHECK (NOT active)) INHERITS (records);
CREATE OR REPLACE FUNCTION record_insert()
RETURNS TRIGGER AS $$
BEGIN
IF (TRUE = NEW.active) THEN
INSERT INTO active_records VALUES (NEW.*);
ELSE
INSERT INTO inactive_records VALUES (NEW.*);
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER record_insert_trigger
BEFORE INSERT ON records
FOR EACH ROW EXECUTE PROCEDURE record_insert();
... laten we wat testgegevens hebben ...
INSERT INTO records VALUES ('FirstLittlePiggy', TRUE);
INSERT INTO records VALUES ('SecondLittlePiggy', FALSE);
INSERT INTO records VALUES ('ThirdLittlePiggy', TRUE);
INSERT INTO records VALUES ('FourthLittlePiggy', FALSE);
INSERT INTO records VALUES ('FifthLittlePiggy', TRUE);
Nu de triggers op de partities. De if NEW.active =OLD.active controle is impliciet bij het controleren van de waarde van active, omdat we weten wat er in de tabel mag staan.
CREATE OR REPLACE FUNCTION active_partition_constraint()
RETURNS TRIGGER AS $$
BEGIN
IF NOT (NEW.active) THEN
INSERT INTO inactive_records VALUES (NEW.*);
DELETE FROM active_records WHERE record = NEW.record;
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER active_constraint_trigger
BEFORE UPDATE ON active_records
FOR EACH ROW EXECUTE PROCEDURE active_partition_constraint();
CREATE OR REPLACE FUNCTION inactive_partition_constraint()
RETURNS TRIGGER AS $$
BEGIN
IF (NEW.active) THEN
INSERT INTO active_records VALUES (NEW.*);
DELETE FROM inactive_records WHERE record = NEW.record;
RETURN NULL;
ELSE
RETURN NEW;
END IF;
END;
$$
LANGUAGE plpgsql;
CREATE TRIGGER inactive_constraint_trigger
BEFORE UPDATE ON inactive_records
FOR EACH ROW EXECUTE PROCEDURE inactive_partition_constraint();
... en test de resultaten ...
scratch=> SELECT * FROM active_records;
record | active
------------------+--------
FirstLittlePiggy | t
ThirdLittlePiggy | t
FifthLittlePiggy | t
(3 rows)
scratch=> UPDATE records SET active = FALSE WHERE record = 'ThirdLittlePiggy';
UPDATE 0
scratch=> SELECT * FROM active_records;
record | active
------------------+--------
FirstLittlePiggy | t
FifthLittlePiggy | t
(2 rows)
scratch=> SELECT * FROM inactive_records;
record | active
-------------------+--------
SecondLittlePiggy | f
FourthLittlePiggy | f
ThirdLittlePiggy | f
(3 rows)