Project

General

Profile

1 1558 aaronmk
----- Trigger function
2
3
-- Function: plantname_update_ancestors()
4
5
-- DROP FUNCTION plantname_update_ancestors();
6
7
CREATE OR REPLACE FUNCTION plantname_update_ancestors()
8
  RETURNS trigger AS
9
$BODY$
10
BEGIN
11 1559 aaronmk
    -- Delete existing ancestors
12
    DELETE FROM plantname_ancestor WHERE plantname_id = new.plantname_id;
13
14 1558 aaronmk
    IF new.parent_id IS NOT NULL THEN
15
        -- Copy parent's ancestors to this node's ancestors
16
        INSERT
17
        INTO plantname_ancestor
18
        (plantname_id, ancestor_id)
19
        SELECT
20
            new.plantname_id, ancestor_id
21
        FROM plantname_ancestor
22
        WHERE plantname_id = new.parent_id
23
        ;
24
    END IF;
25 1559 aaronmk
26
    -- Add "ancestor" for this node
27
    /* This is useful for queries, because you don't have to separately test if
28
    the leaf node is the one you're looking for, in addition to that leaf node's
29
    ancestors. */
30
    INSERT
31
    INTO plantname_ancestor
32
    (plantname_id, ancestor_id)
33
    VALUES (new.plantname_id, new.plantname_id)
34
    ;
35
36
    -- Tell immediate children to update their ancestors lists, which will
37
    -- recursively tell all descendants
38
    UPDATE plantname
39 1560 aaronmk
    SET plantname_id = plantname_id -- need at least one SET statement
40
    WHERE parent_id = new.plantname_id -- the plantname_id passed as param
41 1559 aaronmk
    ;
42
43
    /* Note: We don't need an ON DELETE trigger to update the descendants'
44
    ancestors when a node is deleted, because the plantname.plantname_parent_id
45
    foreign key is set to ON DELETE CASCADE, which just removes all the
46
    descendants anyway. */
47
48 1558 aaronmk
    RETURN new;
49
END;
50
$BODY$
51
  LANGUAGE plpgsql VOLATILE
52
  COST 100;
53
ALTER FUNCTION plantname_update_ancestors()
54
  OWNER TO bien;
55
56
----- Ancestors table
57
58
-- Table: plantname_ancestor
59
60
-- DROP TABLE plantname_ancestor;
61
62
CREATE TABLE plantname_ancestor
63
(
64
  plantname_id integer NOT NULL,
65
  ancestor_id integer NOT NULL,
66
  CONSTRAINT plantname_ancestor_pkey PRIMARY KEY (plantname_id , ancestor_id ),
67
  CONSTRAINT plantname_ancestor_ancestor_id FOREIGN KEY (ancestor_id)
68
      REFERENCES plantname (plantname_id) MATCH SIMPLE
69
      ON UPDATE CASCADE ON DELETE CASCADE,
70
  CONSTRAINT plantname_ancestor_plantname_id FOREIGN KEY (plantname_id)
71
      REFERENCES plantname (plantname_id) MATCH SIMPLE
72
      ON UPDATE CASCADE ON DELETE CASCADE
73
)
74
WITH (
75
  OIDS=FALSE
76
);
77
ALTER TABLE plantname_ancestor
78
  OWNER TO bien;
79
80
-- Index: fki_plantname_ancestor_ancestor_id
81
82
-- DROP INDEX fki_plantname_ancestor_ancestor_id;
83
84
CREATE INDEX fki_plantname_ancestor_ancestor_id
85
  ON plantname_ancestor
86
  USING btree
87
  (ancestor_id );
88
89
-- Index: fki_plantname_ancestor_plantname_id
90
91
-- DROP INDEX fki_plantname_ancestor_plantname_id;
92
93
CREATE INDEX fki_plantname_ancestor_plantname_id
94
  ON plantname_ancestor
95
  USING btree
96
  (plantname_id );
97
98
----- Trigger
99
100
-- Trigger: plantname_update_ancestors on plantname
101
102
-- DROP TRIGGER plantname_update_ancestors ON plantname;
103
104
CREATE TRIGGER plantname_update_ancestors
105
  AFTER INSERT OR UPDATE
106
  ON plantname
107
  FOR EACH ROW
108
  EXECUTE PROCEDURE plantname_update_ancestors();