7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
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 |
||
6 |
-- Trash our existing data, which we will rebuild in a minute.
|
|
7 |
-- Slony-I doesn't like TRUNCATE noramlly, but OK in a DB patch.
|
|
8 |
TRUNCATE BugSummary; |
|
9 |
TRUNCATE BugSummaryJournal; |
|
10 |
||
11 |
-- Drop indexes we will rebuild later.
|
|
12 |
DROP INDEX bugsummary__dimensions__unique; |
|
13 |
DROP INDEX bugsummary__full__idx; |
|
14 |
||
15 |
ALTER TABLE BugSummary |
|
16 |
-- Add a missing foreign key constraint we were unable to add live.
|
|
17 |
-- Person table is always being read, so locks are never acquired.
|
|
18 |
ADD CONSTRAINT bugsummaryjournal_viewed_by_fkey |
|
19 |
FOREIGN KEY(viewed_by) REFERENCES Person ON DELETE CASCADE, |
|
20 |
ADD COLUMN importance integer NOT NULL, |
|
21 |
ADD COLUMN has_patch boolean NOT NULL, |
|
22 |
ADD COLUMN fixed_upstream boolean NOT NULL; |
|
23 |
||
24 |
ALTER TABLE BugSummaryJournal |
|
25 |
ADD COLUMN importance integer NOT NULL, |
|
26 |
ADD COLUMN has_patch boolean NOT NULL, |
|
27 |
ADD COLUMN fixed_upstream boolean NOT NULL; |
|
28 |
||
29 |
DROP VIEW CombinedBugSummary; |
|
30 |
CREATE VIEW CombinedBugSummary AS ( |
|
31 |
SELECT
|
|
32 |
id, count, product, productseries, distribution, distroseries, |
|
33 |
sourcepackagename, viewed_by, tag, status, milestone, |
|
34 |
importance, has_patch, fixed_upstream |
|
35 |
FROM BugSummary |
|
36 |
UNION ALL |
|
37 |
SELECT
|
|
38 |
-id as id, count, product, productseries, distribution, distroseries, |
|
39 |
sourcepackagename, viewed_by, tag, status, milestone, |
|
40 |
importance, has_patch, fixed_upstream |
|
41 |
FROM BugSummaryJournal); |
|
42 |
||
43 |
||
44 |
-- Rebuild the BugSummary data with the new columns.
|
|
7675.1202.20
by Stuart Bishop
Replace slow data migration query |
45 |
INSERT INTO BugSummary ( |
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
46 |
count, product, productseries, distribution, distroseries, |
7675.1202.20
by Stuart Bishop
Replace slow data migration query |
47 |
sourcepackagename, viewed_by, tag, status, importance, has_patch, |
48 |
fixed_upstream, milestone) |
|
49 |
WITH
|
|
50 |
-- kill dupes
|
|
51 |
relevant_bug AS (SELECT * FROM bug where duplicateof is NULL), |
|
52 |
||
53 |
-- (bug.id, tag) for all bug-tag pairs plus (bug.id, NULL) for all bugs
|
|
54 |
bug_tags AS ( |
|
55 |
SELECT relevant_bug.id, NULL::text AS tag FROM relevant_bug |
|
56 |
UNION
|
|
57 |
SELECT relevant_bug.id, tag |
|
58 |
FROM relevant_bug INNER JOIN bugtag ON relevant_bug.id=bugtag.bug), |
|
59 |
||
60 |
-- (bug.id, NULL) for all public bugs + (bug.id, viewer) for all
|
|
61 |
-- (subscribers+assignee) on private bugs
|
|
62 |
bug_viewers AS ( |
|
63 |
SELECT relevant_bug.id, NULL::integer AS person |
|
64 |
FROM relevant_bug WHERE NOT relevant_bug.private |
|
65 |
UNION
|
|
66 |
SELECT relevant_bug.id, assignee AS person |
|
67 |
FROM relevant_bug |
|
68 |
INNER JOIN bugtask ON relevant_bug.id=bugtask.bug |
|
69 |
WHERE relevant_bug.private and bugtask.assignee IS NOT NULL |
|
70 |
UNION
|
|
71 |
SELECT relevant_bug.id, bugsubscription.person |
|
72 |
FROM relevant_bug INNER JOIN bugsubscription |
|
73 |
ON bugsubscription.bug=relevant_bug.id WHERE relevant_bug.private), |
|
74 |
||
75 |
-- (bugtask.(bug, product, productseries, distribution, distroseries,
|
|
76 |
-- sourcepackagename, status, milestone) for all bugs + the same with
|
|
77 |
-- sourcepackage squashed to NULL)
|
|
78 |
tasks AS ( |
|
79 |
SELECT
|
|
80 |
bug, product, productseries, distribution, distroseries, |
|
81 |
sourcepackagename, status, importance, |
|
82 |
(EXISTS |
|
83 |
(SELECT TRUE |
|
84 |
FROM BugTask AS RelatedBugTask |
|
85 |
WHERE RelatedBugTask.bug = BugTask.bug |
|
86 |
AND RelatedBugTask.id != BugTask.id |
|
87 |
AND ((RelatedBugTask.bugwatch IS NOT NULL |
|
88 |
AND RelatedBugTask.status IN (17, 25, 30)) |
|
89 |
OR (RelatedBugTask.product IS NOT NULL |
|
90 |
AND RelatedBugTask.bugwatch IS NULL |
|
91 |
AND RelatedBugTask.status IN (25, 30)))) |
|
92 |
) as fixed_upstream, milestone |
|
93 |
FROM bugtask |
|
94 |
UNION
|
|
95 |
SELECT DISTINCT ON ( |
|
96 |
bug, product, productseries, distribution, distroseries, |
|
97 |
sourcepackagename, milestone) |
|
98 |
bug, product, productseries, distribution, distroseries, |
|
99 |
NULL::integer as sourcepackagename, |
|
100 |
status, importance, |
|
101 |
(EXISTS |
|
102 |
(SELECT TRUE |
|
103 |
FROM BugTask AS RelatedBugTask |
|
104 |
WHERE RelatedBugTask.bug = BugTask.bug |
|
105 |
AND RelatedBugTask.id != BugTask.id |
|
106 |
AND ((RelatedBugTask.bugwatch IS NOT NULL |
|
107 |
AND RelatedBugTask.status IN (17, 25, 30)) |
|
108 |
OR (RelatedBugTask.product IS NOT NULL |
|
109 |
AND RelatedBugTask.bugwatch IS NULL |
|
110 |
AND RelatedBugTask.status IN (25, 30)))) |
|
111 |
) as fixed_upstream, milestone |
|
112 |
FROM bugtask where sourcepackagename IS NOT NULL) |
|
113 |
||
114 |
-- Now combine
|
|
115 |
SELECT
|
|
116 |
count(*), product, productseries, distribution, distroseries, |
|
117 |
sourcepackagename, person, tag, status, importance, |
|
118 |
latest_patch_uploaded IS NOT NULL AS has_patch, fixed_upstream, |
|
119 |
milestone
|
|
120 |
FROM relevant_bug |
|
121 |
INNER JOIN bug_tags ON relevant_bug.id=bug_tags.id |
|
122 |
INNER JOIN bug_viewers ON relevant_bug.id=bug_viewers.id |
|
123 |
INNER JOIN tasks on tasks.bug=relevant_bug.id |
|
124 |
GROUP BY |
|
125 |
product, productseries, distribution, distroseries, |
|
126 |
sourcepackagename, person, tag, status, importance, has_patch, |
|
127 |
fixed_upstream, milestone; |
|
128 |
||
129 |
||
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
130 |
-- Rebuild indexes.
|
131 |
CREATE INDEX bugsummary__full__idx ON BugSummary ( |
|
132 |
tag, status, product, productseries, distribution, |
|
133 |
distroseries, sourcepackagename, viewed_by, milestone, |
|
134 |
importance, has_patch, fixed_upstream); |
|
135 |
-- Enforce uniqueness again.
|
|
136 |
CREATE UNIQUE INDEX bugsummary__product__unique |
|
137 |
ON BugSummary( |
|
138 |
product, status, importance, has_patch, fixed_upstream, |
|
139 |
COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1)) |
|
140 |
WHERE product IS NOT NULL; |
|
141 |
CREATE UNIQUE INDEX bugsummary__productseries__unique |
|
142 |
ON BugSummary( |
|
143 |
productseries, status, importance, has_patch, fixed_upstream, |
|
144 |
COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1)) |
|
145 |
WHERE productseries IS NOT NULL; |
|
146 |
CREATE UNIQUE INDEX bugsummary__distribution__unique |
|
147 |
ON BugSummary( |
|
148 |
distribution, status, importance, has_patch, fixed_upstream, |
|
149 |
COALESCE(sourcepackagename, -1), |
|
150 |
COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1)) |
|
151 |
WHERE distribution IS NOT NULL; |
|
152 |
CREATE UNIQUE INDEX bugsummary__distroseries__unique |
|
153 |
ON BugSummary( |
|
154 |
distroseries, status, importance, has_patch, fixed_upstream, |
|
155 |
COALESCE(sourcepackagename, -1), |
|
156 |
COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1)) |
|
157 |
WHERE distroseries IS NOT NULL; |
|
158 |
||
159 |
||
160 |
-- Rebuild relevant trigger functions.
|
|
161 |
CREATE OR REPLACE FUNCTION bugsummary_journal_ins(d bugsummary) |
|
162 |
RETURNS VOID |
|
163 |
LANGUAGE plpgsql AS |
|
164 |
$$
|
|
165 |
BEGIN
|
|
166 |
IF d.count <> 0 THEN |
|
167 |
INSERT INTO BugSummaryJournal ( |
|
168 |
count, product, productseries, distribution, |
|
169 |
distroseries, sourcepackagename, viewed_by, tag, |
|
170 |
status, milestone, |
|
171 |
importance, has_patch, fixed_upstream) |
|
172 |
VALUES ( |
|
173 |
d.count, d.product, d.productseries, d.distribution, |
|
174 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
175 |
d.status, d.milestone, |
|
176 |
d.importance, d.has_patch, d.fixed_upstream); |
|
177 |
END IF; |
|
178 |
END; |
|
179 |
$$; |
|
180 |
||
181 |
COMMENT ON FUNCTION bugsummary_journal_ins(bugsummary) IS |
|
182 |
'Add an entry into BugSummaryJournal'; |
|
183 |
||
184 |
||
185 |
CREATE OR REPLACE FUNCTION bugsummary_rollup_journal() RETURNS VOID |
|
186 |
LANGUAGE plpgsql VOLATILE |
|
187 |
SECURITY DEFINER SET search_path TO public AS |
|
188 |
$$
|
|
189 |
DECLARE
|
|
190 |
d bugsummary%ROWTYPE; |
|
191 |
max_id integer; |
|
192 |
BEGIN
|
|
193 |
-- Lock so we don't content with other invokations of this
|
|
194 |
-- function. We can happily lock the BugSummary table for writes
|
|
195 |
-- as this function is the only thing that updates that table.
|
|
196 |
-- BugSummaryJournal remains unlocked so nothing should be blocked.
|
|
197 |
LOCK TABLE BugSummary IN ROW EXCLUSIVE MODE; |
|
198 |
||
199 |
SELECT MAX(id) INTO max_id FROM BugSummaryJournal; |
|
200 |
||
201 |
FOR d IN |
|
202 |
SELECT
|
|
203 |
NULL as id, |
|
204 |
SUM(count), |
|
205 |
product, |
|
206 |
productseries, |
|
207 |
distribution, |
|
208 |
distroseries, |
|
209 |
sourcepackagename, |
|
210 |
viewed_by, |
|
211 |
tag, |
|
212 |
status, |
|
213 |
milestone, |
|
214 |
importance, |
|
215 |
has_patch, |
|
216 |
fixed_upstream
|
|
217 |
FROM BugSummaryJournal |
|
218 |
WHERE id <= max_id |
|
219 |
GROUP BY |
|
220 |
product, productseries, distribution, distroseries, |
|
221 |
sourcepackagename, viewed_by, tag, status, milestone, |
|
7675.1202.9
by Stuart Bishop
Updates |
222 |
importance, has_patch, fixed_upstream |
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
223 |
HAVING sum(count) <> 0 |
224 |
LOOP
|
|
225 |
IF d.count < 0 THEN |
|
226 |
PERFORM bug_summary_dec(d); |
|
227 |
ELSIF d.count > 0 THEN |
|
228 |
PERFORM bug_summary_inc(d); |
|
229 |
END IF; |
|
230 |
END LOOP; |
|
231 |
||
232 |
DELETE FROM BugSummaryJournal WHERE id <= max_id; |
|
233 |
END; |
|
234 |
$$; |
|
235 |
||
236 |
CREATE OR REPLACE FUNCTION bug_summary_dec(bugsummary) RETURNS VOID |
|
237 |
LANGUAGE SQL AS |
|
238 |
$$
|
|
239 |
-- We own the row reference, so in the absence of bugs this cannot
|
|
240 |
-- fail - just decrement the row.
|
|
241 |
UPDATE BugSummary SET count = count + $1.count |
|
242 |
WHERE
|
|
243 |
product IS NOT DISTINCT FROM $1.product |
|
244 |
AND productseries IS NOT DISTINCT FROM $1.productseries |
|
245 |
AND distribution IS NOT DISTINCT FROM $1.distribution |
|
246 |
AND distroseries IS NOT DISTINCT FROM $1.distroseries |
|
247 |
AND sourcepackagename IS NOT DISTINCT FROM $1.sourcepackagename |
|
248 |
AND viewed_by IS NOT DISTINCT FROM $1.viewed_by |
|
249 |
AND tag IS NOT DISTINCT FROM $1.tag |
|
250 |
AND status IS NOT DISTINCT FROM $1.status |
|
251 |
AND milestone IS NOT DISTINCT FROM $1.milestone |
|
252 |
AND importance IS NOT DISTINCT FROM $1.importance |
|
253 |
AND has_patch IS NOT DISTINCT FROM $1.has_patch |
|
254 |
AND fixed_upstream IS NOT DISTINCT FROM $1.fixed_upstream; |
|
255 |
-- gc the row (perhaps should be garbo but easy enough to add here:
|
|
256 |
DELETE FROM bugsummary |
|
257 |
WHERE
|
|
258 |
count=0 |
|
259 |
AND product IS NOT DISTINCT FROM $1.product |
|
260 |
AND productseries IS NOT DISTINCT FROM $1.productseries |
|
261 |
AND distribution IS NOT DISTINCT FROM $1.distribution |
|
262 |
AND distroseries IS NOT DISTINCT FROM $1.distroseries |
|
263 |
AND sourcepackagename IS NOT DISTINCT FROM $1.sourcepackagename |
|
264 |
AND viewed_by IS NOT DISTINCT FROM $1.viewed_by |
|
265 |
AND tag IS NOT DISTINCT FROM $1.tag |
|
266 |
AND status IS NOT DISTINCT FROM $1.status |
|
267 |
AND milestone IS NOT DISTINCT FROM $1.milestone |
|
268 |
AND importance IS NOT DISTINCT FROM $1.importance |
|
269 |
AND has_patch IS NOT DISTINCT FROM $1.has_patch |
|
270 |
AND fixed_upstream IS NOT DISTINCT FROM $1.fixed_upstream; |
|
271 |
-- If its not found then someone else also dec'd and won concurrently.
|
|
272 |
$$; |
|
273 |
||
274 |
CREATE OR REPLACE FUNCTION bug_summary_inc(d bugsummary) RETURNS VOID |
|
275 |
LANGUAGE plpgsql AS |
|
276 |
$$
|
|
277 |
BEGIN
|
|
278 |
-- Shameless adaption from postgresql manual
|
|
279 |
LOOP
|
|
280 |
-- first try to update the row
|
|
281 |
UPDATE BugSummary SET count = count + d.count |
|
282 |
WHERE
|
|
283 |
product IS NOT DISTINCT FROM d.product |
|
284 |
AND productseries IS NOT DISTINCT FROM d.productseries |
|
285 |
AND distribution IS NOT DISTINCT FROM d.distribution |
|
286 |
AND distroseries IS NOT DISTINCT FROM d.distroseries |
|
287 |
AND sourcepackagename IS NOT DISTINCT FROM d.sourcepackagename |
|
288 |
AND viewed_by IS NOT DISTINCT FROM d.viewed_by |
|
289 |
AND tag IS NOT DISTINCT FROM d.tag |
|
290 |
AND status IS NOT DISTINCT FROM d.status |
|
291 |
AND milestone IS NOT DISTINCT FROM d.milestone |
|
292 |
AND importance IS NOT DISTINCT FROM d.importance |
|
293 |
AND has_patch IS NOT DISTINCT FROM d.has_patch |
|
294 |
AND fixed_upstream IS NOT DISTINCT FROM d.fixed_upstream; |
|
295 |
IF found THEN |
|
296 |
RETURN; |
|
297 |
END IF; |
|
298 |
-- not there, so try to insert the key
|
|
299 |
-- if someone else inserts the same key concurrently,
|
|
300 |
-- we could get a unique-key failure
|
|
301 |
BEGIN
|
|
302 |
INSERT INTO BugSummary( |
|
303 |
count, product, productseries, distribution, |
|
304 |
distroseries, sourcepackagename, viewed_by, tag, |
|
305 |
status, milestone, |
|
306 |
importance, has_patch, fixed_upstream) |
|
307 |
VALUES ( |
|
308 |
d.count, d.product, d.productseries, d.distribution, |
|
309 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
310 |
d.status, d.milestone, |
|
311 |
d.importance, d.has_patch, d.fixed_upstream); |
|
312 |
RETURN; |
|
313 |
EXCEPTION WHEN unique_violation THEN |
|
314 |
-- do nothing, and loop to try the UPDATE again
|
|
315 |
END; |
|
316 |
END LOOP; |
|
317 |
END; |
|
318 |
$$; |
|
319 |
||
320 |
COMMENT ON FUNCTION bugsummary_rollup_journal() IS |
|
321 |
'Collate and migrate rows from BugSummaryJournal to BugSummary'; |
|
322 |
||
323 |
||
324 |
CREATE OR REPLACE FUNCTION ensure_bugsummary_temp_journal() RETURNS VOID |
|
325 |
LANGUAGE plpgsql VOLATILE AS |
|
326 |
$$
|
|
327 |
DECLARE
|
|
328 |
BEGIN
|
|
329 |
CREATE TEMPORARY TABLE bugsummary_temp_journal ( |
|
330 |
LIKE bugsummary ) ON COMMIT DROP; |
|
331 |
ALTER TABLE bugsummary_temp_journal ALTER COLUMN id DROP NOT NULL; |
|
332 |
EXCEPTION
|
|
333 |
WHEN duplicate_table THEN |
|
334 |
NULL; |
|
335 |
END; |
|
336 |
$$; |
|
337 |
||
338 |
COMMENT ON FUNCTION ensure_bugsummary_temp_journal() IS |
|
339 |
'Create a temporary table bugsummary_temp_journal if it does not exist.'; |
|
340 |
||
341 |
||
342 |
CREATE OR REPLACE FUNCTION bug_summary_temp_journal_ins(d bugsummary) |
|
343 |
RETURNS VOID LANGUAGE plpgsql AS |
|
344 |
$$
|
|
345 |
BEGIN
|
|
346 |
INSERT INTO BugSummary_Temp_Journal( |
|
347 |
count, product, productseries, distribution, |
|
348 |
distroseries, sourcepackagename, viewed_by, tag, |
|
349 |
status, milestone, importance, has_patch, fixed_upstream) |
|
350 |
VALUES ( |
|
351 |
d.count, d.product, d.productseries, d.distribution, |
|
352 |
d.distroseries, d.sourcepackagename, d.viewed_by, d.tag, |
|
353 |
d.status, d.milestone, d.importance, d.has_patch, d.fixed_upstream); |
|
354 |
RETURN; |
|
355 |
END; |
|
356 |
$$; |
|
357 |
||
358 |
COMMENT ON FUNCTION bug_summary_temp_journal_ins(bugsummary) IS |
|
359 |
'Insert a BugSummary into the temporary journal'; |
|
360 |
||
361 |
||
362 |
-- Don't need these. Faster to just append rows to the journal
|
|
363 |
-- than attempt to update existing rows.
|
|
364 |
DROP FUNCTION bug_summary_temp_journal_dec(bugsummary); |
|
365 |
DROP FUNCTION bug_summary_temp_journal_inc(bugsummary); |
|
366 |
||
367 |
||
368 |
CREATE OR REPLACE FUNCTION bug_summary_flush_temp_journal() RETURNS VOID |
|
369 |
LANGUAGE plpgsql VOLATILE AS |
|
370 |
$$
|
|
371 |
DECLARE
|
|
372 |
d bugsummary%ROWTYPE; |
|
373 |
BEGIN
|
|
374 |
-- may get called even though no summaries were made (for simplicity in the
|
|
375 |
-- callers)
|
|
376 |
PERFORM ensure_bugsummary_temp_journal(); |
|
377 |
FOR d IN |
|
378 |
SELECT
|
|
7675.1202.9
by Stuart Bishop
Updates |
379 |
NULL::integer AS id, SUM(count), product, productseries, |
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
380 |
distribution, distroseries, sourcepackagename, |
381 |
viewed_by, tag, status, milestone, |
|
382 |
importance, has_patch, fixed_upstream |
|
383 |
FROM BugSummary_temp_journal |
|
384 |
GROUP BY |
|
385 |
product, productseries, |
|
386 |
distribution, distroseries, sourcepackagename, |
|
387 |
viewed_by, tag, status, milestone, importance, |
|
388 |
has_patch, fixed_upstream |
|
389 |
HAVING SUM(count) <> 0 |
|
390 |
LOOP
|
|
391 |
IF d.count < 0 THEN |
|
392 |
PERFORM bug_summary_dec(d); |
|
7675.1202.3
by Stuart Bishop
Updates |
393 |
ELSE
|
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
394 |
PERFORM bug_summary_inc(d); |
395 |
END IF; |
|
396 |
END LOOP; |
|
397 |
TRUNCATE bugsummary_temp_journal; |
|
398 |
END; |
|
399 |
$$; |
|
400 |
||
401 |
COMMENT ON FUNCTION bug_summary_flush_temp_journal() IS |
|
402 |
'flush the temporary bugsummary journal into the bugsummary table'; |
|
403 |
||
404 |
||
405 |
CREATE OR REPLACE FUNCTION unsummarise_bug(BUG_ROW bug) RETURNS VOID |
|
406 |
LANGUAGE plpgsql VOLATILE AS |
|
407 |
$$
|
|
408 |
DECLARE
|
|
409 |
d bugsummary%ROWTYPE; |
|
410 |
BEGIN
|
|
411 |
PERFORM ensure_bugsummary_temp_journal(); |
|
412 |
FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP |
|
413 |
d.count = -1; |
|
414 |
PERFORM bug_summary_temp_journal_ins(d); |
|
415 |
END LOOP; |
|
416 |
END; |
|
417 |
$$; |
|
418 |
||
419 |
CREATE OR REPLACE FUNCTION summarise_bug(BUG_ROW bug) RETURNS VOID |
|
420 |
LANGUAGE plpgsql VOLATILE AS |
|
421 |
$$
|
|
422 |
DECLARE
|
|
423 |
d bugsummary%ROWTYPE; |
|
424 |
BEGIN
|
|
425 |
PERFORM ensure_bugsummary_temp_journal(); |
|
426 |
FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP |
|
427 |
d.count = 1; |
|
428 |
PERFORM bug_summary_temp_journal_ins(d); |
|
429 |
END LOOP; |
|
430 |
END; |
|
431 |
$$; |
|
432 |
||
433 |
||
434 |
CREATE OR REPLACE FUNCTION bug_maintain_bug_summary() RETURNS TRIGGER |
|
435 |
LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS |
|
436 |
$$
|
|
437 |
BEGIN
|
|
438 |
-- There is no INSERT logic, as a bug will not have any summary
|
|
439 |
-- information until BugTask rows have been attached.
|
|
440 |
IF TG_OP = 'UPDATE' THEN |
|
441 |
IF OLD.duplicateof IS DISTINCT FROM NEW.duplicateof |
|
442 |
OR OLD.private IS DISTINCT FROM NEW.private |
|
7675.1202.7
by Stuart Bishop
Update |
443 |
OR (OLD.latest_patch_uploaded IS NULL) |
444 |
<> (NEW.latest_patch_uploaded IS NULL) THEN |
|
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
445 |
PERFORM unsummarise_bug(OLD); |
446 |
PERFORM summarise_bug(NEW); |
|
447 |
END IF; |
|
448 |
||
449 |
ELSIF TG_OP = 'DELETE' THEN |
|
450 |
PERFORM unsummarise_bug(OLD); |
|
451 |
END IF; |
|
452 |
||
453 |
PERFORM bug_summary_flush_temp_journal(); |
|
454 |
RETURN NULL; -- Ignored - this is an AFTER trigger |
|
455 |
END; |
|
456 |
$$; |
|
457 |
||
458 |
||
459 |
CREATE OR REPLACE FUNCTION bugtask_maintain_bug_summary() RETURNS TRIGGER |
|
460 |
LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS |
|
461 |
$$
|
|
462 |
BEGIN
|
|
463 |
-- This trigger only works if we are inserting, updating or deleting
|
|
464 |
-- a single row per statement.
|
|
465 |
||
466 |
-- Unlike bug_maintain_bug_summary, this trigger does not have access
|
|
467 |
-- to the old bug when invoked as an AFTER trigger. To work around this
|
|
468 |
-- we install this trigger as both a BEFORE and an AFTER trigger.
|
|
469 |
IF TG_OP = 'INSERT' THEN |
|
470 |
IF TG_WHEN = 'BEFORE' THEN |
|
471 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
472 |
ELSE
|
|
473 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
474 |
END IF; |
|
475 |
PERFORM bug_summary_flush_temp_journal(); |
|
476 |
RETURN NEW; |
|
477 |
||
478 |
ELSIF TG_OP = 'DELETE' THEN |
|
479 |
IF TG_WHEN = 'BEFORE' THEN |
|
480 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
481 |
ELSE
|
|
482 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
483 |
END IF; |
|
484 |
PERFORM bug_summary_flush_temp_journal(); |
|
485 |
RETURN OLD; |
|
486 |
||
487 |
ELSE
|
|
488 |
IF (OLD.product IS DISTINCT FROM NEW.product |
|
489 |
OR OLD.productseries IS DISTINCT FROM NEW.productseries |
|
490 |
OR OLD.distribution IS DISTINCT FROM NEW.distribution |
|
491 |
OR OLD.distroseries IS DISTINCT FROM NEW.distroseries |
|
492 |
OR OLD.sourcepackagename IS DISTINCT FROM NEW.sourcepackagename |
|
493 |
OR OLD.status IS DISTINCT FROM NEW.status |
|
7675.1202.16
by Stuart Bishop
Fix trigger for importance, and add XXX explaining why fixed_upstream logic is currently broken |
494 |
OR OLD.importance IS DISTINCT FROM NEW.importance |
7675.1202.7
by Stuart Bishop
Update |
495 |
OR OLD.bugwatch IS DISTINCT FROM NEW.bugwatch |
496 |
OR OLD.milestone IS DISTINCT FROM NEW.milestone) THEN |
|
497 |
||
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
498 |
IF TG_WHEN = 'BEFORE' THEN |
499 |
PERFORM unsummarise_bug(bug_row(OLD.bug)); |
|
500 |
IF OLD.bug <> NEW.bug THEN |
|
501 |
PERFORM unsummarise_bug(bug_row(NEW.bug)); |
|
502 |
END IF; |
|
503 |
ELSE
|
|
504 |
PERFORM summarise_bug(bug_row(OLD.bug)); |
|
505 |
IF OLD.bug <> NEW.bug THEN |
|
506 |
PERFORM summarise_bug(bug_row(NEW.bug)); |
|
507 |
END IF; |
|
508 |
END IF; |
|
509 |
END IF; |
|
510 |
PERFORM bug_summary_flush_temp_journal(); |
|
511 |
RETURN NEW; |
|
512 |
END IF; |
|
513 |
END; |
|
514 |
$$; |
|
515 |
||
516 |
||
7675.1202.4
by Stuart Bishop
Updates |
517 |
CREATE OR REPLACE FUNCTION bugsummary_locations(BUG_ROW bug) |
518 |
RETURNS SETOF bugsummary LANGUAGE plpgsql AS |
|
519 |
$$
|
|
520 |
BEGIN
|
|
521 |
IF BUG_ROW.duplicateof IS NOT NULL THEN |
|
522 |
RETURN; |
|
523 |
END IF; |
|
524 |
RETURN QUERY |
|
525 |
SELECT
|
|
526 |
CAST(NULL AS integer) AS id, |
|
527 |
CAST(1 AS integer) AS count, |
|
528 |
product, productseries, distribution, distroseries, |
|
529 |
sourcepackagename, person AS viewed_by, tag, status, milestone, |
|
530 |
importance, |
|
531 |
BUG_ROW.latest_patch_uploaded IS NOT NULL AS has_patch, |
|
7675.1202.5
by Stuart Bishop
Updates |
532 |
(EXISTS ( |
7675.1202.17
by Stuart Bishop
A BugTask is not fixed_upstream if it is fixed, only if a related BugTask is fixed. Wierd. |
533 |
SELECT TRUE FROM BugTask AS RBT |
7675.1202.4
by Stuart Bishop
Updates |
534 |
WHERE
|
7675.1202.17
by Stuart Bishop
A BugTask is not fixed_upstream if it is fixed, only if a related BugTask is fixed. Wierd. |
535 |
RBT.bug = tasks.bug |
536 |
-- This would just be 'RBT.id <> tasks.id', except
|
|
537 |
-- that the records from tasks are summaries and not
|
|
538 |
-- real bugtasks, and do not have an id.
|
|
539 |
AND (RBT.product IS DISTINCT FROM tasks.product |
|
540 |
OR RBT.productseries |
|
541 |
IS DISTINCT FROM tasks.productseries |
|
542 |
OR RBT.distribution IS DISTINCT FROM tasks.distribution |
|
543 |
OR RBT.distroseries IS DISTINCT FROM tasks.distroseries |
|
544 |
OR RBT.sourcepackagename |
|
545 |
IS DISTINCT FROM tasks.sourcepackagename) |
|
546 |
-- Flagged as INVALID, FIXCOMMITTED or FIXRELEASED
|
|
547 |
-- via a bugwatch, or FIXCOMMITTED or FIXRELEASED on
|
|
548 |
-- the product.
|
|
7675.1202.4
by Stuart Bishop
Updates |
549 |
AND ((bugwatch IS NOT NULL AND status IN (17, 25, 30)) |
550 |
OR (bugwatch IS NULL AND product IS NOT NULL |
|
7675.1202.17
by Stuart Bishop
A BugTask is not fixed_upstream if it is fixed, only if a related BugTask is fixed. Wierd. |
551 |
AND status IN (25, 30)))) |
552 |
)::boolean AS fixed_upstream |
|
7675.1202.4
by Stuart Bishop
Updates |
553 |
FROM bugsummary_tasks(BUG_ROW) AS tasks |
554 |
JOIN bugsummary_tags(BUG_ROW) AS bug_tags ON TRUE |
|
555 |
LEFT OUTER JOIN bugsummary_viewers(BUG_ROW) AS bug_viewers ON TRUE; |
|
556 |
END; |
|
557 |
$$; |
|
558 |
||
7675.1202.5
by Stuart Bishop
Updates |
559 |
COMMENT ON FUNCTION bugsummary_locations(bug) IS |
560 |
'Calculate what BugSummary rows should exist for a given Bug.'; |
|
561 |
||
562 |
||
563 |
CREATE OR REPLACE FUNCTION bugsummary_tasks(BUG_ROW bug) |
|
564 |
RETURNS SETOF bugtask LANGUAGE plpgsql STABLE AS |
|
565 |
$$
|
|
566 |
DECLARE
|
|
567 |
bt bugtask%ROWTYPE; |
|
568 |
r record; |
|
569 |
BEGIN
|
|
570 |
bt.bug = BUG_ROW.id; |
|
571 |
||
572 |
-- One row only for each target permutation - need to ignore other fields
|
|
573 |
-- like date last modified to deal with conjoined masters and multiple
|
|
574 |
-- sourcepackage tasks in a distro.
|
|
575 |
FOR r IN |
|
576 |
SELECT
|
|
577 |
product, productseries, distribution, distroseries, |
|
7675.1202.16
by Stuart Bishop
Fix trigger for importance, and add XXX explaining why fixed_upstream logic is currently broken |
578 |
sourcepackagename, status, milestone, importance, bugwatch |
7675.1202.5
by Stuart Bishop
Updates |
579 |
FROM BugTask WHERE bug=BUG_ROW.id |
580 |
UNION -- Implicit DISTINCT |
|
581 |
SELECT
|
|
582 |
product, productseries, distribution, distroseries, |
|
7675.1202.16
by Stuart Bishop
Fix trigger for importance, and add XXX explaining why fixed_upstream logic is currently broken |
583 |
NULL, status, milestone, importance, bugwatch |
7675.1202.5
by Stuart Bishop
Updates |
584 |
FROM BugTask WHERE bug=BUG_ROW.id AND sourcepackagename IS NOT NULL |
585 |
LOOP
|
|
586 |
bt.product = r.product; |
|
587 |
bt.productseries = r.productseries; |
|
588 |
bt.distribution = r.distribution; |
|
589 |
bt.distroseries = r.distroseries; |
|
590 |
bt.sourcepackagename = r.sourcepackagename; |
|
591 |
bt.status = r.status; |
|
592 |
bt.milestone = r.milestone; |
|
593 |
bt.importance = r.importance; |
|
7675.1202.16
by Stuart Bishop
Fix trigger for importance, and add XXX explaining why fixed_upstream logic is currently broken |
594 |
bt.bugwatch = r.bugwatch; |
7675.1202.5
by Stuart Bishop
Updates |
595 |
RETURN NEXT bt; |
596 |
END LOOP; |
|
597 |
END; |
|
598 |
$$; |
|
599 |
||
600 |
COMMENT ON FUNCTION bugsummary_tasks(bug) IS |
|
601 |
'Return all tasks for the bug + all sourcepackagename tasks again with the sourcepackagename squashed'; |
|
602 |
||
603 |
||
7675.1202.4
by Stuart Bishop
Updates |
604 |
|
7675.1202.2
by Stuart Bishop
Draft of DB patch extending BugSummary |
605 |
INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 75, 0); |