Project

General

Profile

1
/* To get the place trigger, just search and replace taxonconcept with place. */
2

    
3
----- Trigger function
4

    
5
-- Function: taxonconcept_update_ancestors()
6

    
7
-- DROP FUNCTION taxonconcept_update_ancestors();
8

    
9
CREATE OR REPLACE FUNCTION taxonconcept_update_ancestors()
10
  RETURNS trigger AS
11
$BODY$
12
BEGIN
13
    -- Delete existing ancestors
14
    DELETE FROM taxonconcept_ancestor
15
    WHERE taxonconcept_id = new.taxonconcept_id;
16
    
17
    IF new.parent_id IS NOT NULL THEN
18
        -- Copy parent's ancestors to this node's ancestors
19
        INSERT
20
        INTO taxonconcept_ancestor
21
        (taxonconcept_id, ancestor_id)
22
        SELECT
23
            new.taxonconcept_id, ancestor_id
24
        FROM taxonconcept_ancestor
25
        WHERE taxonconcept_id = new.parent_id
26
        ;
27
    END IF;
28
    
29
    -- Add "ancestor" for this node
30
    /* This is useful for queries, because you don't have to separately test if
31
    the leaf node is the one you're looking for, in addition to that leaf node's
32
    ancestors. */
33
    INSERT
34
    INTO taxonconcept_ancestor
35
    (taxonconcept_id, ancestor_id)
36
    VALUES (new.taxonconcept_id, new.taxonconcept_id)
37
    ;
38
    
39
    -- Tell immediate children to update their ancestors lists, which will
40
    -- recursively tell all descendants
41
    UPDATE taxonconcept
42
    SET taxonconcept_id = taxonconcept_id -- need at least one SET statement
43
    -- Add COALESCE() to enable using taxonconcept_unique index for lookup
44
    WHERE COALESCE(parent_id, 2147483647) = new.taxonconcept_id
45
    AND taxonconcept_id != new.taxonconcept_id -- avoid infinite recursion
46
    ;
47
    
48
    /* Note: We don't need an ON DELETE trigger to update the descendants'
49
    ancestors when a node is deleted, because the taxonconcept.parent_id foreign
50
    key is ON DELETE CASCADE, which just removes all the descendants anyway. */
51
    
52
    RETURN new;
53
END;
54
$BODY$
55
  LANGUAGE plpgsql VOLATILE
56
  COST 100;
57
ALTER FUNCTION taxonconcept_update_ancestors()
58
  OWNER TO bien;
59

    
60
----- Ancestors table
61

    
62
-- Table: taxonconcept_ancestor
63

    
64
-- DROP TABLE taxonconcept_ancestor;
65

    
66
CREATE TABLE taxonconcept_ancestor
67
(
68
  taxonconcept_id integer NOT NULL,
69
  ancestor_id integer NOT NULL,
70
  CONSTRAINT taxonconcept_ancestor_pkey PRIMARY KEY (taxonconcept_id , ancestor_id ),
71
  CONSTRAINT taxonconcept_ancestor_ancestor_id_fkey FOREIGN KEY (ancestor_id)
72
      REFERENCES taxonconcept (taxonconcept_id) MATCH SIMPLE
73
      ON UPDATE CASCADE ON DELETE CASCADE,
74
  CONSTRAINT taxonconcept_ancestor_taxonconcept_id_fkey FOREIGN KEY (taxonconcept_id)
75
      REFERENCES taxonconcept (taxonconcept_id) MATCH SIMPLE
76
      ON UPDATE CASCADE ON DELETE CASCADE
77
)
78
WITH (
79
  OIDS=FALSE
80
);
81
ALTER TABLE taxonconcept_ancestor
82
  OWNER TO bien;
83

    
84
----- Trigger
85

    
86
-- Trigger: taxonconcept_update_ancestors on taxonconcept
87

    
88
-- DROP TRIGGER taxonconcept_update_ancestors ON taxonconcept;
89

    
90
CREATE TRIGGER taxonconcept_update_ancestors
91
  AFTER INSERT OR UPDATE
92
  ON taxonconcept
93
  FOR EACH ROW
94
  EXECUTE PROCEDURE taxonconcept_update_ancestors();
(10-10/20)