← Back to team overview

launchpad-reviewers team mailing list archive

[Merge] lp:~stub/launchpad/bugsummary into lp:launchpad/db-devel

 

Stuart Bishop has proposed merging lp:~stub/launchpad/bugsummary into lp:launchpad/db-devel with lp:~stub/launchpad/pending-db-changes as a prerequisite.

Requested reviews:
  Launchpad code reviewers (launchpad-reviewers)

For more details, see:
https://code.launchpad.net/~stub/launchpad/bugsummary/+merge/64583

= Summary =

Add three more fields to BugSummary: importance, has_patch, fixed_upstream

== Proposed fix ==

More columns, more triggers, more tests

== Tests ==

./test -vv test_bugsummary
./test -vv --test=bugsummary.txt
-- 
https://code.launchpad.net/~stub/launchpad/bugsummary/+merge/64583
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~stub/launchpad/bugsummary into lp:launchpad/db-devel.
=== modified file 'database/sampledata/current-dev.sql'
--- database/sampledata/current-dev.sql	2011-06-06 21:40:15 +0000
+++ database/sampledata/current-dev.sql	2011-06-14 17:46:28 +0000
@@ -849,6 +849,9 @@
 
 
 
+
+
+
 SET SESSION AUTHORIZATION DEFAULT;
 
 ALTER TABLE account DISABLE TRIGGER ALL;
