~launchpad-pqm/launchpad/devel

7675.1202.27 by Stuart Bishop
Speed up bugsummaryjournal rollup
1
-- Copyright 2011 Canonical Ltd.  This software is licensed under the
2
-- GNU Affero General Public License version 3 (see the file LICENSE).
3
4
SET client_min_messages=ERROR;
5
7675.1202.28 by Stuart Bishop
Add a batchsize for future garbo job
6
DROP FUNCTION bugsummary_rollup_journal();
7
8
CREATE OR REPLACE FUNCTION bugsummary_rollup_journal(batchsize integer=NULL)
9
RETURNS VOID
7675.1202.27 by Stuart Bishop
Speed up bugsummaryjournal rollup
10
LANGUAGE plpgsql VOLATILE
7675.1202.28 by Stuart Bishop
Add a batchsize for future garbo job
11
CALLED ON NULL INPUT
7675.1202.27 by Stuart Bishop
Speed up bugsummaryjournal rollup
12
SECURITY DEFINER SET search_path TO public AS
13
$$
14
DECLARE
15
    d bugsummary%ROWTYPE;
16
    max_id integer;
17
BEGIN
18
    -- Lock so we don't content with other invokations of this
19
    -- function. We can happily lock the BugSummary table for writes
20
    -- as this function is the only thing that updates that table.
21
    -- BugSummaryJournal remains unlocked so nothing should be blocked.
22
    LOCK TABLE BugSummary IN ROW EXCLUSIVE MODE;
23
7675.1202.28 by Stuart Bishop
Add a batchsize for future garbo job
24
    IF batchsize IS NULL THEN
25
        SELECT MAX(id) INTO max_id FROM BugSummaryJournal;
26
    ELSE
27
        SELECT MAX(id) INTO max_id FROM (
28
            SELECT id FROM BugSummaryJournal ORDER BY id LIMIT batchsize
29
            ) AS Whatever;
30
    END IF;
7675.1202.27 by Stuart Bishop
Speed up bugsummaryjournal rollup
31
32
    FOR d IN
33
        SELECT
34
            NULL as id,
35
            SUM(count),
36
            product,
37
            productseries,
38
            distribution,
39
            distroseries,
40
            sourcepackagename,
41
            viewed_by,
42
            tag,
43
            status,
44
            milestone,
45
            importance,
46
            has_patch,
47
            fixed_upstream
48
        FROM BugSummaryJournal
49
        WHERE id <= max_id
50
        GROUP BY
51
            product, productseries, distribution, distroseries,
52
            sourcepackagename, viewed_by, tag, status, milestone,
53
            importance, has_patch, fixed_upstream
54
        HAVING sum(count) <> 0
55
    LOOP
56
        IF d.count < 0 THEN
57
            PERFORM bug_summary_dec(d);
58
        ELSIF d.count > 0 THEN
59
            PERFORM bug_summary_inc(d);
60
        END IF;
61
    END LOOP;
62
63
    -- Clean out any counts we reduced to 0.
64
    DELETE FROM BugSummary WHERE count=0;
65
    -- Clean out the journal entries we have handled.
66
    DELETE FROM BugSummaryJournal WHERE id <= max_id;
67
END;
68
$$;
69
7675.1202.28 by Stuart Bishop
Add a batchsize for future garbo job
70
COMMENT ON FUNCTION bugsummary_rollup_journal(integer) IS
71
'Collate and migrate rows from BugSummaryJournal to BugSummary';
72
7675.1202.27 by Stuart Bishop
Speed up bugsummaryjournal rollup
73
74
CREATE OR REPLACE FUNCTION bug_summary_dec(bugsummary) RETURNS VOID
75
LANGUAGE SQL AS
76
$$
77
    -- We own the row reference, so in the absence of bugs this cannot
78
    -- fail - just decrement the row.
79
    UPDATE BugSummary SET count = count + $1.count
80
    WHERE
81
        ((product IS NULL AND $1.product IS NULL)
82
            OR product = $1.product)
83
        AND ((productseries IS NULL AND $1.productseries IS NULL)
84
            OR productseries = $1.productseries)
85
        AND ((distribution IS NULL AND $1.distribution IS NULL)
86
            OR distribution = $1.distribution)
87
        AND ((distroseries IS NULL AND $1.distroseries IS NULL)
88
            OR distroseries = $1.distroseries)
89
        AND ((sourcepackagename IS NULL AND $1.sourcepackagename IS NULL)
90
            OR sourcepackagename = $1.sourcepackagename)
91
        AND ((viewed_by IS NULL AND $1.viewed_by IS NULL)
92
            OR viewed_by = $1.viewed_by)
93
        AND ((tag IS NULL AND $1.tag IS NULL)
94
            OR tag = $1.tag)
95
        AND status = $1.status
96
        AND ((milestone IS NULL AND $1.milestone IS NULL)
97
            OR milestone = $1.milestone)
98
        AND importance = $1.importance
99
        AND has_patch = $1.has_patch
100
        AND fixed_upstream = $1.fixed_upstream;
101
$$;
102
103
CREATE OR REPLACE FUNCTION bug_summary_inc(d bugsummary) RETURNS VOID
104
LANGUAGE plpgsql AS
105
$$
106
BEGIN
107
    -- Shameless adaption from postgresql manual
108
    LOOP
109
        -- first try to update the row
110
        UPDATE BugSummary SET count = count + d.count
111
        WHERE
112
            ((product IS NULL AND $1.product IS NULL)
113
                OR product = $1.product)
114
            AND ((productseries IS NULL AND $1.productseries IS NULL)
115
                OR productseries = $1.productseries)
116
            AND ((distribution IS NULL AND $1.distribution IS NULL)
117
                OR distribution = $1.distribution)
118
            AND ((distroseries IS NULL AND $1.distroseries IS NULL)
119
                OR distroseries = $1.distroseries)
120
            AND ((sourcepackagename IS NULL AND $1.sourcepackagename IS NULL)
121
                OR sourcepackagename = $1.sourcepackagename)
122
            AND ((viewed_by IS NULL AND $1.viewed_by IS NULL)
123
                OR viewed_by = $1.viewed_by)
124
            AND ((tag IS NULL AND $1.tag IS NULL)
125
                OR tag = $1.tag)
126
            AND status = $1.status
127
            AND ((milestone IS NULL AND $1.milestone IS NULL)
128
                OR milestone = $1.milestone)
129
            AND importance = $1.importance
130
            AND has_patch = $1.has_patch
131
            AND fixed_upstream = $1.fixed_upstream;
132
        IF found THEN
133
            RETURN;
134
        END IF;
135
        -- not there, so try to insert the key
136
        -- if someone else inserts the same key concurrently,
137
        -- we could get a unique-key failure
138
        BEGIN
139
            INSERT INTO BugSummary(
140
                count, product, productseries, distribution,
141
                distroseries, sourcepackagename, viewed_by, tag,
142
                status, milestone,
143
                importance, has_patch, fixed_upstream)
144
            VALUES (
145
                d.count, d.product, d.productseries, d.distribution,
146
                d.distroseries, d.sourcepackagename, d.viewed_by, d.tag,
147
                d.status, d.milestone,
148
                d.importance, d.has_patch, d.fixed_upstream);
149
            RETURN;
150
        EXCEPTION WHEN unique_violation THEN
151
            -- do nothing, and loop to try the UPDATE again
152
        END;
153
    END LOOP;
154
END;
155
$$;
156
157
158
159
INSERT INTO LaunchpadDatabaseRevision VALUES (2208, 76, 4);