Project

General

Profile

« Previous | Next » 

Revision 1559

vegbien.sql: Fixed bug in tree cross-link algorithm to also insert ancestors for top-level nodes, because they now need an ancestor entry for themselves

View differences:

schemas/tree_cross-links.sql
8 8
  RETURNS trigger AS
9 9
$BODY$
10 10
BEGIN
11
    -- Delete existing ancestors
12
    DELETE FROM plantname_ancestor WHERE plantname_id = new.plantname_id;
13
    
11 14
    IF new.parent_id IS NOT NULL THEN
12
        -- Delete existing ancestors
13
        DELETE FROM plantname_ancestor WHERE plantname_id = new.plantname_id;
14 15
        -- Copy parent's ancestors to this node's ancestors
15 16
        INSERT
16 17
        INTO plantname_ancestor
......
20 21
        FROM plantname_ancestor
21 22
        WHERE plantname_id = new.parent_id
22 23
        ;
23
        -- Add "ancestor" for this node
24
        /* This is useful for queries, because you don't have to separately test
25
        if the leaf node is the one you're looking for, in addition to that leaf
26
        node's ancestors. */
27
        INSERT
28
        INTO plantname_ancestor
29
        (plantname_id, ancestor_id)
30
        VALUES (new.plantname_id, new.plantname_id)
31
        ;
32
        -- Tell immediate children to update their ancestors lists, which will
33
        -- recursively tell all descendants
34
        UPDATE plantname
35
        SET plantname_id = plantname.plantname_id -- set to itself
36
        WHERE parent_id = plantname_id -- the plantname_id passed as param
37
        ;
38
        /*
39
        Note: We don't need an ON DELETE trigger to update the descendants'
40
        ancestors when a node is deleted, because the
41
        plantname.plantname_parent_id foreign key is set to ON DELETE CASCADE,
42
        which just removes all the descendants anyway.
43
        */
44 24
    END IF;
25
    
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
    SET plantname_id = plantname.plantname_id -- set to itself
40
    WHERE parent_id = plantname_id -- the plantname_id passed as param
41
    ;
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
    
45 48
    RETURN new;
46 49
END;
47 50
$BODY$
schemas/vegbien.sql
207 207
    LANGUAGE plpgsql
208 208
    AS $$
209 209
BEGIN
210
    -- Delete existing ancestors
211
    DELETE FROM namedplace_ancestor WHERE namedplace_id = new.namedplace_id;
212
    
210 213
    IF new.parent_id IS NOT NULL THEN
211
        -- Delete existing ancestors
212
        DELETE FROM namedplace_ancestor WHERE namedplace_id = new.namedplace_id;
213 214
        -- Copy parent's ancestors to this node's ancestors
214 215
        INSERT
215 216
        INTO namedplace_ancestor
......
219 220
        FROM namedplace_ancestor
220 221
        WHERE namedplace_id = new.parent_id
221 222
        ;
222
        -- Add "ancestor" for this node
223
        /* This is useful for queries, because you don't have to separately test
224
        if the leaf node is the one you're looking for, in addition to that leaf
225
        node's ancestors. */
226
        INSERT
227
        INTO namedplace_ancestor
228
        (namedplace_id, ancestor_id)
229
        VALUES (new.namedplace_id, new.namedplace_id)
230
        ;
231
        -- Tell immediate children to update their ancestors lists, which will
232
        -- recursively tell all descendants
233
        UPDATE namedplace
234
        SET namedplace_id = namedplace.namedplace_id -- set to itself
235
        WHERE parent_id = namedplace_id -- the namedplace_id passed as param
236
        ;
237
        /*
238
        Note: We don't need an ON DELETE trigger to update the descendants'
239
        ancestors when a node is deleted, because the
240
        namedplace.namedplace_parent_id foreign key is set to ON DELETE CASCADE,
241
        which just removes all the descendants anyway.
242
        */
243 223
    END IF;
224
    
225
    -- Add "ancestor" for this node
226
    /* This is useful for queries, because you don't have to separately test if
227
    the leaf node is the one you're looking for, in addition to that leaf node's
228
    ancestors. */
229
    INSERT
230
    INTO namedplace_ancestor
231
    (namedplace_id, ancestor_id)
232
    VALUES (new.namedplace_id, new.namedplace_id)
233
    ;
234
    
235
    -- Tell immediate children to update their ancestors lists, which will
236
    -- recursively tell all descendants
237
    UPDATE namedplace
238
    SET namedplace_id = namedplace.namedplace_id -- set to itself
239
    WHERE parent_id = namedplace_id -- the namedplace_id passed as param
240
    ;
241
    
242
    /* Note: We don't need an ON DELETE trigger to update the descendants'
243
    ancestors when a node is deleted, because the namedplace.namedplace_parent_id
244
    foreign key is set to ON DELETE CASCADE, which just removes all the
245
    descendants anyway. */
246
    
244 247
    RETURN new;
245 248
END;
246 249
$$;
......
254 257
    LANGUAGE plpgsql
255 258
    AS $$
256 259
BEGIN
260
    -- Delete existing ancestors
261
    DELETE FROM plantname_ancestor WHERE plantname_id = new.plantname_id;
262
    
257 263
    IF new.parent_id IS NOT NULL THEN
258
        -- Delete existing ancestors
259
        DELETE FROM plantname_ancestor WHERE plantname_id = new.plantname_id;
260 264
        -- Copy parent's ancestors to this node's ancestors
261 265
        INSERT
262 266
        INTO plantname_ancestor
......
266 270
        FROM plantname_ancestor
267 271
        WHERE plantname_id = new.parent_id
268 272
        ;
269
        -- Add "ancestor" for this node
270
        /* This is useful for queries, because you don't have to separately test
271
        if the leaf node is the one you're looking for, in addition to that leaf
272
        node's ancestors. */
273
        INSERT
274
        INTO plantname_ancestor
275
        (plantname_id, ancestor_id)
276
        VALUES (new.plantname_id, new.plantname_id)
277
        ;
278
        -- Tell immediate children to update their ancestors lists, which will
279
        -- recursively tell all descendants
280
        UPDATE plantname
281
        SET plantname_id = plantname.plantname_id -- set to itself
282
        WHERE parent_id = plantname_id -- the plantname_id passed as param
283
        ;
284
        /*
285
        Note: We don't need an ON DELETE trigger to update the descendants'
286
        ancestors when a node is deleted, because the
287
        plantname.plantname_parent_id foreign key is set to ON DELETE CASCADE,
288
        which just removes all the descendants anyway.
289
        */
290 273
    END IF;
274
    
275
    -- Add "ancestor" for this node
276
    /* This is useful for queries, because you don't have to separately test if
277
    the leaf node is the one you're looking for, in addition to that leaf node's
278
    ancestors. */
279
    INSERT
280
    INTO plantname_ancestor
281
    (plantname_id, ancestor_id)
282
    VALUES (new.plantname_id, new.plantname_id)
283
    ;
284
    
285
    -- Tell immediate children to update their ancestors lists, which will
286
    -- recursively tell all descendants
287
    UPDATE plantname
288
    SET plantname_id = plantname.plantname_id -- set to itself
289
    WHERE parent_id = plantname_id -- the plantname_id passed as param
290
    ;
291
    
292
    /* Note: We don't need an ON DELETE trigger to update the descendants'
293
    ancestors when a node is deleted, because the plantname.plantname_parent_id
294
    foreign key is set to ON DELETE CASCADE, which just removes all the
295
    descendants anyway. */
296
    
291 297
    RETURN new;
292 298
END;
293 299
$$;

Also available in: Unified diff