@@ -3832,75 +3835,84 @@
 
 ALTER TABLE bugsummary DISABLE TRIGGER ALL;
 
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (1, 1, 1, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (2, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 30, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (3, 1, NULL, NULL, NULL, 7, NULL, NULL, NULL, 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (4, 1, NULL, 2, NULL, NULL, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (5, 1, NULL, NULL, 3, NULL, 1, NULL, 'pebcak', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (6, 1, NULL, NULL, 1, NULL, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (7, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (8, 1, NULL, NULL, 1, NULL, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (9, 1, 20, NULL, NULL, NULL, NULL, 14, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (10, 1, 17, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (11, 1, NULL, NULL, NULL, 6, 1, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (12, 1, NULL, NULL, NULL, 6, 1, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (13, 1, NULL, NULL, 1, NULL, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (14, 2, NULL, NULL, 3, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (15, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (16, 1, NULL, NULL, NULL, 6, 1, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (17, 1, 20, NULL, NULL, NULL, NULL, 63, 'lunch-money', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (18, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (19, 1, NULL, NULL, 3, NULL, 1, NULL, 'dataloss', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (20, 2, NULL, NULL, NULL, 6, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (21, 3, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (22, 1, NULL, NULL, NULL, 7, 1, NULL, 'layout-test', 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (23, 1, NULL, NULL, 3, NULL, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (24, 1, NULL, NULL, NULL, 3, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (25, 1, NULL, NULL, 1, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (26, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (27, 1, NULL, NULL, NULL, 3, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (28, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (29, 1, NULL, NULL, NULL, 1, 1, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (30, 1, NULL, NULL, NULL, 1, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (31, 2, NULL, NULL, 3, NULL, 1, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (32, 1, 4, NULL, NULL, NULL, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (33, 1, 22, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (34, 1, NULL, NULL, NULL, 6, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (35, 1, NULL, NULL, 3, NULL, NULL, NULL, 'dataloss', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (36, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (37, 1, NULL, NULL, 1, NULL, 18, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (38, 1, NULL, NULL, 3, NULL, 9, NULL, NULL, 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (39, 2, NULL, NULL, NULL, 6, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (40, 1, 20, NULL, NULL, NULL, NULL, 63, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (41, 1, 1, NULL, NULL, NULL, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (42, 1, NULL, NULL, NULL, 7, NULL, NULL, 'layout-test', 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (43, 1, 20, NULL, NULL, NULL, NULL, 14, 'lunch-money', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (44, 1, 4, NULL, NULL, NULL, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (45, 1, NULL, NULL, NULL, 7, 1, NULL, NULL, 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (46, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 30, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (47, 1, 1, NULL, NULL, NULL, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (48, 3, NULL, NULL, 1, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (49, 1, NULL, NULL, 3, NULL, NULL, NULL, 'pebcak', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (50, 1, NULL, NULL, 1, NULL, 18, NULL, 'crash', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (51, 1, NULL, 2, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (52, 1, NULL, NULL, NULL, 6, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (53, 1, NULL, NULL, NULL, 6, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (54, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (55, 1, NULL, NULL, NULL, 3, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (56, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (57, 1, 8, NULL, NULL, NULL, NULL, NULL, 'crash', 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (58, 1, NULL, NULL, NULL, 1, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (59, 1, NULL, NULL, 1, NULL, 22, NULL, 'crash', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (60, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (61, 1, NULL, NULL, 1, NULL, 22, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (62, 1, NULL, NULL, 3, NULL, 1, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (63, 1, 5, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (64, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 999, NULL);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (65, 1, 20, NULL, NULL, NULL, NULL, 14, 'lunch-money', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (66, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (67, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (68, 1, 1, NULL, NULL, NULL, NULL, NULL, 'dataloss', 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (69, 2, NULL, NULL, NULL, 6, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (70, 1, NULL, NULL, NULL, 3, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (71, 1, NULL, NULL, 1, NULL, 18, NULL, NULL, 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (72, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (73, 1, NULL, NULL, NULL, 1, NULL, NULL, 'doc', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (74, 1, NULL, NULL, 3, NULL, NULL, NULL, 'dataloss', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (75, 1, 8, NULL, NULL, NULL, NULL, NULL, 'crash', 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (76, 1, 4, NULL, NULL, NULL, NULL, NULL, 'doc', 10, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (77, 1, NULL, NULL, 1, NULL, 22, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (78, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 20, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (79, 1, 22, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (80, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (81, 1, NULL, NULL, 3, NULL, 1, NULL, 'dataloss', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (82, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (83, 1, NULL, NULL, NULL, 1, 1, NULL, 'doc', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (84, 1, NULL, NULL, NULL, 7, NULL, NULL, NULL, 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (85, 1, 20, NULL, NULL, NULL, NULL, 63, 'lunch-money', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (86, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (87, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 30, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (88, 1, NULL, NULL, NULL, 6, 1, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (89, 1, NULL, NULL, NULL, 6, NULL, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (90, 1, NULL, NULL, NULL, 3, NULL, NULL, 'dataloss', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (91, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 30, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (92, 1, NULL, 2, NULL, NULL, NULL, NULL, 'doc', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (93, 1, 1, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (94, 1, NULL, NULL, NULL, 7, 1, NULL, NULL, 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (95, 2, NULL, NULL, 3, NULL, NULL, NULL, NULL, 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (96, 1, 4, NULL, NULL, NULL, NULL, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (97, 1, NULL, NULL, 1, NULL, NULL, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (98, 2, NULL, NULL, 3, NULL, 1, NULL, NULL, 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (99, 1, NULL, NULL, 3, NULL, 9, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (100, 1, NULL, NULL, NULL, 6, NULL, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (101, 1, NULL, NULL, NULL, 6, NULL, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (102, 1, NULL, NULL, NULL, 3, NULL, NULL, 'pebcak', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (103, 1, NULL, NULL, 3, NULL, 1, NULL, 'layout-test', 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (104, 1, 5, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (105, 1, 20, NULL, NULL, NULL, NULL, 63, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (106, 1, NULL, NULL, 3, NULL, NULL, NULL, 'layout-test', 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (107, 1, NULL, NULL, NULL, 6, 1, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (108, 1, NULL, NULL, NULL, 6, 1, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (109, 1, NULL, NULL, 1, NULL, NULL, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (110, 1, NULL, NULL, NULL, 1, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (111, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (112, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (113, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (114, 1, 1, NULL, NULL, NULL, NULL, NULL, 'pebcak', 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (115, 1, NULL, NULL, 1, NULL, 18, NULL, 'crash', 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (116, 1, NULL, NULL, NULL, 7, 1, NULL, 'layout-test', 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (117, 1, 17, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (118, 1, NULL, NULL, NULL, 7, NULL, NULL, 'layout-test', 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (119, 1, NULL, 2, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (120, 1, 20, NULL, NULL, NULL, NULL, 14, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (121, 1, NULL, NULL, 1, NULL, NULL, NULL, NULL, 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (122, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (123, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (124, 1, NULL, NULL, 3, NULL, 1, NULL, 'pebcak', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (125, 1, NULL, NULL, 1, NULL, 22, NULL, 'crash', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (126, 3, NULL, NULL, 1, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (127, 1, NULL, NULL, 1, NULL, 1, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (128, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (129, 1, NULL, NULL, 3, NULL, NULL, NULL, 'pebcak', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (130, 2, NULL, NULL, NULL, 6, 1, NULL, NULL, 10, NULL, 30, false, false);
 
 
 ALTER TABLE bugsummary ENABLE TRIGGER ALL;
 
 
+ALTER TABLE bugsummaryjournal DISABLE TRIGGER ALL;
+
+
+
+ALTER TABLE bugsummaryjournal ENABLE TRIGGER ALL;
+
+
 ALTER TABLE bugtag DISABLE TRIGGER ALL;
 
 INSERT INTO bugtag (id, bug, tag) VALUES (1, 9, 'crash');

=== modified file 'database/sampledata/current.sql'
--- database/sampledata/current.sql	2011-06-06 21:40:15 +0000
+++ database/sampledata/current.sql	2011-06-14 17:46:28 +0000
@@ -849,6 +849,9 @@
 
 
 
+
+
+
 SET SESSION AUTHORIZATION DEFAULT;
 
 ALTER TABLE account DISABLE TRIGGER ALL;
@@ -3768,75 +3771,84 @@
 
 ALTER TABLE bugsummary DISABLE TRIGGER ALL;
 
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (1, 1, 1, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (2, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 30, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (3, 1, NULL, NULL, NULL, 7, NULL, NULL, NULL, 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (4, 1, NULL, 2, NULL, NULL, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (5, 1, NULL, NULL, 3, NULL, 1, NULL, 'pebcak', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (6, 1, NULL, NULL, 1, NULL, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (7, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (8, 1, NULL, NULL, 1, NULL, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (9, 1, 20, NULL, NULL, NULL, NULL, 14, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (10, 1, 17, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (11, 1, NULL, NULL, NULL, 6, 1, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (12, 1, NULL, NULL, NULL, 6, 1, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (13, 1, NULL, NULL, 1, NULL, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (14, 2, NULL, NULL, 3, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (15, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (16, 1, NULL, NULL, NULL, 6, 1, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (17, 1, 20, NULL, NULL, NULL, NULL, 63, 'lunch-money', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (18, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (19, 1, NULL, NULL, 3, NULL, 1, NULL, 'dataloss', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (20, 2, NULL, NULL, NULL, 6, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (21, 3, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (22, 1, NULL, NULL, NULL, 7, 1, NULL, 'layout-test', 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (23, 1, NULL, NULL, 3, NULL, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (24, 1, NULL, NULL, NULL, 3, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (25, 1, NULL, NULL, 1, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (26, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (27, 1, NULL, NULL, NULL, 3, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (28, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (29, 1, NULL, NULL, NULL, 1, 1, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (30, 1, NULL, NULL, NULL, 1, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (31, 2, NULL, NULL, 3, NULL, 1, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (32, 1, 4, NULL, NULL, NULL, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (33, 1, 22, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (34, 1, NULL, NULL, NULL, 6, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (35, 1, NULL, NULL, 3, NULL, NULL, NULL, 'dataloss', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (36, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (37, 1, NULL, NULL, 1, NULL, 18, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (38, 1, NULL, NULL, 3, NULL, 9, NULL, NULL, 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (39, 2, NULL, NULL, NULL, 6, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (40, 1, 20, NULL, NULL, NULL, NULL, 63, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (41, 1, 1, NULL, NULL, NULL, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (42, 1, NULL, NULL, NULL, 7, NULL, NULL, 'layout-test', 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (43, 1, 20, NULL, NULL, NULL, NULL, 14, 'lunch-money', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (44, 1, 4, NULL, NULL, NULL, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (45, 1, NULL, NULL, NULL, 7, 1, NULL, NULL, 10, 2);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (46, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 30, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (47, 1, 1, NULL, NULL, NULL, NULL, NULL, 'dataloss', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (48, 3, NULL, NULL, 1, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (49, 1, NULL, NULL, 3, NULL, NULL, NULL, 'pebcak', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (50, 1, NULL, NULL, 1, NULL, 18, NULL, 'crash', 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (51, 1, NULL, 2, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (52, 1, NULL, NULL, NULL, 6, NULL, NULL, 'pebcak', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (53, 1, NULL, NULL, NULL, 6, NULL, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (54, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (55, 1, NULL, NULL, NULL, 3, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (56, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 20, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (57, 1, 8, NULL, NULL, NULL, NULL, NULL, 'crash', 999, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (58, 1, NULL, NULL, NULL, 1, NULL, NULL, 'doc', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (59, 1, NULL, NULL, 1, NULL, 22, NULL, 'crash', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (60, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (61, 1, NULL, NULL, 1, NULL, 22, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (62, 1, NULL, NULL, 3, NULL, 1, NULL, 'layout-test', 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (63, 1, 5, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL);
-INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone) VALUES (64, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 999, NULL);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (65, 1, 20, NULL, NULL, NULL, NULL, 14, 'lunch-money', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (66, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (67, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (68, 1, 1, NULL, NULL, NULL, NULL, NULL, 'dataloss', 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (69, 2, NULL, NULL, NULL, 6, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (70, 1, NULL, NULL, NULL, 3, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (71, 1, NULL, NULL, 1, NULL, 18, NULL, NULL, 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (72, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (73, 1, NULL, NULL, NULL, 1, NULL, NULL, 'doc', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (74, 1, NULL, NULL, 3, NULL, NULL, NULL, 'dataloss', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (75, 1, 8, NULL, NULL, NULL, NULL, NULL, 'crash', 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (76, 1, 4, NULL, NULL, NULL, NULL, NULL, 'doc', 10, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (77, 1, NULL, NULL, 1, NULL, 22, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (78, 1, 20, NULL, NULL, NULL, NULL, NULL, NULL, 20, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (79, 1, 22, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (80, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (81, 1, NULL, NULL, 3, NULL, 1, NULL, 'dataloss', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (82, 1, NULL, NULL, 1, NULL, NULL, NULL, 'crash', 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (83, 1, NULL, NULL, NULL, 1, 1, NULL, 'doc', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (84, 1, NULL, NULL, NULL, 7, NULL, NULL, NULL, 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (85, 1, 20, NULL, NULL, NULL, NULL, 63, 'lunch-money', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (86, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (87, 1, NULL, NULL, 3, NULL, 1, NULL, NULL, 30, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (88, 1, NULL, NULL, NULL, 6, 1, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (89, 1, NULL, NULL, NULL, 6, NULL, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (90, 1, NULL, NULL, NULL, 3, NULL, NULL, 'dataloss', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (91, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 30, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (92, 1, NULL, 2, NULL, NULL, NULL, NULL, 'doc', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (93, 1, 1, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (94, 1, NULL, NULL, NULL, 7, 1, NULL, NULL, 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (95, 2, NULL, NULL, 3, NULL, NULL, NULL, NULL, 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (96, 1, 4, NULL, NULL, NULL, NULL, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (97, 1, NULL, NULL, 1, NULL, NULL, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (98, 2, NULL, NULL, 3, NULL, 1, NULL, NULL, 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (99, 1, NULL, NULL, 3, NULL, 9, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (100, 1, NULL, NULL, NULL, 6, NULL, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (101, 1, NULL, NULL, NULL, 6, NULL, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (102, 1, NULL, NULL, NULL, 3, NULL, NULL, 'pebcak', 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (103, 1, NULL, NULL, 3, NULL, 1, NULL, 'layout-test', 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (104, 1, 5, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (105, 1, 20, NULL, NULL, NULL, NULL, 63, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (106, 1, NULL, NULL, 3, NULL, NULL, NULL, 'layout-test', 10, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (107, 1, NULL, NULL, NULL, 6, 1, NULL, 'pebcak', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (108, 1, NULL, NULL, NULL, 6, 1, NULL, 'layout-test', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (109, 1, NULL, NULL, 1, NULL, NULL, NULL, 'dataloss', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (110, 1, NULL, NULL, NULL, 1, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (111, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 50, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (112, 1, NULL, NULL, NULL, 1, 1, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (113, 1, NULL, NULL, 3, NULL, NULL, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (114, 1, 1, NULL, NULL, NULL, NULL, NULL, 'pebcak', 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (115, 1, NULL, NULL, 1, NULL, 18, NULL, 'crash', 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (116, 1, NULL, NULL, NULL, 7, 1, NULL, 'layout-test', 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (117, 1, 17, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (118, 1, NULL, NULL, NULL, 7, NULL, NULL, 'layout-test', 10, 2, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (119, 1, NULL, 2, NULL, NULL, NULL, NULL, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (120, 1, 20, NULL, NULL, NULL, NULL, 14, NULL, 10, NULL, 5, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (121, 1, NULL, NULL, 1, NULL, NULL, NULL, NULL, 20, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (122, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (123, 1, 4, NULL, NULL, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (124, 1, NULL, NULL, 3, NULL, 1, NULL, 'pebcak', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (125, 1, NULL, NULL, 1, NULL, 22, NULL, 'crash', 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (126, 3, NULL, NULL, 1, NULL, NULL, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (127, 1, NULL, NULL, 1, NULL, 1, NULL, NULL, 10, NULL, 30, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (128, 1, 8, NULL, NULL, NULL, NULL, NULL, NULL, 999, NULL, 999, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (129, 1, NULL, NULL, 3, NULL, NULL, NULL, 'pebcak', 20, NULL, 20, false, false);
+INSERT INTO bugsummary (id, count, product, productseries, distribution, distroseries, sourcepackagename, viewed_by, tag, status, milestone, importance, has_patch, fixed_upstream) VALUES (130, 2, NULL, NULL, NULL, 6, 1, NULL, NULL, 10, NULL, 30, false, false);
 
 
 ALTER TABLE bugsummary ENABLE TRIGGER ALL;
 
 
+ALTER TABLE bugsummaryjournal DISABLE TRIGGER ALL;
+
+
+
+ALTER TABLE bugsummaryjournal ENABLE TRIGGER ALL;
+
+
 ALTER TABLE bugtag DISABLE TRIGGER ALL;
 
 INSERT INTO bugtag (id, bug, tag) VALUES (1, 9, 'crash');

=== added file 'database/schema/patch-2208-75-0.sql'
--- database/schema/patch-2208-75-0.sql	1970-01-01 00:00:00 +0000
+++ database/schema/patch-2208-75-0.sql	2011-06-14 17:46:28 +0000
@@ -0,0 +1,601 @@
+-- Copyright 2011 Canonical Ltd.  This software is licensed under the
+-- GNU Affero General Public License version 3 (see the file LICENSE).
+
+SET client_min_messages=ERROR;
+
+-- Trash our existing data, which we will rebuild in a minute.
+-- Slony-I doesn't like TRUNCATE noramlly, but OK in a DB patch.
+TRUNCATE BugSummary;
+TRUNCATE BugSummaryJournal;
+
+-- Drop indexes we will rebuild later.
+DROP INDEX bugsummary__dimensions__unique;
+DROP INDEX bugsummary__full__idx;
+
+ALTER TABLE BugSummary
+    -- Add a missing foreign key constraint we were unable to add live.
+    -- Person table is always being read, so locks are never acquired.
+    ADD CONSTRAINT bugsummaryjournal_viewed_by_fkey
+        FOREIGN KEY(viewed_by) REFERENCES Person ON DELETE CASCADE,
+    ADD COLUMN importance integer NOT NULL,
+    ADD COLUMN has_patch boolean NOT NULL,
+    ADD COLUMN fixed_upstream boolean NOT NULL;
+
+ALTER TABLE BugSummaryJournal
+    ADD COLUMN importance integer NOT NULL,
+    ADD COLUMN has_patch boolean NOT NULL,
+    ADD COLUMN fixed_upstream boolean NOT NULL;
+
+DROP VIEW CombinedBugSummary;
+CREATE VIEW CombinedBugSummary AS (
+    SELECT
+        id, count, product, productseries, distribution, distroseries,
+        sourcepackagename, viewed_by, tag, status, milestone,
+        importance, has_patch, fixed_upstream
+    FROM BugSummary
+    UNION ALL
+    SELECT
+        -id as id, count, product, productseries, distribution, distroseries,
+        sourcepackagename, viewed_by, tag, status, milestone,
+        importance, has_patch, fixed_upstream
+    FROM BugSummaryJournal);
+
+
+-- Rebuild the BugSummary data with the new columns.
+INSERT INTO bugsummary (
+    count, product, productseries, distribution, distroseries,
+    sourcepackagename, viewed_by, tag, status, milestone,
+    importance, has_patch, fixed_upstream)
+WITH
+    -- kill dupes
+    relevant_bug AS (SELECT * FROM bug where duplicateof is NULL),
+
+    -- (bug.id, tag) for all bug-tag pairs plus (bug.id, NULL) for all bugs
+    bug_tags AS (
+        SELECT relevant_bug.id, NULL::text AS tag FROM relevant_bug
+        UNION
+        SELECT relevant_bug.id, tag
+        FROM relevant_bug INNER JOIN bugtag ON relevant_bug.id=bugtag.bug),
+    -- (bug.id, NULL) for all public bugs + (bug.id, viewer) for all
+    -- (subscribers+assignee) on private bugs
+    bug_viewers AS (
+        SELECT relevant_bug.id, NULL::integer AS person
+        FROM relevant_bug WHERE NOT relevant_bug.private
+        UNION
+        SELECT relevant_bug.id, assignee AS person
+        FROM relevant_bug
+        INNER JOIN bugtask ON relevant_bug.id=bugtask.bug
+        WHERE relevant_bug.private and bugtask.assignee IS NOT NULL
+        UNION
+        SELECT relevant_bug.id, bugsubscription.person
+        FROM relevant_bug INNER JOIN bugsubscription
+            ON bugsubscription.bug=relevant_bug.id WHERE relevant_bug.private),
+
+    fixed_upstream_tasks AS (
+        SELECT BugTask.id, BugTask.bug FROM BugTask
+        WHERE (
+            (bugwatch IS NOT NULL AND status IN (17, 25, 30))
+            OR (
+                bugwatch IS NULL AND product IS NOT NULL
+                AND status IN (25, 30)))),
+
+    -- (bugtask.(bug, product, productseries, distribution, distroseries,
+    -- sourcepackagename, status, milestone) for all bugs + the same with
+    -- sourcepackage squashed to NULL)
+    tasks AS (
+        SELECT
+            bug, product, productseries, distribution, distroseries,
+            sourcepackagename, status, milestone, importance,
+            EXISTS (
+                SELECT TRUE FROM fixed_upstream_tasks
+                WHERE 
+                    BugTask.bug = fixed_upstream_tasks.bug
+                    AND BugTask.id <> fixed_upstream_tasks.id
+                    ) AS fixed_upstream
+        FROM bugtask
+        UNION
+        SELECT DISTINCT ON (
+            bug, product, productseries, distribution, distroseries,
+            sourcepackagename, milestone)
+            bug, product, productseries, distribution, distroseries,
+            NULL::integer as sourcepackagename,
+            status, milestone, importance,
+            EXISTS (
+                SELECT TRUE FROM fixed_upstream_tasks
+                WHERE
+                    BugTask.bug = fixed_upstream_tasks.bug
+                    AND BugTask.id <> fixed_upstream_tasks.id
+                    ) AS fixed_upstream
+        FROM bugtask where sourcepackagename IS NOT NULL)
+
+    -- Now combine
+    SELECT
+        count(*), product, productseries, distribution, distroseries,
+        sourcepackagename, person, tag, status, milestone, importance,
+        latest_patch_uploaded IS NOT NULL AS has_patch, fixed_upstream
+    FROM relevant_bug
+    INNER JOIN bug_tags ON relevant_bug.id=bug_tags.id
+    INNER JOIN bug_viewers ON relevant_bug.id=bug_viewers.id
+    INNER JOIN tasks on tasks.bug=relevant_bug.id
+    GROUP BY
+        product, productseries, distribution, distroseries,
+        sourcepackagename, person, tag, status, milestone,
+        importance, has_patch, fixed_upstream;
+
+
+-- Rebuild indexes.
+CREATE INDEX bugsummary__full__idx ON BugSummary (
+    tag, status, product, productseries, distribution,
+    distroseries, sourcepackagename, viewed_by, milestone,
+    importance, has_patch, fixed_upstream);
+-- Enforce uniqueness again.
+CREATE UNIQUE INDEX bugsummary__product__unique
+    ON BugSummary(
+        product, status, importance, has_patch, fixed_upstream,
+        COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1))
+    WHERE product IS NOT NULL;
+CREATE UNIQUE INDEX bugsummary__productseries__unique
+    ON BugSummary(
+        productseries, status, importance, has_patch, fixed_upstream,
+        COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1))
+    WHERE productseries IS NOT NULL;
+CREATE UNIQUE INDEX bugsummary__distribution__unique
+    ON BugSummary(
+        distribution, status, importance, has_patch, fixed_upstream,
+        COALESCE(sourcepackagename, -1),
+        COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1))
+    WHERE distribution IS NOT NULL;
+CREATE UNIQUE INDEX bugsummary__distroseries__unique
+    ON BugSummary(
+        distroseries, status, importance, has_patch, fixed_upstream,
+        COALESCE(sourcepackagename, -1),
+        COALESCE(tag, ''), COALESCE(milestone, -1), COALESCE(viewed_by, -1))
+    WHERE distroseries IS NOT NULL;
+
+
+-- Rebuild relevant trigger functions.
+CREATE OR REPLACE FUNCTION bugsummary_journal_ins(d bugsummary)
+RETURNS VOID
+LANGUAGE plpgsql AS
+$$
+BEGIN
+    IF d.count <> 0 THEN
+        INSERT INTO BugSummaryJournal (
+            count, product, productseries, distribution,
+            distroseries, sourcepackagename, viewed_by, tag,
+            status, milestone,
+            importance, has_patch, fixed_upstream)
+        VALUES (
+            d.count, d.product, d.productseries, d.distribution,
+            d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
+            d.status, d.milestone,
+            d.importance, d.has_patch, d.fixed_upstream);
+    END IF;
+END;
+$$;
+
+COMMENT ON FUNCTION bugsummary_journal_ins(bugsummary) IS
+'Add an entry into BugSummaryJournal';
+
+
+CREATE OR REPLACE FUNCTION bugsummary_rollup_journal() RETURNS VOID
+LANGUAGE plpgsql VOLATILE
+SECURITY DEFINER SET search_path TO public AS
+$$
+DECLARE
+    d bugsummary%ROWTYPE;
+    max_id integer;
+BEGIN
+    -- Lock so we don't content with other invokations of this
+    -- function. We can happily lock the BugSummary table for writes
+    -- as this function is the only thing that updates that table.
+    -- BugSummaryJournal remains unlocked so nothing should be blocked.
+    LOCK TABLE BugSummary IN ROW EXCLUSIVE MODE;
+
+    SELECT MAX(id) INTO max_id FROM BugSummaryJournal;
+
+    FOR d IN
+        SELECT
+            NULL as id,
+            SUM(count),
+            product,
+            productseries,
+            distribution,
+            distroseries,
+            sourcepackagename,
+            viewed_by,
+            tag,
+            status,
+            milestone,
+            importance,
+            has_patch,
+            fixed_upstream
+        FROM BugSummaryJournal
+        WHERE id <= max_id
+        GROUP BY
+            product, productseries, distribution, distroseries,
+            sourcepackagename, viewed_by, tag, status, milestone,
+            importance, has_patch, fixed_upstream
+        HAVING sum(count) <> 0
+    LOOP
+        IF d.count < 0 THEN
+            PERFORM bug_summary_dec(d);
+        ELSIF d.count > 0 THEN
+            PERFORM bug_summary_inc(d);
+        END IF;
+    END LOOP;
+
+    DELETE FROM BugSummaryJournal WHERE id <= max_id;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION bug_summary_dec(bugsummary) RETURNS VOID
+LANGUAGE SQL AS
+$$
+    -- We own the row reference, so in the absence of bugs this cannot
+    -- fail - just decrement the row.
+    UPDATE BugSummary SET count = count + $1.count
+    WHERE
+        product IS NOT DISTINCT FROM $1.product
+        AND productseries IS NOT DISTINCT FROM $1.productseries
+        AND distribution IS NOT DISTINCT FROM $1.distribution
+        AND distroseries IS NOT DISTINCT FROM $1.distroseries
+        AND sourcepackagename IS NOT DISTINCT FROM $1.sourcepackagename
+        AND viewed_by IS NOT DISTINCT FROM $1.viewed_by
+        AND tag IS NOT DISTINCT FROM $1.tag
+        AND status IS NOT DISTINCT FROM $1.status
+        AND milestone IS NOT DISTINCT FROM $1.milestone
+        AND importance IS NOT DISTINCT FROM $1.importance
+        AND has_patch IS NOT DISTINCT FROM $1.has_patch
+        AND fixed_upstream IS NOT DISTINCT FROM $1.fixed_upstream;
+    -- gc the row (perhaps should be garbo but easy enough to add here:
+    DELETE FROM bugsummary
+    WHERE
+        count=0
+        AND product IS NOT DISTINCT FROM $1.product
+        AND productseries IS NOT DISTINCT FROM $1.productseries
+        AND distribution IS NOT DISTINCT FROM $1.distribution
+        AND distroseries IS NOT DISTINCT FROM $1.distroseries
+        AND sourcepackagename IS NOT DISTINCT FROM $1.sourcepackagename
+        AND viewed_by IS NOT DISTINCT FROM $1.viewed_by
+        AND tag IS NOT DISTINCT FROM $1.tag
+        AND status IS NOT DISTINCT FROM $1.status
+        AND milestone IS NOT DISTINCT FROM $1.milestone
+        AND importance IS NOT DISTINCT FROM $1.importance
+        AND has_patch IS NOT DISTINCT FROM $1.has_patch
+        AND fixed_upstream IS NOT DISTINCT FROM $1.fixed_upstream;
+    -- If its not found then someone else also dec'd and won concurrently.
+$$;
+
+CREATE OR REPLACE FUNCTION bug_summary_inc(d bugsummary) RETURNS VOID
+LANGUAGE plpgsql AS
+$$
+BEGIN
+    -- Shameless adaption from postgresql manual
+    LOOP
+        -- first try to update the row
+        UPDATE BugSummary SET count = count + d.count
+        WHERE
+            product IS NOT DISTINCT FROM d.product
+            AND productseries IS NOT DISTINCT FROM d.productseries
+            AND distribution IS NOT DISTINCT FROM d.distribution
+            AND distroseries IS NOT DISTINCT FROM d.distroseries
+            AND sourcepackagename IS NOT DISTINCT FROM d.sourcepackagename
+            AND viewed_by IS NOT DISTINCT FROM d.viewed_by
+            AND tag IS NOT DISTINCT FROM d.tag
+            AND status IS NOT DISTINCT FROM d.status
+            AND milestone IS NOT DISTINCT FROM d.milestone
+            AND importance IS NOT DISTINCT FROM d.importance
+            AND has_patch IS NOT DISTINCT FROM d.has_patch
+            AND fixed_upstream IS NOT DISTINCT FROM d.fixed_upstream;
+        IF found THEN
+            RETURN;
+        END IF;
+        -- not there, so try to insert the key
+        -- if someone else inserts the same key concurrently,
+        -- we could get a unique-key failure
+        BEGIN
+            INSERT INTO BugSummary(
+                count, product, productseries, distribution,
+                distroseries, sourcepackagename, viewed_by, tag,
+                status, milestone,
+                importance, has_patch, fixed_upstream)
+            VALUES (
+                d.count, d.product, d.productseries, d.distribution,
+                d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
+                d.status, d.milestone,
+                d.importance, d.has_patch, d.fixed_upstream);
+            RETURN;
+        EXCEPTION WHEN unique_violation THEN
+            -- do nothing, and loop to try the UPDATE again
+        END;
+    END LOOP;
+END;
+$$;
+
+COMMENT ON FUNCTION bugsummary_rollup_journal() IS
+'Collate and migrate rows from BugSummaryJournal to BugSummary';
+
+
+CREATE OR REPLACE FUNCTION ensure_bugsummary_temp_journal() RETURNS VOID
+LANGUAGE plpgsql VOLATILE AS
+$$
+DECLARE
+BEGIN
+    CREATE TEMPORARY TABLE bugsummary_temp_journal (
+        LIKE bugsummary ) ON COMMIT DROP;
+    ALTER TABLE bugsummary_temp_journal ALTER COLUMN id DROP NOT NULL;
+EXCEPTION
+    WHEN duplicate_table THEN
+        NULL;
+END;
+$$;
+
+COMMENT ON FUNCTION ensure_bugsummary_temp_journal() IS
+'Create a temporary table bugsummary_temp_journal if it does not exist.';
+
+
+CREATE OR REPLACE FUNCTION bug_summary_temp_journal_ins(d bugsummary)
+RETURNS VOID LANGUAGE plpgsql AS
+$$
+BEGIN
+    INSERT INTO BugSummary_Temp_Journal(
+        count, product, productseries, distribution,
+        distroseries, sourcepackagename, viewed_by, tag,
+        status, milestone, importance, has_patch, fixed_upstream)
+    VALUES (
+        d.count, d.product, d.productseries, d.distribution,
+        d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
+        d.status, d.milestone, d.importance, d.has_patch, d.fixed_upstream);
+    RETURN;
+END;
+$$;
+
+COMMENT ON FUNCTION bug_summary_temp_journal_ins(bugsummary) IS
+'Insert a BugSummary into the temporary journal';
+
+
+-- Don't need these. Faster to just append rows to the journal
+-- than attempt to update existing rows.
+DROP FUNCTION bug_summary_temp_journal_dec(bugsummary);
+DROP FUNCTION bug_summary_temp_journal_inc(bugsummary);
+
+
+CREATE OR REPLACE FUNCTION bug_summary_flush_temp_journal() RETURNS VOID
+LANGUAGE plpgsql VOLATILE AS
+$$
+DECLARE
+    d bugsummary%ROWTYPE;
+BEGIN
+    -- may get called even though no summaries were made (for simplicity in the
+    -- callers)
+    PERFORM ensure_bugsummary_temp_journal();
+    FOR d IN 
+        SELECT
+            NULL::integer AS id, SUM(count), product, productseries,
+            distribution, distroseries, sourcepackagename,
+            viewed_by, tag, status, milestone,
+            importance, has_patch, fixed_upstream
+        FROM BugSummary_temp_journal
+        GROUP BY
+            product, productseries,
+            distribution, distroseries, sourcepackagename,
+            viewed_by, tag, status, milestone, importance,
+            has_patch, fixed_upstream
+        HAVING SUM(count) <> 0
+    LOOP
+        IF d.count < 0 THEN
+            PERFORM bug_summary_dec(d);
+        ELSE
+            PERFORM bug_summary_inc(d);
+        END IF;
+    END LOOP;
+    TRUNCATE bugsummary_temp_journal;
+END;
+$$;
+
+COMMENT ON FUNCTION bug_summary_flush_temp_journal() IS
+'flush the temporary bugsummary journal into the bugsummary table';
+
+
+CREATE OR REPLACE FUNCTION unsummarise_bug(BUG_ROW bug) RETURNS VOID
+LANGUAGE plpgsql VOLATILE AS
+$$
+DECLARE
+    d bugsummary%ROWTYPE;
+BEGIN
+    PERFORM ensure_bugsummary_temp_journal();
+    FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP
+        d.count = -1;
+        PERFORM bug_summary_temp_journal_ins(d);
+    END LOOP;
+END;
+$$;
+
+CREATE OR REPLACE FUNCTION summarise_bug(BUG_ROW bug) RETURNS VOID
+LANGUAGE plpgsql VOLATILE AS
+$$
+DECLARE
+    d bugsummary%ROWTYPE;
+BEGIN
+    PERFORM ensure_bugsummary_temp_journal();
+    FOR d IN SELECT * FROM bugsummary_locations(BUG_ROW) LOOP
+        d.count = 1;
+        PERFORM bug_summary_temp_journal_ins(d);
+    END LOOP;
+END;
+$$;
+
+
+CREATE OR REPLACE FUNCTION bug_maintain_bug_summary() RETURNS TRIGGER
+LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS
+$$
+BEGIN
+    -- There is no INSERT logic, as a bug will not have any summary
+    -- information until BugTask rows have been attached.
+    IF TG_OP = 'UPDATE' THEN
+        IF OLD.duplicateof IS DISTINCT FROM NEW.duplicateof
+            OR OLD.private IS DISTINCT FROM NEW.private
+            OR (OLD.latest_patch_uploaded IS NULL)
+                <> (NEW.latest_patch_uploaded IS NULL) THEN
+            PERFORM unsummarise_bug(OLD);
+            PERFORM summarise_bug(NEW);
+        END IF;
+
+    ELSIF TG_OP = 'DELETE' THEN
+        PERFORM unsummarise_bug(OLD);
+    END IF;
+
+    PERFORM bug_summary_flush_temp_journal();
+    RETURN NULL; -- Ignored - this is an AFTER trigger
+END;
+$$;
+
+
+CREATE OR REPLACE FUNCTION bugtask_maintain_bug_summary() RETURNS TRIGGER
+LANGUAGE plpgsql VOLATILE SECURITY DEFINER SET search_path TO public AS
+$$
+BEGIN
+    -- This trigger only works if we are inserting, updating or deleting
+    -- a single row per statement.
+
+    -- Unlike bug_maintain_bug_summary, this trigger does not have access
+    -- to the old bug when invoked as an AFTER trigger. To work around this
+    -- we install this trigger as both a BEFORE and an AFTER trigger.
+    IF TG_OP = 'INSERT' THEN
+        IF TG_WHEN = 'BEFORE' THEN
+            PERFORM unsummarise_bug(bug_row(NEW.bug));
+        ELSE
+            PERFORM summarise_bug(bug_row(NEW.bug));
+        END IF;
+        PERFORM bug_summary_flush_temp_journal();
+        RETURN NEW;
+
+    ELSIF TG_OP = 'DELETE' THEN
+        IF TG_WHEN = 'BEFORE' THEN
+            PERFORM unsummarise_bug(bug_row(OLD.bug));
+        ELSE
+            PERFORM summarise_bug(bug_row(OLD.bug));
+        END IF;
+        PERFORM bug_summary_flush_temp_journal();
+        RETURN OLD;
+
+    ELSE
+        IF (OLD.product IS DISTINCT FROM NEW.product
+            OR OLD.productseries IS DISTINCT FROM NEW.productseries
+            OR OLD.distribution IS DISTINCT FROM NEW.distribution
+            OR OLD.distroseries IS DISTINCT FROM NEW.distroseries
+            OR OLD.sourcepackagename IS DISTINCT FROM NEW.sourcepackagename
+            OR OLD.status IS DISTINCT FROM NEW.status
+            OR OLD.importance IS DISTINCT FROM NEW.importance
+            OR OLD.bugwatch IS DISTINCT FROM NEW.bugwatch
+            OR OLD.milestone IS DISTINCT FROM NEW.milestone) THEN
+
+            IF TG_WHEN = 'BEFORE' THEN
+                PERFORM unsummarise_bug(bug_row(OLD.bug));
+                IF OLD.bug <> NEW.bug THEN
+                    PERFORM unsummarise_bug(bug_row(NEW.bug));
+                END IF;
+            ELSE
+                PERFORM summarise_bug(bug_row(OLD.bug));
+                IF OLD.bug <> NEW.bug THEN
+                    PERFORM summarise_bug(bug_row(NEW.bug));
+                END IF;
+            END IF;
+        END IF;
+        PERFORM bug_summary_flush_temp_journal();
+        RETURN NEW;
+    END IF;
+END;
+$$;
+
+
+CREATE OR REPLACE FUNCTION bugsummary_locations(BUG_ROW bug)
+RETURNS SETOF bugsummary LANGUAGE plpgsql AS
+$$
+BEGIN
+    IF BUG_ROW.duplicateof IS NOT NULL THEN
+        RETURN;
+    END IF;
+    RETURN QUERY
+        SELECT
+            CAST(NULL AS integer) AS id,
+            CAST(1 AS integer) AS count,
+            product, productseries, distribution, distroseries,
+            sourcepackagename, person AS viewed_by, tag, status, milestone,
+            importance,
+            BUG_ROW.latest_patch_uploaded IS NOT NULL AS has_patch,
+            (EXISTS (
+                SELECT TRUE FROM BugTask AS RBT
+                WHERE
+                    RBT.bug = tasks.bug
+                    -- This would just be 'RBT.id <> tasks.id', except
+                    -- that the records from tasks are summaries and not
+                    -- real bugtasks, and do not have an id.
+                    AND (RBT.product IS DISTINCT FROM tasks.product
+                        OR RBT.productseries
+                            IS DISTINCT FROM tasks.productseries
+                        OR RBT.distribution IS DISTINCT FROM tasks.distribution
+                        OR RBT.distroseries IS DISTINCT FROM tasks.distroseries
+                        OR RBT.sourcepackagename
+                            IS DISTINCT FROM tasks.sourcepackagename)
+                    -- Flagged as INVALID, FIXCOMMITTED or FIXRELEASED
+                    -- via a bugwatch, or FIXCOMMITTED or FIXRELEASED on
+                    -- the product.
+                    AND ((bugwatch IS NOT NULL AND status IN (17, 25, 30))
+                        OR (bugwatch IS NULL AND product IS NOT NULL
+                            AND status IN (25, 30))))
+                )::boolean AS fixed_upstream
+        FROM bugsummary_tasks(BUG_ROW) AS tasks
+        JOIN bugsummary_tags(BUG_ROW) AS bug_tags ON TRUE
+        LEFT OUTER JOIN bugsummary_viewers(BUG_ROW) AS bug_viewers ON TRUE;
+END;
+$$;
+
+COMMENT ON FUNCTION bugsummary_locations(bug) IS
+'Calculate what BugSummary rows should exist for a given Bug.';
+
+
+CREATE OR REPLACE FUNCTION bugsummary_tasks(BUG_ROW bug)
+RETURNS SETOF bugtask LANGUAGE plpgsql STABLE AS
+$$
+DECLARE
+    bt bugtask%ROWTYPE;
+    r record;
+BEGIN
+    bt.bug = BUG_ROW.id;
+
+    -- One row only for each target permutation - need to ignore other fields
+    -- like date last modified to deal with conjoined masters and multiple
+    -- sourcepackage tasks in a distro.
+    FOR r IN
+        SELECT
+            product, productseries, distribution, distroseries,
+            sourcepackagename, status, milestone, importance, bugwatch
+        FROM BugTask WHERE bug=BUG_ROW.id
+        UNION -- Implicit DISTINCT
+        SELECT
+            product, productseries, distribution, distroseries,
+            NULL, status, milestone, importance, bugwatch
+        FROM BugTask WHERE bug=BUG_ROW.id AND sourcepackagename IS NOT NULL
+    LOOP
+        bt.product = r.product;
+        bt.productseries = r.productseries;
+        bt.distribution = r.distribution;
+        bt.distroseries = r.distroseries;
+        bt.sourcepackagename = r.sourcepackagename;
+        bt.status = r.status;
+        bt.milestone = r.milestone;
+        bt.importance = r.importance;
+        bt.bugwatch = r.bugwatch;
+        RETURN NEXT bt;
+    END LOOP;
+END;
+$$;
+
+COMMENT ON FUNCTION bugsummary_tasks(bug) IS
+'Return all tasks for the bug + all sourcepackagename tasks again with the sourcepackagename squashed';
+
+
+
+INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 75, 0);

=== modified file 'database/schema/security.cfg'
--- database/schema/security.cfg	2011-06-13 08:48:11 +0000
+++ database/schema/security.cfg	2011-06-14 17:46:28 +0000
@@ -84,8 +84,7 @@
 public.bug_summary_dec(bugsummary)         =
 public.bug_summary_flush_temp_journal()    =
 public.bug_summary_inc(bugsummary)         =
-public.bug_summary_temp_journal_dec(bugsummary) =
-public.bug_summary_temp_journal_inc(bugsummary) =
+public.bug_summary_temp_journal_ins(bugsummary) =
 public.bugsummary_journal_ins(bugsummary)  =
 public.bugsummary_locations(bug)           =
 public.bugsummary_tags(bug)                =

=== modified file 'lib/lp/bugs/doc/bugsummary.txt'
--- lib/lp/bugs/doc/bugsummary.txt	2011-06-09 16:37:03 +0000
+++ lib/lp/bugs/doc/bugsummary.txt	2011-06-14 17:46:28 +0000
@@ -2,7 +2,7 @@
 ===================
 
 The BugSummary table contains summaries of bug counts. It contains one
-row for every unique public BugTask targetting:
+or more rows row for every unique public BugTask targetting:
 
     - product
     - productseries
@@ -12,18 +12,22 @@
     - tag
     - status
     - milestone
+    - importance
+    - has_patch
+    - fixed_upstream
 
 
 First we should setup some helpers to use in the examples. These will
 let us dump the BugSummary table in a readable format.
 
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
 
 The columns are product, productseries, distribution, distroseries,
-sourcepackagename, tag, milestone, status, viewed_by and the count.
-viewed_by is a team reference and used to query private bug counts.
+sourcepackagename, tag, milestone, status, importance, has_patch,
+fixed_upstream, viewed_by and the count. viewed_by is a team reference
+and used to query private bug counts.
 
     >>> from canonical.launchpad.interfaces.lpstorm import IMasterStore
     >>> from lp.bugs.interfaces.bugtask import BugTaskStatus
@@ -55,11 +59,15 @@
     ...         BugSummary.distribution_id, BugSummary.distroseries_id,
     ...         BugSummary.sourcepackagename_id, BugSummary.tag,
     ...         BugSummary.milestone_id, BugSummary.status,
-    ...         BugSummary.viewed_by_id, BugSummary.id)
-    ...     fmt = "%-4s %-4s %-4s %-4s %-5s %-3s %-4s %-12s %-4s %3s"
+    ...         BugSummary.importance, BugSummary.has_patch,
+    ...         BugSummary.fixed_upstream, BugSummary.viewed_by_id,
+    ...         BugSummary.id)
+    ...     fmt = (
+    ...         "%-4s %-4s %-4s %-4s %-5s %-3s %-4s "
+    ...         "%-6s %-6s %-2s %-2s %-4s %3s")
     ...     header = fmt % (
     ...         'prod', 'ps', 'dist', 'ds', 'spn', 'tag', 'mile',
-    ...         'status', 'vis', '#')
+    ...         'status', 'import', 'pa', 'up', 'vis', '#')
     ...     print "-" * len(header)
     ...     print header
     ...     print "-" * len(header)
@@ -72,7 +80,10 @@
     ...             name(bugsummary.sourcepackagename),
     ...             bugsummary.tag or 'x',
     ...             name(bugsummary.milestone),
-    ...             bugsummary.status,
+    ...             str(bugsummary.status)[:6],
+    ...             str(bugsummary.importance)[:6],
+    ...             str(bugsummary.has_patch)[:1],
+    ...             str(bugsummary.fixed_upstream)[:1],
     ...             name(bugsummary.viewed_by),
     ...             bugsummary.count)
     ...     print " " * (len(header) - 4),
@@ -111,12 +122,12 @@
     ...     BugSummary.tag == None)
 
     >>> print_result(bug_summaries)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    pr-a x    x    x    x     x   x    New          x      1
-                                                         ===
-                                                           1
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    pr-a x    x    x    x     x   x    New    Undeci F  F  x      1
+                                                                ===
+                                                                  1
 
 There is one row per tag per combination of product, status and milestone.
 If we are interested in all bugs targeted to a product regardless of how
@@ -137,13 +148,13 @@
     ...     BugSummary.product == prod_a,
     ...     BugSummary.tag == None,
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    pr-a x    x    x    x     x   x    New          x      2
-    pr-a x    x    x    x     x   x    Confirmed    x      2
-                                                         ===
-                                                           4
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    pr-a x    x    x    x     x   x    New    Undeci F  F  x      2
+    pr-a x    x    x    x     x   x    Confir Undeci F  F  x      2
+                                                                ===
+                                                                  4
 
 Here are the rows associated with the 't-a' tag. There is 1 Confirmed
 bug task targetted to the pr-a product who's bug is tagged 't-a'.:
@@ -152,12 +163,12 @@
     ...     BugSummary.product == prod_a,
     ...     BugSummary.tag == u't-a',
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    pr-a x    x    x    x     t-a x    Confirmed    x      1
-                                                         ===
-                                                           1
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    pr-a x    x    x    x     t-a x    Confir Undeci F  F  x      1
+                                                                ===
+                                                                  1
 
 You will normally want to get the total count counted in the database
 rather than waste transmission time to calculate the rows client side.
@@ -197,17 +208,17 @@
     >>> print_find(
     ...     BugSummary.product == prod_a,
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    pr-a x    x    x    x     t-a x    Confirmed    x      1
-    pr-a x    x    x    x     t-b ms-a New          x      1
-    pr-a x    x    x    x     t-c ms-a New          x      1
-    pr-a x    x    x    x     x   ms-a New          x      1
-    pr-a x    x    x    x     x   x    New          x      2
-    pr-a x    x    x    x     x   x    Confirmed    x      2
-                                                         ===
-                                                           8
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    pr-a x    x    x    x     t-a x    Confir Undeci F  F  x      1
+    pr-a x    x    x    x     t-b ms-a New    Undeci F  F  x      1
+    pr-a x    x    x    x     t-c ms-a New    Undeci F  F  x      1
+    pr-a x    x    x    x     x   ms-a New    Undeci F  F  x      1
+    pr-a x    x    x    x     x   x    New    Undeci F  F  x      2
+    pr-a x    x    x    x     x   x    Confir Undeci F  F  x      2
+                                                                ===
+                                                                  8
 
 Number of New bugs not targeted to a milestone. Note the difference
 between selecting records where tag is None, and where milestone is None:
@@ -262,13 +273,13 @@
     ...         BugSummary.productseries == productseries_b,
     ...         BugSummary.product == prod_b),
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    pr-b x    x    x    x     x   x    New          x      1
-    x    ps-b x    x    x     x   x    New          x      1
-                                                         ===
-                                                           2
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    pr-b x    x    x    x     x   x    New    Undeci F  F  x      1
+    x    ps-b x    x    x     x   x    New    Undeci F  F  x      1
+                                                                ===
+                                                                  2
 
 Distribution Bug Counts
 -----------------------
@@ -290,14 +301,14 @@
     >>> print_find(
     ...     BugSummary.distribution == distribution,
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    x    x    di-a x    sp-a  x   x    New          x      1
-    x    x    di-a x    x     x   x    New          x      1
-    x    x    di-a x    x     x   x    Confirmed    x      1
-                                                         ===
-                                                           3
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    x    x    di-a x    sp-a  x   x    New    Undeci F  F  x      1
+    x    x    di-a x    x     x   x    New    Undeci F  F  x      1
+    x    x    di-a x    x     x   x    Confir Undeci F  F  x      1
+                                                                ===
+                                                                  3
 
 How many bugs targeted to a distribution?
 
@@ -362,12 +373,12 @@
     >>> print_find(
     ...     BugSummary.distroseries == series_c,
     ...     BugSummary.viewed_by == None)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    x    x    x    ds-c x     x   x    New          x      1
-                                                         ===
-                                                           1
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    x    x    x    ds-c x     x   x    New    Undeci F  F  x      1
+                                                                ===
+                                                                  1
 
 
 Privacy
@@ -424,18 +435,18 @@
     ...     BugSummary.distribution == distro_p,
     ...     BugSummary.distroseries == series_p)
     >>> print_find(distro_or_series)
-    --------------------------------------------------------
-    prod ps   dist ds   spn   tag mile status       vis    #
-    --------------------------------------------------------
-    x    x    di-p x    x     x   x    New          p-b    1
-    x    x    di-p x    x     x   x    New          own    3
-    x    x    di-p x    x     x   x    New          t-a    1
-    x    x    di-p x    x     x   x    New          t-c    1
-    x    x    di-p x    x     x   x    New          x      1
-    x    x    x    ds-p x     x   x    New          own    1
-    x    x    x    ds-p x     x   x    New          t-c    1
-                                                         ===
-                                                           9
+    ---------------------------------------------------------------
+    prod ps   dist ds   spn   tag mile status import pa up vis    #
+    ---------------------------------------------------------------
+    x    x    di-p x    x     x   x    New    Undeci F  F  p-b    1
+    x    x    di-p x    x     x   x    New    Undeci F  F  own    3
+    x    x    di-p x    x     x   x    New    Undeci F  F  t-a    1
+    x    x    di-p x    x     x   x    New    Undeci F  F  t-c    1
+    x    x    di-p x    x     x   x    New    Undeci F  F  x      1
+    x    x    x    ds-p x     x   x    New    Undeci F  F  own    1
+    x    x    x    ds-p x     x   x    New    Undeci F  F  t-c    1
+                                                                ===
+                                                                  9
 
 So how many public bugs are there on the distro?
 

=== modified file 'lib/lp/bugs/interfaces/bugsummary.py'
--- lib/lp/bugs/interfaces/bugsummary.py	2011-05-25 13:56:17 +0000
+++ lib/lp/bugs/interfaces/bugsummary.py	2011-06-14 17:46:28 +0000
@@ -9,6 +9,7 @@
 
 from zope.interface import Interface
 from zope.schema import (
+    Bool,
     Choice,
     Int,
     Object,
@@ -16,7 +17,10 @@
     )
 
 from canonical.launchpad import _
-from lp.bugs.interfaces.bugtask import BugTaskStatus
+from lp.bugs.interfaces.bugtask import (
+    BugTaskImportance,
+    BugTaskStatus,
+    )
 from lp.registry.interfaces.distribution import IDistribution
 from lp.registry.interfaces.distroseries import IDistroSeries
 from lp.registry.interfaces.milestone import IMilestone
@@ -51,12 +55,18 @@
     sourcepackagename_id = Int(readonly=True)
     sourcepackagename = Object(ISourcePackageName, readonly=True)
 
+    milestone_id = Int(readonly=True)
+    milestone = Object(IMilestone, readonly=True)
+
+    status = Choice(
+        title=_('Status'), vocabulary=BugTaskStatus, readonly=True)
+    importance = Choice(
+        title=_('Importance'), vocabulary=BugTaskImportance, readonly=True)
+
+    tag = Text(readonly=True)
+
     viewed_by_id = Int(readonly=True)
     viewed_by = Object(IPerson, readonly=True)
 
-    tag = Text(readonly=True)
-    status = Choice(
-        title=_('Status'), vocabulary=BugTaskStatus, readonly=True)
-
-    milestone_id = Int(readonly=True)
-    milestone = Object(IMilestone, readonly=True)
+    has_patch = Bool(readonly=True)
+    fixed_upstream = Bool(readonly=True)

=== modified file 'lib/lp/bugs/interfaces/bugtask.py'
--- lib/lp/bugs/interfaces/bugtask.py	2011-05-26 10:45:55 +0000
+++ lib/lp/bugs/interfaces/bugtask.py	2011-06-14 17:46:28 +0000
@@ -480,7 +480,6 @@
         schema=Interface)) # IMilestone
     milestoneID = Attribute('The id of the milestone.')
 
-    # XXX kiko 2006-03-23:
     # The status and importance's vocabularies do not
     # contain an UNKNOWN item in bugtasks that aren't linked to a remote
     # bugwatch; this would be better described in a separate interface,

=== modified file 'lib/lp/bugs/model/bugsummary.py'
--- lib/lp/bugs/model/bugsummary.py	2011-06-09 16:05:20 +0000
+++ lib/lp/bugs/model/bugsummary.py	2011-06-14 17:46:28 +0000
@@ -7,6 +7,7 @@
 __all__ = ['BugSummary']
 
 from storm.locals import (
+    Bool,
     Int,
     Reference,
     Storm,
@@ -16,7 +17,10 @@
 
 from canonical.database.enumcol import EnumCol
 from lp.bugs.interfaces.bugsummary import IBugSummary
-from lp.bugs.interfaces.bugtask import BugTaskStatus
+from lp.bugs.interfaces.bugtask import (
+    BugTaskImportance,
+    BugTaskStatus,
+    )
 from lp.registry.model.distribution import Distribution
 from lp.registry.model.distroseries import DistroSeries
 from lp.registry.model.milestone import Milestone
@@ -51,11 +55,16 @@
     sourcepackagename_id = Int(name='sourcepackagename')
     sourcepackagename = Reference(sourcepackagename_id, SourcePackageName.id)
 
+    milestone_id = Int(name='milestone')
+    milestone = Reference(milestone_id, Milestone.id)
+
+    status = EnumCol(dbName='status', schema=BugTaskStatus)
+    importance = EnumCol(dbName='importance', schema=BugTaskImportance)
+
+    tag = Unicode()
+
     viewed_by_id = Int(name='viewed_by')
     viewed_by = Reference(viewed_by_id, Person.id)
 
-    tag = Unicode()
-    status = EnumCol(dbName='status', schema=BugTaskStatus)
-
-    milestone_id = Int(name='milestone')
-    milestone = Reference(milestone_id, Milestone.id)
+    has_patch = Bool()
+    fixed_upstream = Bool()

=== modified file 'lib/lp/bugs/model/tests/test_bugsummary.py'
--- lib/lp/bugs/model/tests/test_bugsummary.py	2011-06-09 20:46:15 +0000
+++ lib/lp/bugs/model/tests/test_bugsummary.py	2011-06-14 17:46:28 +0000
@@ -5,10 +5,18 @@
 
 __metaclass__ = type
 
+from datetime import datetime
+
+from pytz import utc
+from zope.security.proxy import removeSecurityProxy
+
 from canonical.launchpad.interfaces.lpstorm import IMasterStore
 from canonical.testing.layers import LaunchpadZopelessLayer
 from lp.bugs.interfaces.bugsummary import IBugSummary
-from lp.bugs.interfaces.bugtask import BugTaskStatus
+from lp.bugs.interfaces.bugtask import (
+    BugTaskImportance,
+    BugTaskStatus,
+    )
 from lp.bugs.model.bug import BugTag
 from lp.bugs.model.bugsummary import BugSummary
 from lp.bugs.model.bugtask import BugTask
@@ -204,6 +212,38 @@
                     BugSummary.status == new_status),
                 3 - count)
 
+    def test_changeImportance(self):
+        org_importance = BugTaskImportance.UNDECIDED
+        new_importance = BugTaskImportance.CRITICAL
+
+        product = self.factory.makeProduct()
+
+        for count in range(3):
+            bug = self.factory.makeBug(product=product)
+            bug_task = self.store.find(BugTask, bug=bug).one()
+            bug_task.importance = org_importance
+
+            self.assertEqual(
+                self.getPublicCount(
+                    BugSummary.product == product,
+                    BugSummary.importance == org_importance),
+                count + 1)
+
+        for count in reversed(range(3)):
+            bug_task = self.store.find(
+                BugTask, product=product, importance=org_importance).any()
+            bug_task.importance = new_importance
+            self.assertEqual(
+                self.getPublicCount(
+                    BugSummary.product == product,
+                    BugSummary.importance == org_importance),
+                count)
+            self.assertEqual(
+                self.getPublicCount(
+                    BugSummary.product == product,
+                    BugSummary.importance == new_importance),
+                3 - count)
+
     def test_makePrivate(self):
         product = self.factory.makeProduct()
         bug = self.factory.makeBug(product=product)
@@ -927,6 +967,190 @@
                 BugSummary.milestone == milestone),
             0)
 
+    def test_fixUpstream(self):
+        distribution = self.factory.makeDistribution()
+        product = self.factory.makeProduct()
+        distro_bugtask = self.factory.makeBugTask(target=distribution)
+        bug = distro_bugtask.bug
+        product_bugtask = self.factory.makeBugTask(bug=bug, target=product)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            0)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            1)
+
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.FIXRELEASED, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            1)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            0)
+
+    def test_breakUpstream(self):
+        distribution = self.factory.makeDistribution()
+        product = self.factory.makeProduct()
+        distro_bugtask = self.factory.makeBugTask(target=distribution)
+        bug = distro_bugtask.bug
+        product_bugtask = self.factory.makeBugTask(bug=bug, target=product)
+
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.FIXCOMMITTED, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            1)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            0)
+
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.INPROGRESS, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            0)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            1)
+
+    def test_fixUpstreamViaWatch(self):
+        distribution = self.factory.makeDistribution()
+        product = self.factory.makeProduct()
+        distro_bugtask = self.factory.makeBugTask(target=distribution)
+        bug = distro_bugtask.bug
+        product_bugtask = self.factory.makeBugTask(bug=bug, target=product)
+        product_bugwatch = self.factory.makeBugWatch(bug_task=product_bugtask)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            0)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            1)
+
+        # Bugs flagged INVALID by upstream count as fixed upstream.
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.INVALID, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            1)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            0)
+
+    def test_breakUpstreamViaWatch(self):
+        distribution = self.factory.makeDistribution()
+        product = self.factory.makeProduct()
+        distro_bugtask = self.factory.makeBugTask(target=distribution)
+        bug = distro_bugtask.bug
+        product_bugtask = self.factory.makeBugTask(bug=bug, target=product)
+        product_bugwatch = self.factory.makeBugWatch(bug_task=product_bugtask)
+
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.FIXCOMMITTED, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            1)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            0)
+
+        product_bugtask.transitionToStatus(
+            BugTaskStatus.UNKNOWN, bug.owner)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == True),
+            0)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.distribution == distribution,
+                BugSummary.fixed_upstream == False),
+            1)
+
+    def test_addPatch(self):
+        product = self.factory.makeProduct()
+        bug = self.factory.makeBug(product=product)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == True),
+            0)
+
+        removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == True),
+            1)
+
+    def test_removePatch(self):
+        product = self.factory.makeProduct()
+        bug = self.factory.makeBug(product=product)
+        removeSecurityProxy(bug).latest_patch_uploaded = datetime.now(tz=utc)
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == True),
+            1)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == False),
+            0)
+
+        removeSecurityProxy(bug).latest_patch_uploaded = None
+
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == True),
+            0)
+        self.assertEqual(
+            self.getPublicCount(
+                BugSummary.product == product,
+                BugSummary.has_patch == False),
+            1)
+
 
 class TestBugSummaryRolledUp(TestBugSummary):
 


Follow ups