13175.3.1
by Robert Collins
Do not spuriously summarise in public bug subscriptions. |
1 |
-- Copyright 2011 Canonical Ltd. This software is licensed under the
|
2 |
-- GNU Affero General Public License version 3 (see the file LICENSE).
|
|
3 |
||
4 |
SET client_min_messages=ERROR; |
|
5 |
||
13175.3.8
by Stuart Bishop
Optimize real BugSummary _inc and _dec functions too |
6 |
CREATE OR REPLACE FUNCTION bug_summary_inc(d bugsummary) RETURNS VOID |
7 |
LANGUAGE plpgsql AS |
|
8 |
$$
|
|
9 |
BEGIN
|
|
10 |
-- Shameless adaption from postgresql manual
|
|
11 |
LOOP
|
|
12 |
-- first try to update the row
|
|
13 |
UPDATE BugSummary SET count = count + 1 |
|
14 |
WHERE
|
|
15 |
((d.product IS NULL AND product IS NULL) |
|
16 |
OR product = d.product) |
|
17 |
AND ((d.productseries IS NULL AND productseries IS NULL) |
|
18 |
OR productseries = d.productseries) |
|
19 |
AND ((d.distribution IS NULL AND distribution IS NULL) |
|
20 |
OR distribution = d.distribution) |
|
21 |
AND ((d.distroseries IS NULL AND distroseries IS NULL) |
|
22 |
OR distroseries = d.distroseries) |
|
23 |
AND ((d.sourcepackagename IS NULL AND sourcepackagename IS NULL) |
|
24 |
OR sourcepackagename = d.sourcepackagename) |
|
25 |
AND ((d.viewed_by IS NULL AND viewed_by IS NULL) |
|
26 |
OR viewed_by = d.viewed_by) |
|
27 |
AND ((d.tag IS NULL AND tag IS NULL) |
|
28 |
OR tag = d.tag) |
|
29 |
AND ((d.status IS NULL AND status IS NULL) |
|
30 |
OR status = d.status) |
|
31 |
AND ((d.milestone IS NULL AND milestone IS NULL) |
|
32 |
OR milestone = d.milestone); |
|
33 |
IF found THEN |
|
34 |
RETURN; |
|
35 |
END IF; |
|
36 |
-- not there, so try to insert the key
|
|
37 |
-- if someone else inserts the same key concurrently,
|
|
38 |
-- we could get a unique-key failure
|
|
39 |
BEGIN
|
|
40 |
INSERT INTO BugSummary( |
|
41 |
count, product, productseries, distribution, |
|
42 |
distroseries, sourcepackagename, viewed_by, tag, |
|
43 |
status, milestone) |
|
44 |
VALUES ( |
|
45 |
1, d.product, d.productseries, d.distribution, |
|
46 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
47 |
d.status, d.milestone); |
|
48 |
RETURN; |
|
49 |
EXCEPTION WHEN unique_violation THEN |
|
50 |
-- do nothing, and loop to try the UPDATE again
|
|
51 |
END; |
|
52 |
END LOOP; |
|
53 |
END; |
|
54 |
$$; |
|
55 |
||
56 |
COMMENT ON FUNCTION bug_summary_inc(bugsummary) IS |
|
57 |
'UPSERT into bugsummary incrementing one row'; |
|
58 |
||
59 |
CREATE OR REPLACE FUNCTION bug_summary_dec(bugsummary) RETURNS VOID |
|
60 |
LANGUAGE SQL AS |
|
61 |
$$
|
|
62 |
-- We own the row reference, so in the absence of bugs this cannot
|
|
63 |
-- fail - just decrement the row.
|
|
64 |
UPDATE BugSummary SET count = count - 1 |
|
65 |
WHERE
|
|
66 |
(($1.product IS NULL AND product IS NULL) |
|
67 |
OR product = $1.product) |
|
68 |
AND (($1.productseries IS NULL AND productseries IS NULL) |
|
69 |
OR productseries = $1.productseries) |
|
70 |
AND (($1.distribution IS NULL AND distribution IS NULL) |
|
71 |
OR distribution = $1.distribution) |
|
72 |
AND (($1.distroseries IS NULL AND distroseries IS NULL) |
|
73 |
OR distroseries = $1.distroseries) |
|
74 |
AND (($1.sourcepackagename IS NULL AND sourcepackagename IS NULL) |
|
75 |
OR sourcepackagename = $1.sourcepackagename) |
|
76 |
AND (($1.viewed_by IS NULL AND viewed_by IS NULL) |
|
77 |
OR viewed_by = $1.viewed_by) |
|
78 |
AND (($1.tag IS NULL AND tag IS NULL) |
|
79 |
OR tag = $1.tag) |
|
80 |
AND (($1.status IS NULL AND status IS NULL) |
|
81 |
OR status = $1.status) |
|
82 |
AND (($1.milestone IS NULL AND milestone IS NULL) |
|
83 |
OR milestone = $1.milestone); |
|
84 |
-- gc the row (perhaps should be garbo but easy enough to add here:
|
|
85 |
DELETE FROM bugsummary |
|
86 |
WHERE
|
|
87 |
count=0 |
|
88 |
AND (($1.product IS NULL AND product IS NULL) |
|
89 |
OR product = $1.product) |
|
90 |
AND (($1.productseries IS NULL AND productseries IS NULL) |
|
91 |
OR productseries = $1.productseries) |
|
92 |
AND (($1.distribution IS NULL AND distribution IS NULL) |
|
93 |
OR distribution = $1.distribution) |
|
94 |
AND (($1.distroseries IS NULL AND distroseries IS NULL) |
|
95 |
OR distroseries = $1.distroseries) |
|
96 |
AND (($1.sourcepackagename IS NULL AND sourcepackagename IS NULL) |
|
97 |
OR sourcepackagename = $1.sourcepackagename) |
|
98 |
AND (($1.viewed_by IS NULL AND viewed_by IS NULL) |
|
99 |
OR viewed_by = $1.viewed_by) |
|
100 |
AND (($1.tag IS NULL AND tag IS NULL) |
|
101 |
OR tag = $1.tag) |
|
102 |
AND (($1.status IS NULL AND status IS NULL) |
|
103 |
OR status = $1.status) |
|
104 |
AND (($1.milestone IS NULL AND milestone IS NULL) |
|
105 |
OR milestone = $1.milestone); |
|
106 |
-- If its not found then someone else also dec'd and won concurrently.
|
|
107 |
$$; |
|
108 |
||
109 |
||
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
110 |
-- bad comment fixup
|
111 |
COMMENT ON FUNCTION bug_summary_dec(bugsummary) IS |
|
112 |
'UPSERT into bugsummary incrementing one row'; |
|
113 |
||
114 |
CREATE OR REPLACE FUNCTION ensure_bugsummary_temp_journal() RETURNS VOID |
|
115 |
LANGUAGE plpgsql VOLATILE AS |
|
116 |
$$
|
|
117 |
DECLARE
|
|
118 |
BEGIN
|
|
119 |
CREATE TEMPORARY TABLE bugsummary_temp_journal ( |
|
120 |
LIKE bugsummary ) ON COMMIT DROP; |
|
121 |
ALTER TABLE bugsummary_temp_journal ALTER COLUMN id DROP NOT NULL; |
|
122 |
-- For safety use a unique index.
|
|
123 |
CREATE UNIQUE INDEX bugsummary__temp_journal__dimensions__unique ON bugsummary_temp_journal ( |
|
124 |
status, |
|
125 |
COALESCE(product, (-1)), |
|
126 |
COALESCE(productseries, (-1)), |
|
127 |
COALESCE(distribution, (-1)), |
|
128 |
COALESCE(distroseries, (-1)), |
|
129 |
COALESCE(sourcepackagename, (-1)), |
|
130 |
COALESCE(viewed_by, (-1)), |
|
131 |
COALESCE(milestone, (-1)), |
|
132 |
COALESCE(tag, (''))); |
|
133 |
EXCEPTION
|
|
134 |
WHEN duplicate_table THEN |
|
135 |
NULL; |
|
136 |
END; |
|
137 |
$$; |
|
138 |
||
139 |
COMMENT ON FUNCTION ensure_bugsummary_temp_journal() IS |
|
140 |
'Create a temporary table bugsummary_temp_journal if it does not exist.'; |
|
141 |
||
142 |
||
143 |
CREATE OR REPLACE FUNCTION bug_summary_temp_journal_dec(d bugsummary) RETURNS VOID |
|
144 |
LANGUAGE plpgsql AS |
|
145 |
$$
|
|
146 |
BEGIN
|
|
147 |
-- We own the row reference, so in the absence of bugs this cannot
|
|
148 |
-- fail - just decrement the row.
|
|
149 |
UPDATE BugSummary_Temp_Journal SET count = count - 1 |
|
150 |
WHERE
|
|
13175.3.4
by Stuart Bishop
Belt queries with the ugly stick until they use indexes |
151 |
((d.product IS NULL AND product IS NULL) |
152 |
OR product = d.product) |
|
153 |
AND ((d.productseries IS NULL AND productseries IS NULL) |
|
154 |
OR productseries = d.productseries) |
|
155 |
AND ((d.distribution IS NULL AND distribution IS NULL) |
|
156 |
OR distribution = d.distribution) |
|
157 |
AND ((d.distroseries IS NULL AND distroseries IS NULL) |
|
158 |
OR distroseries = d.distroseries) |
|
159 |
AND ((d.sourcepackagename IS NULL AND sourcepackagename IS NULL) |
|
160 |
OR sourcepackagename = d.sourcepackagename) |
|
161 |
AND ((d.viewed_by IS NULL AND viewed_by IS NULL) |
|
162 |
OR viewed_by = d.viewed_by) |
|
163 |
AND ((d.tag IS NULL AND tag IS NULL) |
|
164 |
OR tag = d.tag) |
|
165 |
AND ((d.status IS NULL AND status IS NULL) |
|
166 |
OR status = d.status) |
|
167 |
AND ((d.milestone IS NULL AND milestone IS NULL) |
|
168 |
OR milestone = d.milestone); |
|
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
169 |
IF found THEN |
170 |
RETURN; |
|
171 |
END IF; |
|
172 |
-- not there, so try to insert the key
|
|
173 |
INSERT INTO BugSummary_Temp_Journal( |
|
174 |
count, product, productseries, distribution, |
|
175 |
distroseries, sourcepackagename, viewed_by, tag, |
|
176 |
status, milestone) |
|
177 |
VALUES ( |
|
178 |
-1, d.product, d.productseries, d.distribution, |
|
179 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
180 |
d.status, d.milestone); |
|
181 |
RETURN; |
|
182 |
END; |
|
183 |
$$; |
|
184 |
||
185 |
COMMENT ON FUNCTION bug_summary_temp_journal_dec(bugsummary) IS |
|
186 |
'UPSERT into bugsummary_temp_journal decrementing one row'; |
|
187 |
||
188 |
CREATE OR REPLACE FUNCTION bug_summary_temp_journal_inc(d bugsummary) RETURNS VOID |
|
189 |
LANGUAGE plpgsql AS |
|
190 |
$$
|
|
191 |
BEGIN
|
|
192 |
-- first try to update the row
|
|
193 |
UPDATE BugSummary_Temp_Journal SET count = count + 1 |
|
194 |
WHERE
|
|
13175.3.4
by Stuart Bishop
Belt queries with the ugly stick until they use indexes |
195 |
((d.product IS NULL AND product IS NULL) |
196 |
OR product = d.product) |
|
197 |
AND ((d.productseries IS NULL AND productseries IS NULL) |
|
198 |
OR productseries = d.productseries) |
|
199 |
AND ((d.distribution IS NULL AND distribution IS NULL) |
|
200 |
OR distribution = d.distribution) |
|
201 |
AND ((d.distroseries IS NULL AND distroseries IS NULL) |
|
202 |
OR distroseries = d.distroseries) |
|
203 |
AND ((d.sourcepackagename IS NULL AND sourcepackagename IS NULL) |
|
204 |
OR sourcepackagename = d.sourcepackagename) |
|
205 |
AND ((d.viewed_by IS NULL AND viewed_by IS NULL) |
|
206 |
OR viewed_by = d.viewed_by) |
|
207 |
AND ((d.tag IS NULL AND tag IS NULL) |
|
208 |
OR tag = d.tag) |
|
209 |
AND ((d.status IS NULL AND status IS NULL) |
|
210 |
OR status = d.status) |
|
211 |
AND ((d.milestone IS NULL AND milestone IS NULL) |
|
212 |
OR milestone = d.milestone); |
|
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
213 |
IF found THEN |
214 |
RETURN; |
|
215 |
END IF; |
|
216 |
-- not there, so try to insert the key
|
|
217 |
INSERT INTO BugSummary_Temp_Journal( |
|
218 |
count, product, productseries, distribution, |
|
219 |
distroseries, sourcepackagename, viewed_by, tag, |
|
220 |
status, milestone) |
|
221 |
VALUES ( |
|
222 |
1, d.product, d.productseries, d.distribution, |
|
223 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
224 |
d.status, d.milestone); |
|
225 |
RETURN; |
|
226 |
END; |
|
227 |
$$; |
|
228 |
||
229 |
COMMENT ON FUNCTION bug_summary_temp_journal_inc(bugsummary) IS |
|
230 |
'UPSERT into bugsummary incrementing one row'; |
|
231 |
||
232 |
CREATE OR REPLACE FUNCTION bug_summary_flush_temp_journal() RETURNS VOID |
|
233 |
LANGUAGE plpgsql VOLATILE AS |
|
234 |
$$
|
|
235 |
DECLARE
|
|
236 |
d bugsummary%ROWTYPE; |
|
237 |
BEGIN
|
|
238 |
-- may get called even though no summaries were made (for simplicity in the
|
|
239 |
-- callers)
|
|
240 |
PERFORM ensure_bugsummary_temp_journal(); |
|
241 |
FOR d IN SELECT * FROM bugsummary_temp_journal LOOP |
|
242 |
IF d.count < 0 THEN |
|
243 |
PERFORM bug_summary_dec(d); |
|
244 |
ELSIF d.count > 0 THEN |
|
245 |
PERFORM bug_summary_inc(d); |
|
246 |
END IF; |
|
247 |
END LOOP; |
|
248 |
DELETE FROM bugsummary_temp_journal; |
|
249 |
END; |
|
250 |
$$; |
|
251 |
||
252 |
COMMENT ON FUNCTION bug_summary_flush_temp_journal() IS |
|
253 |
'flush the temporary bugsummary journal into the bugsummary table'; |
|
254 |
||
255 |
CREATE OR REPLACE FUNCTION unsummarise_bug(BUG_ROW bug) RETURNS VOID |
|
256 |
LANGUAGE plpgsql VOLATILE AS |
|
257 |
$$
|
|
258 |
DECLARE
|
|
259 |
d bugsummary%ROWTYPE; |
|
260 |
BEGIN
|
|
261 |
PERFORM ensure_bugsummary_temp_journal(); |
|
262 |
FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP |
|
263 |
PERFORM bug_summary_temp_journal_dec(d); |
|
264 |
END LOOP; |
|
265 |
END; |
|
266 |
$$; |
|
267 |
||
268 |
CREATE OR REPLACE FUNCTION summarise_bug(BUG_ROW bug) RETURNS VOID |
|
269 |
LANGUAGE plpgsql VOLATILE AS |
|
270 |
$$
|
|
271 |
DECLARE
|
|
272 |
d bugsummary%ROWTYPE; |
|
273 |
BEGIN
|
|
274 |
PERFORM ensure_bugsummary_temp_journal(); |
|
275 |
FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP |
|
276 |
PERFORM bug_summary_temp_journal_inc(d); |
|
277 |
END LOOP; |
|
278 |
END; |
|
279 |
$$; |
|
280 |
||
281 |
-- fixed to summarise less often and use the journal.
|
|
13175.3.1
by Robert Collins
Do not spuriously summarise in public bug subscriptions. |
282 |
CREATE OR REPLACE FUNCTION bugsubscription_maintain_bug_summary() |
283 |
RETURNS TRIGGER LANGUAGE plpgsql VOLATILE |
|
284 |
SECURITY DEFINER SET search_path TO public AS |
|
285 |
$$
|
|
286 |
BEGIN
|
|
287 |
-- This trigger only works if we are inserting, updating or deleting
|
|
288 |
-- a single row per statement.
|
|
289 |
IF TG_OP = 'INSERT' THEN |
|
290 |
IF NOT (bug_row(NEW.bug)).private THEN |
|
291 |
-- Public subscriptions are not aggregated.
|
|
292 |
RETURN NEW; |
|
293 |
END IF; |
|
294 |
IF TG_WHEN = 'BEFORE' THEN |
|
295 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
296 |
ELSE
|
|
297 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
298 |
END IF; |
|
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
299 |
PERFORM bug_summary_flush_temp_journal(); |
13175.3.1
by Robert Collins
Do not spuriously summarise in public bug subscriptions. |
300 |
RETURN NEW; |
301 |
ELSIF TG_OP = 'DELETE' THEN |
|
302 |
IF NOT (bug_row(OLD.bug)).private THEN |
|
303 |
-- Public subscriptions are not aggregated.
|
|
304 |
RETURN OLD; |
|
305 |
END IF; |
|
306 |
IF TG_WHEN = 'BEFORE' THEN |
|
307 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
308 |
ELSE
|
|
309 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
310 |
END IF; |
|
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
311 |
PERFORM bug_summary_flush_temp_journal(); |
13175.3.1
by Robert Collins
Do not spuriously summarise in public bug subscriptions. |
312 |
RETURN OLD; |
313 |
ELSE
|
|
314 |
IF (OLD.person IS DISTINCT FROM NEW.person |
|
315 |
OR OLD.bug IS DISTINCT FROM NEW.bug) THEN |
|
316 |
IF TG_WHEN = 'BEFORE' THEN |
|
317 |
IF (bug_row(OLD.bug)).private THEN |
|
318 |
-- Public subscriptions are not aggregated.
|
|
319 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
320 |
END IF; |
|
321 |
IF OLD.bug <> NEW.bug AND (bug_row(NEW.bug)).private THEN |
|
322 |
-- Public subscriptions are not aggregated.
|
|
323 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
324 |
END IF; |
|
325 |
ELSE
|
|
326 |
IF (bug_row(OLD.bug)).private THEN |
|
327 |
-- Public subscriptions are not aggregated.
|
|
328 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
329 |
END IF; |
|
330 |
IF OLD.bug <> NEW.bug AND (bug_row(NEW.bug)).private THEN |
|
331 |
-- Public subscriptions are not aggregated.
|
|
332 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
333 |
END IF; |
|
334 |
END IF; |
|
335 |
END IF; |
|
13175.3.2
by Robert Collins
Rather than taking a table lock, do row level locking and update only the rows which a net different would have applied to. |
336 |
PERFORM bug_summary_flush_temp_journal(); |
337 |
RETURN NEW; |
|
338 |
END IF; |
|
339 |
END; |
|
340 |
$$; |
|
341 |
||
342 |
-- fixed to use the journal
|
|
343 |
CREATE OR REPLACE FUNCTION bugtag_maintain_bug_summary() RETURNS TRIGGER |
|
344 |
LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS |
|
345 |
$$
|
|
346 |
BEGIN
|
|
347 |
IF TG_OP = 'INSERT' THEN |
|
348 |
IF TG_WHEN = 'BEFORE' THEN |
|
349 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
350 |
ELSE
|
|
351 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
352 |
END IF; |
|
353 |
PERFORM bug_summary_flush_temp_journal(); |
|
354 |
RETURN NEW; |
|
355 |
ELSIF TG_OP = 'DELETE' THEN |
|
356 |
IF TG_WHEN = 'BEFORE' THEN |
|
357 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
358 |
ELSE
|
|
359 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
360 |
END IF; |
|
361 |
PERFORM bug_summary_flush_temp_journal(); |
|
362 |
RETURN OLD; |
|
363 |
ELSE
|
|
364 |
IF TG_WHEN = 'BEFORE' THEN |
|
365 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
366 |
IF OLD.bug <> NEW.bug THEN |
|
367 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
368 |
END IF; |
|
369 |
ELSE
|
|
370 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
371 |
IF OLD.bug <> NEW.bug THEN |
|
372 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
373 |
END IF; |
|
374 |
END IF; |
|
375 |
PERFORM bug_summary_flush_temp_journal(); |
|
376 |
RETURN NEW; |
|
377 |
END IF; |
|
378 |
END; |
|
379 |
$$; |
|
380 |
||
381 |
-- fixed to use the journal
|
|
382 |
CREATE OR REPLACE FUNCTION bug_maintain_bug_summary() RETURNS TRIGGER |
|
383 |
LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS |
|
384 |
$$
|
|
385 |
BEGIN
|
|
386 |
-- There is no INSERT logic, as a bug will not have any summary
|
|
387 |
-- information until BugTask rows have been attached.
|
|
388 |
IF TG_OP = 'UPDATE' THEN |
|
389 |
IF OLD.duplicateof IS DISTINCT FROM NEW.duplicateof |
|
390 |
OR OLD.private IS DISTINCT FROM NEW.private THEN |
|
391 |
PERFORM unsummarise_bug(OLD); |
|
392 |
PERFORM summarise_bug(NEW); |
|
393 |
END IF; |
|
394 |
||
395 |
ELSIF TG_OP = 'DELETE' THEN |
|
396 |
PERFORM unsummarise_bug(OLD); |
|
397 |
END IF; |
|
398 |
||
399 |
PERFORM bug_summary_flush_temp_journal(); |
|
400 |
RETURN NULL; -- Ignored - this is an AFTER trigger |
|
401 |
END; |
|
402 |
$$; |
|
403 |
||
404 |
-- fixed to use the journal
|
|
405 |
CREATE OR REPLACE FUNCTION bugtask_maintain_bug_summary() RETURNS TRIGGER |
|
406 |
LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS |
|
407 |
$$
|
|
408 |
BEGIN
|
|
409 |
-- This trigger only works if we are inserting, updating or deleting
|
|
410 |
-- a single row per statement.
|
|
411 |
||
412 |
-- Unlike bug_maintain_bug_summary, this trigger does not have access
|
|
413 |
-- to the old bug when invoked as an AFTER trigger. To work around this
|
|
414 |
-- we install this trigger as both a BEFORE and an AFTER trigger.
|
|
415 |
IF TG_OP = 'INSERT' THEN |
|
416 |
IF TG_WHEN = 'BEFORE' THEN |
|
417 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
418 |
ELSE
|
|
419 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
420 |
END IF; |
|
421 |
PERFORM bug_summary_flush_temp_journal(); |
|
422 |
RETURN NEW; |
|
423 |
||
424 |
ELSIF TG_OP = 'DELETE' THEN |
|
425 |
IF TG_WHEN = 'BEFORE' THEN |
|
426 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
427 |
ELSE
|
|
428 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
429 |
END IF; |
|
430 |
PERFORM bug_summary_flush_temp_journal(); |
|
431 |
RETURN OLD; |
|
432 |
||
433 |
ELSE
|
|
434 |
IF (OLD.product IS DISTINCT FROM NEW.product |
|
435 |
OR OLD.productseries IS DISTINCT FROM NEW.productseries |
|
436 |
OR OLD.distribution IS DISTINCT FROM NEW.distribution |
|
437 |
OR OLD.distroseries IS DISTINCT FROM NEW.distroseries |
|
438 |
OR OLD.sourcepackagename IS DISTINCT FROM NEW.sourcepackagename |
|
439 |
OR OLD.status IS DISTINCT FROM NEW.status |
|
440 |
OR OLD.milestone IS DISTINCT FROM NEW.milestone) THEN |
|
441 |
IF TG_WHEN = 'BEFORE' THEN |
|
442 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
443 |
IF OLD.bug <> NEW.bug THEN |
|
444 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
445 |
END IF; |
|
446 |
ELSE
|
|
447 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
448 |
IF OLD.bug <> NEW.bug THEN |
|
449 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
450 |
END IF; |
|
451 |
END IF; |
|
452 |
END IF; |
|
453 |
PERFORM bug_summary_flush_temp_journal(); |
|
454 |
RETURN NEW; |
|
455 |
END IF; |
|
456 |
END; |
|
457 |
$$; |
|
13175.3.1
by Robert Collins
Do not spuriously summarise in public bug subscriptions. |
458 |
|
13175.3.4
by Stuart Bishop
Belt queries with the ugly stick until they use indexes |
459 |
|
13175.3.6
by Stuart Bishop
Remove live application cruft |
460 |
INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 63, 1); |