Skip to content

Commit 159bd78

Browse files
committed
RHINENG-21214: update sql functions that use system_platform
1 parent c43723e commit 159bd78

1 file changed

Lines changed: 303 additions & 0 deletions

File tree

database_admin/migrations/142_split_system_platform.up.sql

Lines changed: 303 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,309 @@ ADD CONSTRAINT system_inventory_id
165165
FOREIGN KEY (rh_account_id, system_id)
166166
REFERENCES system_inventory (rh_account_id, id);
167167

168+
-- UPDATE FUNCTIONS
169+
CREATE OR REPLACE FUNCTION on_system_update()
170+
-- this trigger updates advisory_account_data when server changes its stale flag
171+
RETURNS TRIGGER
172+
AS
173+
$system_update$
174+
DECLARE
175+
was_counted BOOLEAN;
176+
should_count BOOLEAN;
177+
change INT;
178+
BEGIN
179+
-- Ignore not yet evaluated systems
180+
IF TG_OP != 'UPDATE' OR NOT EXISTS (
181+
SELECT 1
182+
FROM system_patch
183+
WHERE system_id = NEW.id
184+
AND rh_account_id = NEW.rh_account_id
185+
AND last_evaluation IS NOT NULL
186+
) THEN
187+
RETURN NEW;
188+
END IF;
189+
190+
was_counted := OLD.stale = FALSE;
191+
should_count := NEW.stale = FALSE;
192+
193+
-- Determine what change we are performing
194+
IF was_counted and NOT should_count THEN
195+
change := -1;
196+
ELSIF NOT was_counted AND should_count THEN
197+
change := 1;
198+
ELSE
199+
-- No change
200+
RETURN NEW;
201+
END IF;
202+
203+
-- insert/update advisories linked to the server
204+
INSERT
205+
INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
206+
SELECT sa.advisory_id, NEW.rh_account_id,
207+
case when sa.status_id = 0 then change else 0 end as systems_installable,
208+
change as systems_applicable
209+
FROM system_advisories sa
210+
WHERE sa.system_id = NEW.id AND sa.rh_account_id = NEW.rh_account_id
211+
ORDER BY sa.advisory_id
212+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE
213+
SET systems_installable = advisory_account_data.systems_installable + EXCLUDED.systems_installable,
214+
systems_applicable = advisory_account_data.systems_applicable + EXCLUDED.systems_applicable;
215+
RETURN NEW;
216+
END;
217+
$system_update$ LANGUAGE plpgsql;
218+
219+
CREATE OR REPLACE FUNCTION refresh_advisory_caches_multi(advisory_ids_in INTEGER[] DEFAULT NULL,
220+
rh_account_id_in INTEGER DEFAULT NULL)
221+
RETURNS VOID AS
222+
$refresh_advisory$
223+
BEGIN
224+
-- Lock rows
225+
PERFORM aad.rh_account_id, aad.advisory_id
226+
FROM advisory_account_data aad
227+
WHERE (aad.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL)
228+
AND (aad.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL)
229+
FOR UPDATE OF aad;
230+
231+
WITH current_counts AS (
232+
SELECT sa.advisory_id, sa.rh_account_id,
233+
count(sa.*) filter (where sa.status_id = 0) as systems_installable,
234+
count(sa.*) as systems_applicable
235+
FROM system_advisories sa
236+
JOIN system_inventory si
237+
ON sa.rh_account_id = si.rh_account_id AND sa.system_id = si.id
238+
JOIN system_patch sp
239+
ON si.id = sp.system_id AND sp.rh_account_id = si.rh_account_id
240+
WHERE sp.last_evaluation IS NOT NULL
241+
AND si.stale = FALSE
242+
AND (sa.advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL)
243+
AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL)
244+
GROUP BY sa.advisory_id, sa.rh_account_id
245+
),
246+
upserted AS (
247+
INSERT INTO advisory_account_data (advisory_id, rh_account_id, systems_installable, systems_applicable)
248+
SELECT advisory_id, rh_account_id, systems_installable, systems_applicable
249+
FROM current_counts
250+
ON CONFLICT (advisory_id, rh_account_id) DO UPDATE SET
251+
systems_installable = EXCLUDED.systems_installable,
252+
systems_applicable = EXCLUDED.systems_applicable
253+
)
254+
DELETE FROM advisory_account_data
255+
WHERE (advisory_id, rh_account_id) NOT IN (SELECT advisory_id, rh_account_id FROM current_counts)
256+
AND (advisory_id = ANY (advisory_ids_in) OR advisory_ids_in IS NULL)
257+
AND (rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL);
258+
END;
259+
$refresh_advisory$ language plpgsql;
260+
261+
CREATE OR REPLACE FUNCTION refresh_system_caches(system_id_in BIGINT DEFAULT NULL,
262+
rh_account_id_in INTEGER DEFAULT NULL)
263+
RETURNS INTEGER AS
264+
$refresh_system$
265+
DECLARE
266+
COUNT INTEGER;
267+
BEGIN
268+
WITH system_advisories_count AS (
269+
SELECT si.rh_account_id, si.id,
270+
COUNT(advisory_id) FILTER (WHERE sa.status_id = 0) as installable_total,
271+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1 AND sa.status_id = 0) AS installable_enhancement,
272+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2 AND sa.status_id = 0) AS installable_bugfix,
273+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3 AND sa.status_id = 0) as installable_security,
274+
COUNT(advisory_id) as applicable_total,
275+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 1) AS applicable_enhancement,
276+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 2) AS applicable_bugfix,
277+
COUNT(advisory_id) FILTER (WHERE am.advisory_type_id = 3) as applicable_security
278+
FROM system_inventory si -- this table ensures even systems without any system_advisories are in results
279+
LEFT JOIN system_advisories sa
280+
ON si.rh_account_id = sa.rh_account_id AND si.id = sa.system_id
281+
LEFT JOIN advisory_metadata am
282+
ON sa.advisory_id = am.id
283+
WHERE (si.id = system_id_in OR system_id_in IS NULL)
284+
AND (si.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL)
285+
GROUP BY si.rh_account_id, si.id
286+
ORDER BY si.rh_account_id, si.id
287+
)
288+
UPDATE system_patch sp
289+
SET installable_advisory_count_cache = sc.installable_total,
290+
installable_advisory_enh_count_cache = sc.installable_enhancement,
291+
installable_advisory_bug_count_cache = sc.installable_bugfix,
292+
installable_advisory_sec_count_cache = sc.installable_security,
293+
applicable_advisory_count_cache = sc.applicable_total,
294+
applicable_advisory_enh_count_cache = sc.applicable_enhancement,
295+
applicable_advisory_bug_count_cache = sc.applicable_bugfix,
296+
applicable_advisory_sec_count_cache = sc.applicable_security
297+
FROM system_advisories_count sc
298+
WHERE sp.rh_account_id = sc.rh_account_id AND sp.system_id = sc.id
299+
AND (sp.system_id = system_id_in OR system_id_in IS NULL)
300+
AND (sp.rh_account_id = rh_account_id_in OR rh_account_id_in IS NULL);
301+
302+
GET DIAGNOSTICS COUNT = ROW_COUNT;
303+
RETURN COUNT;
304+
END;
305+
$refresh_system$ LANGUAGE plpgsql;
306+
307+
CREATE OR REPLACE FUNCTION refresh_system_cached_counts(inventory_id_in varchar)
308+
RETURNS void AS
309+
$refresh_system_cached_counts$
310+
DECLARE
311+
system_id int;
312+
BEGIN
313+
314+
SELECT id FROM system_inventory WHERE inventory_id = inventory_id_in INTO system_id;
315+
316+
PERFORM refresh_system_caches(system_id, NULL);
317+
END;
318+
$refresh_system_cached_counts$
319+
LANGUAGE 'plpgsql';
320+
321+
CREATE OR REPLACE FUNCTION delete_system(inventory_id_in uuid)
322+
RETURNS TABLE
323+
(
324+
deleted_inventory_id uuid
325+
)
326+
AS
327+
$delete_system$
328+
DECLARE
329+
v_system_id INT;
330+
v_account_id INT;
331+
BEGIN
332+
-- opt out to refresh cache and then delete
333+
SELECT id, rh_account_id
334+
FROM system_inventory
335+
WHERE inventory_id = inventory_id_in
336+
LIMIT 1
337+
FOR UPDATE OF system_inventory
338+
INTO v_system_id, v_account_id;
339+
340+
IF v_system_id IS NULL OR v_account_id IS NULL THEN
341+
RAISE NOTICE 'Not found';
342+
RETURN;
343+
END IF;
344+
345+
UPDATE system_inventory
346+
SET stale = true
347+
WHERE rh_account_id = v_account_id
348+
AND id = v_system_id;
349+
350+
DELETE
351+
FROM system_advisories
352+
WHERE rh_account_id = v_account_id
353+
AND system_id = v_system_id;
354+
355+
DELETE
356+
FROM system_repo
357+
WHERE rh_account_id = v_account_id
358+
AND system_id = v_system_id;
359+
360+
DELETE
361+
FROM system_package2
362+
WHERE rh_account_id = v_account_id
363+
AND system_id = v_system_id;
364+
365+
DELETE
366+
FROM system_patch
367+
WHERE rh_account_id = v_account_id
368+
AND system_id = v_system_id;
369+
370+
RETURN QUERY DELETE FROM system_inventory
371+
WHERE rh_account_id = v_account_id AND
372+
id = v_system_id
373+
RETURNING inventory_id;
374+
END;
375+
$delete_system$ LANGUAGE 'plpgsql';
376+
377+
CREATE OR REPLACE FUNCTION delete_systems(inventory_ids UUID[])
378+
RETURNS INTEGER
379+
AS
380+
$$
381+
DECLARE
382+
tmp_cnt INTEGER;
383+
BEGIN
384+
385+
WITH systems as (
386+
SELECT rh_account_id, id
387+
FROM system_inventory
388+
WHERE inventory_id = ANY (inventory_ids)
389+
ORDER BY rh_account_id, id FOR UPDATE OF system_inventory),
390+
marked as (
391+
UPDATE system_inventory sp
392+
SET stale = true
393+
WHERE (rh_account_id, id) in (select rh_account_id, id from systems)
394+
),
395+
advisories as (
396+
DELETE
397+
FROM system_advisories
398+
WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems)
399+
),
400+
repos as (
401+
DELETE
402+
FROM system_repo
403+
WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems)
404+
),
405+
packages2 as (
406+
DELETE
407+
FROM system_package2
408+
WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems)
409+
),
410+
patch_systems as (
411+
DELETE
412+
FROM system_patch
413+
WHERE (rh_account_id, system_id) in (select rh_account_id, id from systems)
414+
),
415+
deleted as (
416+
DELETE
417+
FROM system_inventory
418+
WHERE (rh_account_id, id) in (select rh_account_id, id from systems)
419+
RETURNING id
420+
)
421+
SELECT count(*)
422+
FROM deleted
423+
INTO tmp_cnt;
424+
425+
RETURN tmp_cnt;
426+
END
427+
$$ LANGUAGE plpgsql;
428+
429+
CREATE OR REPLACE FUNCTION delete_culled_systems(delete_limit INTEGER)
430+
RETURNS INTEGER
431+
AS
432+
$fun$
433+
DECLARE
434+
ids UUID[];
435+
BEGIN
436+
ids := ARRAY(
437+
SELECT inventory_id
438+
FROM system_inventory
439+
WHERE culled_timestamp < now()
440+
ORDER BY id
441+
LIMIT delete_limit
442+
);
443+
return delete_systems(ids);
444+
END;
445+
$fun$ LANGUAGE plpgsql;
446+
447+
CREATE OR REPLACE FUNCTION mark_stale_systems(mark_limit integer)
448+
RETURNS INTEGER
449+
AS
450+
$fun$
451+
DECLARE
452+
marked integer;
453+
BEGIN
454+
WITH ids AS (
455+
SELECT rh_account_id, id, stale_warning_timestamp < now() as expired
456+
FROM system_inventory
457+
WHERE stale != (stale_warning_timestamp < now())
458+
ORDER BY rh_account_id, id FOR UPDATE OF system_inventory
459+
LIMIT mark_limit
460+
)
461+
UPDATE system_inventory si
462+
SET stale = ids.expired
463+
FROM ids
464+
WHERE si.rh_account_id = ids.rh_account_id
465+
AND si.id = ids.id;
466+
GET DIAGNOSTICS marked = ROW_COUNT;
467+
RETURN marked;
468+
END;
469+
$fun$ LANGUAGE plpgsql;
470+
168471

169472

170473
-- system_patch

0 commit comments

Comments
 (0)