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 |
$$;
|
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